Tag Archives: Cherrypy

Revit and RabbitMQ: Passing Data in to Revit from Outside Applications

25 Oct

UPDATED:

I threw together a quick website using CherryPY to pass data to Revit. The QR Code pictured below, when scanned, will pull up the website, triggering the data in it to be sent to Revit. Picture a QR Code with info on a HVAC Unit, you scan it and the data is passed to Revit for when it was installed or serviced.

Sending Data in a URL to Revit. Data can be parsed to up date parameters of object.

Sending Data in a URL to Revit. Data can be parsed to update parameters of object.

QR Code with embedded data to send to Revit.

QR Code with embedded data to send to Revit.

 

 

 

 

 

 

 

 

 

 

***************************************************************************

ORIGINAL:

 

Modifying Revit from outside the program has been my primary interest for some time.

Initially, I was fascinated by the Revit DBLink plugin and wrote a few proof of concepts that relied on the following architecture:

Revit <—–> Database<—–>Outside Program

I have recently posted proof of concepts about sending data in to Revit from outside – skipping the database export– but used GIS as my example, arguing that because GIS and Revit use the same API language it should be possible.

I now have a working example in Revit. The architecture no longer requires a Revit DB to be exported.

Revit <——- RabbitMQ<———-Outside Program. (can be bidirectional if want it to)

I wrote a Revit Add-In that connects to a Messaging Queue and retrieves any waiting messages. Getting the message in to Revit is the hard part. Once in, we can use it to modify properties – like in the GIS example that drew points from a message.

The screenshots show the Add-In, No Messages Waiting, and a Message Coming In.

This is my proof of concept and the goal is to modify this program to allow the scanning of a QR code to send a message in to Revit and modify/add properties to an object. That architects looks like this:

Revit<—— RabbitMQ<——-WebServer <——- QR Code scanned by mobile device

The Qr Code Opens a URL with Parameters(http://somewhere.com/revit?id=123&wallheight=12

The WebServer is a CherryPy Script that reads in the parameters and passes them as a message to RabbitMQ using Pika.

The Revit Add-In gets the message and modifies the properties of the wall with ID=123

D3.js and MongoDB

28 Nov

I have not been shy in my love of MongoDB. The honeymoon is not over. Now I want to graph and visualize my data from MongoDB. I just started looking at D3 – I’m coming to the party a bit late – and it is perfect for this task. I have thrown together a super simple, absurd even, example using a DB I had already populated and some left over CherryPy code. Let me say that reusing code is a good idea – when I can find what I’m looking for. It allows me to throw something together quickly. These are not production samples, but just for me to see that I can get it to work. Enough already. Here is a bar chart using D3 and MongoDB.

d3

A Bar Chart, that should be in SVG, from MongoDB data in D3.js

I have not put this on OpenShift yet, but may.  This bar chart is a simple python script using CherryPy and committing my favorite sin – passing HTML as a variable in a return. One reason to put it on OpenShift is so I can template it in Jinja.  Here is the code:

import cherrypy
from pymongo import Connection

class mongocherry(object):

def index(self):
db=Connection().geo
output =[]
output.append(‘<HTML><HEAD><TITLE>D3 and MONGODB</TITLE><script type=”text/javascript” src=”http://d3js.org/d3.v2.min.js”></script><style type=”text/css”>div.bar {display: inline-block;width: 20px;height: 75px;margin-right: 2px;background-color: teal;}</style></HEAD><BODY><h1>D3 and MongoDB</h1>’)
output.append(‘<script type=”text/javascript”>var dataset=[‘)

for x in db.places.find():
output.append(str(x[“loc”][0])+’,’)
output.append(‘0];’+”\n”+’d3.select(“body”).selectAll(“div”).data(dataset).enter().append(“div”).attr(“class”, “bar”).style(“height”, function(d) {var barHeight = d * 5;return barHeight + “px”;});</script></body></html>’)

i=0
html=””
while i<len(output):
html+=str(output[i])
i+=1

return html

index.exposed = True

cherrypy.config.update({‘server.socket_host’: ‘127.0.0.1’,
‘server.socket_port’: 8000,
})

cherrypy.quickstart(mongocherry())

The Python code prints out HTML that looks like this:

<HTML><HEAD><TITLE>D3 and MONGODB</TITLE>
<script type="text/javascript" src="http://d3js.org/d3.v2.min.js"></script>
<style type="text/css">
div.bar {
display: inline-block;
width: 20px;
height: 75px;
margin-right: 2px;
background-color: teal;}
</style>
</HEAD><BODY>
<h1>D3 and MongoDB</h1>
<script type="text/javascript">
var dataset=[35,35.8,38,39,30,31,31,31,33,25,33,0];
d3.select("body")
.selectAll("div")
.data(dataset)
.enter()
.append("div")
.attr("class", "bar")
.style("height", function(d) {var barHeight = d * 5;return barHeight + "px";});
</script></body></html>

Not much going on here, just a simple D3.js bar chart – not even done in SVG. The MongoDB part is in the variable dataset[..]. While writing the HTML, the python code loops through my mongodb with for x in db.places.find(): and it grabs the latitude of the data I have with x[“loc”][0] prints it out in the JavaScript variable dataset[]. I add a 0 at the end because I get a trailing comma. Sloppy, but oh well.

I return all the HTML and you get the page displayed at the top of this post. The cool part of marrying D3.js and MongoDB is JSON. I have JSON in my DB and D3 takes JSON.

Web Based Spreadsheet with CherryPy and XLWT

15 Nov

An example of a simple spreadsheet through the web. Uses a Table and Form.

The code:

import cherrypy
from cherrypy.lib.static import serve_file
import xlwt

class SHP(object):

def index(self):
return “””<HTML><HEAD><TITLE>SPREADSHEET</TITLE></HEAD>
<BODY><FORM NAME=’sheet’ action=’paul’>
<table border=’1′>
<tr><td><input type=”text” name=”r0c0″></td><td><input type=”text” name=”r0c1″></td><td><input type=”text” name=”r0c2″></td></tr>
<tr><td><input type=”text” name=”r1c0″></td><td><input type=”text” name=”r1c1″></td><td><input type=”text” name=”r1c2″></td></tr>
<tr><td><input type=”text” name=”r2c0″></td><td><input type=”text” name=”r2c1″></td><td><input type=”text” name=”r2c2″></td></tr>
</table><BR>
<input type=’submit’ Value=’SUBMIT’>”””

index.exposed = True

def paul(self,r0c0,r0c1,r0c2,r1c0,r1c1,r1c2,r2c0,r2c1,r2c2):
wb=xlwt.Workbook()
ws=wb.add_sheet(‘Web Sheet’)
ws.write(0,0,r0c0)
ws.write(0,1,r0c1)
ws.write(0,2,xlwt.Formula(r0c2))
ws.write(1,0,r1c0)
ws.write(1,1,r1c1)
ws.write(1,2,xlwt.Formula(r1c2))
ws.write(2,0,r2c0)
ws.write(2,1,r2c1)
ws.write(2,2,xlwt.Formula(r2c2))
wb.save(‘Spreadsheet.xls’)

return “Download Spreadsheet: <a href=’/get?filepath=C:\Documents and Settings\user\Desktop\Spreadsheet.xls’>Your Spreadsheet</a>”

paul.exposed = True

def get(self, filepath):
return serve_file(filepath, “application/x-download”, “attachment”)
get.exposed = True

cherrypy.config.update({‘server.socket_host’: ‘127.0.0.1’,
‘server.socket_port’: 8000,
})

cherrypy.quickstart(SHP())

MongoDB with a slice of CherryPy: Running a Query and Displaying Results

15 Nov

As you may have noticed, I love CherryPy. Recently, I have been playing with MongoDB and pymongo. In my last post I showed how to create a shapefile from a mongoDB. In this post, I will show how to connect to mongoDB through Python using CherryPy and spitting out the results of a find() in an HTML table.

Here is what the webpage will look like:

And here is the code – I’m sure there is a cleaner way to write this instead of looping twice but i’m writing this on my lunch break and don’t have a lot of time to do more than make it run.

import cherrypy
from pymongo import Connection,GEO2D
class mongocherry(object):
def index(self):
db=Connection().geo
output =[]
output.append(‘<HTML><HEAD><TITLE>QUERY MONGODB</TITLE></HEAD><BODY><h1>Query MongoDB</h1>’)
output.append(‘<table border=”1″><tr><td>ID</td><td>LAT</td><td>LONG</td></tr>’)

for x in db.places.find():
output.append(‘<tr><td>’+str(x[“_id”])+'</td><td>’+str(x[“loc”][0])+'</td><td>’+str(x[“loc”][1])+'</td></tr>’)

output.append(‘</table></BODY></HTML>’)
i=0
html=””
while i<len(output):
html+=str(output[i])
i+=1

return html

index.exposed = True

cherrypy.config.update({‘server.socket_host’: ‘127.0.0.1’,
‘server.socket_port’: 8000,
})

cherrypy.quickstart(mongocherry())

I have servers running on some ports so I needed to set a config to change the port. This site creates a front end to data that will always be current. You can make your index page a form and allow the user to select the data they want, then in another def returnResults(self, user selected data): Spit out all the HTML that is in the index now, passing ‘user selected data’ to mongoDB.

I have really enjoyed playing with mongoDB and am curious about importing Revit schedule. Not sure what I would do with it once it’s loaded. But still thinking…… Any ideas?

Shapefile Creator Website Using Cherrypy

8 Nov

I showed how to create a shapefile using python, now I want to make the tool public with a web based front-end. My python web framework of choice is Cherrypy. -a minimal web framework.

My website will allow you to enter Longitude, Latitude and a comment. I am working on a text area where you can paste data. Here ie my website:

And when you submit, you can download a ZIP of your shapefile.

Pretty simple. I don’t really know what the use case is – if you have GIS and Long/Lat you would just import it directly. And if you don’t have GIS, why do you need a shapefile? But I guess this shows how you can perform GIS data functions through the web using python. Maybe connect some toolboxes and use Arcpy to allow people to run your models with their data – without giving your model and logic away.

My code is not pretty and no built for production – it is built to work. Here it is.

import cherrypy
import shapefile
from cherrypy.lib.static import serve_file
import zipfile

class SHP(object):

def index(self):
return “””<HTML><HEAD><TITLE>SHAPEFILE CREATOR</TITLE></HEAD>
<BODY><FORM NAME=’shp’ action=’paul’>Latitude: <input type=’text’ name=’lat’><BR>Longitude: <input type=’text’ name=’long’>
<BR>Comment: <input type=’text’ name=’comment’><BR><input type=’submit’ Value=’SUBMIT’>
</FORM></BODY></HTML>”””

index.exposed = True

def paul(self,lat,long,comment):
w = shapefile.Writer(shapefile.POINT)
Flat=float(lat)
Flong=float(long)
w.point(Flong, Flat)
w.field(‘Comment’)
w.record(comment)
w.save(‘Web’)
prj = open(“Web.prj”, “w”)
epsg = ‘GEOGCS[“WGS 84”,’
epsg += ‘DATUM[“WGS_1984”,’
epsg += ‘SPHEROID[“WGS 84”,6378137,298.257223563]]’
epsg += ‘,PRIMEM[“Greenwich”,0],’
epsg += ‘UNIT[“degree”,0.0174532925199433]]’
prj.write(epsg)
prj.close()
zipped = zipfile.ZipFile(‘YourShapefile.zip’, mode=’w’)
zipped.write(‘Web.shp’)
zipped.write(‘Web.shx’)
zipped.write(‘Web.dbf’)
zipped.write(‘Web.prj’)
zipped.close()
return “Download Shapefile: <a href=’/get?filepath=C:\Documents and Settings\user\Desktop\YourShapefile.zip’>YourShapefile</a>”

paul.exposed = True

def get(self, filepath):
return serve_file(filepath, “application/x-download”, “attachment”)
get.exposed = True

cherrypy.config.update({‘server.socket_host’: ‘127.0.0.1’,
‘server.socket_port’: 8000,
})

cherrypy.quickstart(SHP())