Skip to content

Commit

Permalink
Merge pull request #15 from compas-dev/msg_components
Browse files Browse the repository at this point in the history
Add GH components
  • Loading branch information
gonzalocasas authored May 27, 2024
2 parents 2b551a0 + ec62b77 commit 37ab513
Show file tree
Hide file tree
Showing 13 changed files with 359 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

* Add Grasshopper components for publishing and subscribing to topics, for creating messages and connecting to MQTT transports.

### Changed

### Removed
Expand Down
64 changes: 64 additions & 0 deletions src/compas_eve/ghpython/components/Ce_Message/code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Create a message.
COMPAS EVE v0.5.0
"""

import System

import Rhino.Geometry as rg
import rhinoscriptsyntax as rs

from compas.geometry import Brep
from compas_eve import Message
from compas_rhino import conversions

component = ghenv.Component # noqa: F821

local_values = locals()
data = dict()

for input_param in component.Params.Input:
name = input_param.NickName
value = local_values[name]
if isinstance(value, System.Guid):
try:
value = rs.coercegeometry(value)
except: # noqa: E722
pass
if isinstance(value, rg.Point3d):
value = conversions.point_to_compas(value)
elif isinstance(value, rg.Box):
value = conversions.box_to_compas(value)
elif isinstance(value, rg.Vector3d):
value = conversions.vector_to_compas(value)
elif isinstance(value, rg.Arc):
value = conversions.arc_to_compas(value)
elif isinstance(value, rg.Circle):
value = conversions.circle_to_compas(value)
elif isinstance(value, rg.Curve):
value = conversions.curve_to_compas(value)
elif isinstance(value, rg.Cone):
value = conversions.cone_to_compas(value)
elif isinstance(value, rg.Cylinder):
value = conversions.cylinder_to_compas(value)
elif isinstance(value, rg.Line):
value = conversions.line_to_compas(value)
elif isinstance(value, rg.Mesh):
value = conversions.mesh_to_compas(value)
elif isinstance(value, rg.Plane):
value = conversions.plane_to_compas_frame(value)
elif isinstance(value, rg.Sphere):
value = conversions.sphere_to_compas(value)
elif isinstance(value, rg.PolylineCurve):
value = conversions.polygon_to_compas(value)
elif isinstance(value, rg.Polyline):
value = conversions.polyline_to_compas(value)
elif isinstance(value, rg.Surface):
value = conversions.surface_to_compas(value)
elif isinstance(value, rg.Brep):
value = Brep.from_native(value)

data[name] = value

message = Message(**data)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 25 additions & 0 deletions src/compas_eve/ghpython/components/Ce_Message/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "Create message",
"nickname": "Message",
"category": "COMPAS EVE",
"subcategory": "Events",
"description": "Create a new message.",
"exposure": 2,

"ghpython": {
"isAdvancedMode": false,
"iconDisplay": 2,
"inputParameters": [
{
"name": "x",
"description": "Example input field. Add or remove fields as needed."
}
],
"outputParameters": [
{
"name": "message",
"description": "The newly created message."
}
]
}
}
40 changes: 40 additions & 0 deletions src/compas_eve/ghpython/components/Ce_MqttConnect/code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Connect or disconnect to an MQTT broker.
COMPAS EVE v0.5.0
"""

from threading import Event

from compas_ghpython import create_id
from ghpythonlib.componentbase import executingcomponent as component
from scriptcontext import sticky as st

from compas_eve.mqtt import MqttTransport


class MqttConnectComponent(component):
def RunScript(self, host, port, connect):
mqtt_transport = None

host = host or "127.0.0.1"
port = port or 1883

key = create_id(self, "mqtt_transport")
mqtt_transport = st.get(key, None)

if mqtt_transport:
st[key].close()

if connect:
event = Event()
transport = MqttTransport(host, port)
transport.on_ready(event.set)
if not event.wait(5):
raise Exception("Failed to connect to MQTT broker.")

st[key] = transport

mqtt_transport = st.get(key, None)
is_connected = mqtt_transport._is_connected if mqtt_transport else False
return (mqtt_transport, is_connected)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions src/compas_eve/ghpython/components/Ce_MqttConnect/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "MQTT Transport",
"nickname": "MQTT",
"category": "COMPAS EVE",
"subcategory": "Events",
"description": "Connect or disconnect to an MQTT broker.",
"exposure": 2,

"ghpython": {
"isAdvancedMode": true,
"iconDisplay": 2,
"inputParameters": [
{
"name": "host",
"description": "The host address of the MQTT broker. Defaults to 127.0.0.1.",
"typeHintID": "str"
},
{
"name": "port",
"description": "The port of MQTT broker. Defaults to 1883.",
"typeHintID": "int"
},
{
"name": "connect",
"description": "If True, connects to MQTT broker. If False, disconnects from MQTT. Defaults to False.",
"typeHintID": "bool"
}
],
"outputParameters": [
{
"name": "mqtt_transport",
"description": "The MQTT transport instance."
},
{
"name": "is_connected",
"description": "True if connection established."
}
]
}
}
43 changes: 43 additions & 0 deletions src/compas_eve/ghpython/components/Ce_Publish/code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""
Publish messages to a topic.
COMPAS EVE v0.5.0
"""

import time

from ghpythonlib.componentbase import executingcomponent as component
from scriptcontext import sticky as st

from compas_eve import Topic
from compas_eve import Publisher
from compas_ghpython import create_id


class PublishComponent(component):
def RunScript(self, transport, topic_name, message, on):
if not topic_name:
raise ValueError("Please specify the name of the topic")

if on is None:
on = True

key = create_id(self, "publisher_{}".format(id(transport)))
key_count = create_id(self, "publisher_count_{}".format(id(transport)))
publisher = st.get(key, None)

if not publisher:
topic = Topic(topic_name)
publisher = Publisher(topic, transport=transport)
publisher.advertise()
time.sleep(0.2)

st[key] = publisher
st[key_count] = 0

if on and message:
st[key_count] += 1
publisher.publish(message)
self.Message = "Published {} messages".format(st[key_count])

return st[key_count]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
40 changes: 40 additions & 0 deletions src/compas_eve/ghpython/components/Ce_Publish/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "Publish to topic",
"nickname": "Publish",
"category": "COMPAS EVE",
"subcategory": "Events",
"description": "Publish messages to a topic.",
"exposure": 4,

"ghpython": {
"isAdvancedMode": true,
"iconDisplay": 2,
"inputParameters": [
{
"name": "transport",
"description": "An instance of transport. If no transport is specified, it will use in-memory transport."
},
{
"name": "topic_name",
"description": "The name of the topic to publish to to, e.g. `/compas_eve/hello_world/`.",
"typeHintID": "str"
},
{
"name": "message",
"description": "The message to publish. It can be an instance of `Message` or a dictionary"
},
{
"name": "on",
"description": "Turn ON or OFF the publisher. Defaults to True.",
"typeHintID": "bool"
}

],
"outputParameters": [
{
"name": "count",
"description": "The count of published messages on the selected topic."
}
]
}
}
64 changes: 64 additions & 0 deletions src/compas_eve/ghpython/components/Ce_Subscribe/code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
Subscribe to a topic to receive messages.
COMPAS EVE v0.5.0
"""

from ghpythonlib.componentbase import executingcomponent as component

from compas_eve import Topic
from compas_eve import Subscriber
from compas_eve.ghpython import BackgroundWorker


class SubscribeComponent(component):
def RunScript(self, transport, topic_name, start, on):
if not topic_name:
raise ValueError("Please specify the name of the topic")

if on is None:
on = True

if not on:
BackgroundWorker.stop_instance_by_component(ghenv) # noqa: F821
return None

args = (
transport,
topic_name,
)

self.worker = BackgroundWorker.instance_by_component(
ghenv, # noqa: F821
self.start_subscriber,
dispose_function=self.stop_subscriber,
force_new=start,
auto_set_done=False,
args=args,
)

if not self.worker.is_working() and not self.worker.is_done() and start:
self.worker.start_work()

if hasattr(self.worker, "result"):
return self.worker.result
else:
return None

def start_subscriber(self, worker, transport, topic_name):
worker.count = 0

def received_message(message):
worker.count += 1
worker.display_message("Received {} messages".format(worker.count))
worker.update_result(message, 10)

topic = Topic(topic_name)
worker.subscriber = Subscriber(topic, callback=received_message, transport=transport)
worker.subscriber.subscribe()
worker.display_message("Subscribed")

def stop_subscriber(self, worker):
if hasattr(worker, "subscriber"):
worker.subscriber.unsubscribe()
worker.display_message("Stopped")
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions src/compas_eve/ghpython/components/Ce_Subscribe/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "Subscribe to topic",
"nickname": "Subscribe",
"category": "COMPAS EVE",
"subcategory": "Events",
"description": "Subscribe to a topic to receive messages.",
"exposure": 4,

"ghpython": {
"isAdvancedMode": true,
"iconDisplay": 2,
"inputParameters": [
{
"name": "transport",
"description": "An instance of transport. If no transport is specified, it will use in-memory transport."
},
{
"name": "topic_name",
"description": "The name of the topic to subscribe to, e.g. `/compas_eve/hello_world/`.",
"typeHintID": "str"
},
{
"name": "start",
"description": "Starts/Restarts the subscriber.",
"typeHintID": "bool"
},
{
"name": "on",
"description": "Turn ON or OFF the subscriber. Defaults to True.",
"typeHintID": "bool"
}

],
"outputParameters": [
{
"name": "message",
"description": "The last message received on the selected topic."
}
]
}
}

0 comments on commit 37ab513

Please sign in to comment.