Tag Archives: pika

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

Advertisements

Auto Message Popups in ArcGIS Desktop Explorer From RabbitMQ

19 Apr
Message sent from terminal to ArcGIS Desktop Explorer Extension.

Message sent from terminal to ArcGIS Desktop Explorer Extension.

My previous post showed how to send messages to GIS from a terminal using Python-Pika, RabbitMQ, and C#. It required the user to click a button to receive them. I have modified code from several sources to make it run on a thread- as an extension to ArcGIS Desktop Explorer. Every 2 seconds, the extension checks for messages.

I modified code from:

LosTechies – For C#.

RabbitMQ Tutorial – For Python Producer.

And the ArcGIS Resource Center for the threading info.

I can send you the Addin .EAZ if you wish. Here is what I came up with:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using RabbitMQ.Client;

using ESRI.ArcGISExplorer;
using ESRI.ArcGISExplorer.Application;
using ESRI.ArcGISExplorer.Mapping;
using ESRI.ArcGISExplorer.Geometry;
using ESRI.ArcGISExplorer.Data;
using ESRI.ArcGISExplorer.Threading;
namespace RabbitMQgisExtension
{
public class Extension : ESRI.ArcGISExplorer.Application.Extension
{
string msg;
static IConnection connection;
static IModel channel;
System.Timers.Timer _t = new System.Timers.Timer(2000);

public override void OnStartup()
{
_t.Start();
_t.Elapsed += new System.Timers.ElapsedEventHandler(_t_Elapsed);

}

public override void OnShutdown()
{
_t.Stop();
channel.Close();
connection.Close();
}

void _t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
var connectionFactory = new ConnectionFactory();

connection = connectionFactory.CreateConnection();
channel = connection.CreateModel();
channel.ExchangeDeclare(“GIS”, ExchangeType.Direct);
channel.QueueDeclare(“GIS”, false, false, false, null);
channel.QueueBind(“GIS”, “GIS”, “PAUL”);
BasicGetResult result = channel.BasicGet(“GIS”, true);

if (result != null)
{
msg = Encoding.UTF8.GetString(result.Body);
MessageBox.Show(msg, “You’ve Got a Message!”);
//If set Message to send coords in form “35,-106” Next lines will draw points.
//string[] coords = msg.Split(‘,’);
// float x = float.Parse(coords[0]);
// float y = float.Parse(coords[1]);
//Note fromRabbit = new Note(“From RabbitMQ”, new ESRI.ArcGISExplorer.Geometry.Point(y, x));
//ESRI.ArcGISExplorer.Application.Application.ActiveMapDisplay.Map.ChildItems.Add(fromRabbit);
}
}

 

and the Python Producer – EXAMPLE: python send.py KEY TEXT

(python send.py PAUL message to you):

import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(
host=’localhost’))
channel = connection.channel()

channel.exchange_declare(exchange=’GIS’,
type=’direct’)

to = sys.argv[1]
message = ‘ ‘.join(sys.argv[2:])

channel.basic_publish(exchange=’GIS’,
routing_key=to,
body=message)
print “Sent %r:%r” % (to, message)
connection.close()

Send Message to GIS or Revit from a Terminal using RabbitMQ, Python, Pika and C#

19 Apr

I have been playing with messaging in software applications. Using RabbitMQ, C# and Python, I got the bright idea to send messages to GIS from a python console – which will later be another program or windows form, but for demo purposes I just needed to verify the possibility. The SDK for my GIS is in C#, and so is the SDK for Revit.
I will show you what I did in GIS and then explain how this would work in Revit.
First, I sent a message to the GIS software.
20130419-081234.jpg
The DOS window is my command center that sends the messages. You can see that there are two commands: one has JOE and one has PAUL in it. You can send messages to every listener, or you can specify a keyword or word pattern – in this case PAUL and JOE are the keywords. My GIS app will only receive messages sent to PAUL. When you click the button, it grabs all waiting messages.
If I can send text, I can send data too. What if I send coordinates? I can draw them in the map.
20130419-081352.jpg
Now it takes the message and does something with it. This example has the sender and receiver on the same machine, but they do not have to be. So for Revit, what if we had a window that could update schedules in Revit with data. A user could input the data and the Revit user could press a button to update the model with the new data. Perfect for additional fields in a schedule. Or you could set it to run as a thread so when a message comes in the box pops up automatically. Here is the Code for the Plugin:
string msg = null;
var connectionFactory = new ConnectionFactory();
IConnection connection = connectionFactory.CreateConnection();
IModel channel = connection.CreateModel();
channel.ExchangeDeclare(“GIS”,ExchangeType.Direct);
channel.QueueDeclare(“GIS”,false,false,false,null);
channel.QueueBind(“GIS”,”GIS”,”PAUL”);
BasicGetResult result = channel.BasicGet(“GIS”, true);
if (result != null)
{
msg = Encoding.UTF8.GetString(result.Body);
MessageBox.Show(msg, “Status”);

}
else
{
MessageBox.Show(“No Messages Waiting.”, “Status”);
}
And the sender in python:
import pika
import sys
connection = pika.BlockingConnection(pika.ConnectionParameters(
host=’localhost’))
channel = connection.channel()
channel.exchange_declare(exchange=’GIS’,
type=’direct’)
to = sys.argv[1]
message = ‘ ‘.join(sys.argv[2:])
channel.basic_publish(exchange=’GIS’,
routing_key=to,
body=message)
print “Sent %r:%r” % (to, message)
connection.close()

Messaging in Python with RabbitMQ and Pika

17 Apr

I just started using RabbitMQ and Pika and sent a message – “hello world!” Cool, but so what. I threw an IF statement in my code to simulate reading the message and doing different tasks based on the content of the message. This is better, but still interested in doing more. How about sending binary data – files?

Sure!

I modified the simple tutorial producer and consumer to send a JPG. The producer opens a jpg image in binary mode RB and reads it to a variable. It then sends that variable to the queue.

The consumer knows to expect a jpg – but you could code all this in assuming it doesn’t know. It opens a blank file, gets the message and writes it to the file in binary mode – wb.

This is cool. Now we can send tasks – files to be operated on. And these tasks can be sent to multiple workers.

Here is the code:

SEND.PY

import pika
import logging
f=open(“image.jpg”,”rb”)
i=f.read()

logging.basicConfig()
connection = pika.BlockingConnection(pika.ConnectionParameters(host=’localhost’))
channel = connection.channel()

channel.queue_declare(queue=’hello’)

channel.basic_publish(exchange=”,routing_key=’hello’,body=i)
print ” [x] Sent ‘Hello World!'”
connection.close()

 

CONSUME.PY

import pika

f=open(“outputimage.jpg”,”wb”)

connection = pika.BlockingConnection(pika.ConnectionParameters(
host=’localhost’))
channel = connection.channel()

channel.queue_declare(queue=’hello’)

print ‘ [*] Waiting for messages. To exit press CTRL+C’

def callback(ch, method, properties, body):
f.write(body)
f.close()
channel.basic_consume(callback,
queue=’hello’,
no_ack=True)

channel.start_consuming()

RabbitMQ, Python and C#

17 Apr
C# consuming a message from python producer via RabbitMQ.

C# consuming a message from python producer via RabbitMQ.

I don’t know much about software patterns. My applications tend to be more of the script variety – though I throw some OOP in for fun. I recently came across RabbitMQ – a message broker. It sits between producers and consumers of messages – it is the queue. I tested out the python hello world example and then got the bright idea to use C# as one piece. The thing about RabbitMQ is that it uses a standard Advanced Messaging Queuing Protocol. This means any language or application that implements that protocol can communicate – think HTTP or FTP protocols.

Here is the python producer taken from the RabbitMQ Tutorial. You will need pika.

import pika
import logging
logging.basicConfig()
connection = pika.BlockingConnection(pika.ConnectionParameters(host=’localhost’))
channel = connection.channel()

channel.queue_declare(queue=’hello’)

channel.basic_publish(exchange=”,routing_key=’hello’,body=’Hello World!’)
print ” [x] Sent ‘Hello World!'”
connection.close()

 

Simple enough. Now I wrote a C# form that consumes the messages onClick of a button and displays them in a text box – appending the new messages as they come in.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using RabbitMQ.Client;

 

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
var connectionFactory = new ConnectionFactory();
IConnection connection = connectionFactory.CreateConnection();
IModel channel = connection.CreateModel();
channel.QueueDeclare(“hello”, false, false, false, null);
BasicGetResult result = channel.BasicGet(“hello”, true);
if (result != null)
{
string message = Encoding.UTF8.GetString(result.Body);

textBox1.Text += message+”\r\n”;
}

channel.Close();
connection.Close();
}
}
}