Connecting to MQTT and expiring component

I’m trying to run this script in a python script to simulate a robot:

Run the following code in VS CODE

import paho.mqtt.client as mqtt
import time

broker = "mqtt.eclipseprojects.io"
port = 1883
topic = "robot/signal"

client = mqtt.Client()
client.connect(broker, port, 60)
client.loop_start()

message_count = 0
try:
    while True:
        payload = f"Simulated message {message_count}"
        client.publish(topic, payload)
        print(f"Published: {payload}")
        message_count += 1
        time.sleep(1)
except KeyboardInterrupt:
    client.loop_stop()
    client.disconnect()

Now I woujld like to listen to this in Grasshopper and expire a pytho ncomponent everytime it fires.

For this I use this code.

import paho.mqtt.client as mqtt
import Rhino
import Grasshopper

class MyComponent(Grasshopper.Kernel.GH_ScriptInstance):
    def __init__(self):
        # Initialize instance variables.
        self.mqtt_client = None
        self.message_data = None
        self.setup_mqtt()
    
    def setup_mqtt(self):
        # Create and configure the MQTT client if it hasn't been initialized.
        if self.mqtt_client is None:
            self.mqtt_client = mqtt.Client()
            self.mqtt_client.on_connect = self.on_connect
            self.mqtt_client.on_message = self.on_message
            self.mqtt_client.connect("mqtt.eclipseprojects.io", 1883, 60)
            self.mqtt_client.loop_start()
    
    def on_connect(self, client, userdata, flags, rc):
        print("Connected with result code " + str(rc))
        client.subscribe("robot/signal")

    def on_message(self, client, userdata, msg):
        # Update message_data with the received MQTT message.
        self.message_data = msg.payload.decode()
        print("Received message: " + self.message_data)
        # Safely expire the component solution on the main thread.
        try:
            ghenv.Component.ExpireSolution(True)
        except Exception as e:
            self.message_data = "Error expiring solution: " + str(e)
    
    def RunScript(self, x, y):
        # When the component is executed, check if a new MQTT message was received.
        output = "Hello Python 3 in Grasshopper! Subscription active."
        if self.message_data:
            output = self.message_data
        print(output)
        return output

But Rhino immediately crashes. Any suggestions why?

Hi @Timo_Harboe_Nielsen,

You don’t get a traceback or rhino crash report when it crashes?

This script is admittedly over my head… however, perhaps you could more directly target the component to expire “by nickname” as in this code instead of expiring the whole solution:

for obj in gh.Instances.ActiveCanvas.Document.Objects:
    if obj.NickName == "ExpireMePlease":
        print("Valid Nickname Match Found")
        obj.ExpireSolution(True)

I think it was @AndersDeleuran that turned me on to this method initially

1 Like