From 6196130f7206c1fd0a6deda105c4470f462056ca Mon Sep 17 00:00:00 2001 From: Gonzalo Casas Date: Mon, 27 May 2024 11:27:33 +0200 Subject: [PATCH 1/2] Add GH components --- CHANGELOG.md | 2 + .../ghpython/components/Ce_Message/code.py | 64 ++++++++++++++++++ .../ghpython/components/Ce_Message/icon.png | Bin 0 -> 1505 bytes .../components/Ce_Message/metadata.json | 25 +++++++ .../components/Ce_MqttTransport/code.py | 40 +++++++++++ .../components/Ce_MqttTransport/icon.png | Bin 0 -> 1439 bytes .../components/Ce_MqttTransport/metadata.json | 40 +++++++++++ .../ghpython/components/Ce_Publish/code.py | 43 ++++++++++++ .../ghpython/components/Ce_Publish/icon.png | Bin 0 -> 1684 bytes .../components/Ce_Publish/metadata.json | 40 +++++++++++ .../ghpython/components/Ce_Subscribe/code.py | 64 ++++++++++++++++++ .../ghpython/components/Ce_Subscribe/icon.png | Bin 0 -> 1671 bytes .../components/Ce_Subscribe/metadata.json | 41 +++++++++++ 13 files changed, 359 insertions(+) create mode 100644 src/compas_eve/ghpython/components/Ce_Message/code.py create mode 100644 src/compas_eve/ghpython/components/Ce_Message/icon.png create mode 100644 src/compas_eve/ghpython/components/Ce_Message/metadata.json create mode 100644 src/compas_eve/ghpython/components/Ce_MqttTransport/code.py create mode 100644 src/compas_eve/ghpython/components/Ce_MqttTransport/icon.png create mode 100644 src/compas_eve/ghpython/components/Ce_MqttTransport/metadata.json create mode 100644 src/compas_eve/ghpython/components/Ce_Publish/code.py create mode 100644 src/compas_eve/ghpython/components/Ce_Publish/icon.png create mode 100644 src/compas_eve/ghpython/components/Ce_Publish/metadata.json create mode 100644 src/compas_eve/ghpython/components/Ce_Subscribe/code.py create mode 100644 src/compas_eve/ghpython/components/Ce_Subscribe/icon.png create mode 100644 src/compas_eve/ghpython/components/Ce_Subscribe/metadata.json diff --git a/CHANGELOG.md b/CHANGELOG.md index f52b7f8..15a0ec0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/compas_eve/ghpython/components/Ce_Message/code.py b/src/compas_eve/ghpython/components/Ce_Message/code.py new file mode 100644 index 0000000..d5c7915 --- /dev/null +++ b/src/compas_eve/ghpython/components/Ce_Message/code.py @@ -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) diff --git a/src/compas_eve/ghpython/components/Ce_Message/icon.png b/src/compas_eve/ghpython/components/Ce_Message/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..af649018745b21a4b30b0d60c97b1290aa5b5b97 GIT binary patch literal 1505 zcmV<71s?i|P)8V?|;v8o;+9SDR!PJv9yFcCy&jWDw&y`VQPBz z<-z{G?}KcDlniWkLn%R)m*Xsl=0NXRS%9+m))cHyT5#vi9VsX%ko^37^UFR%eU9$ay;0CM~GZCPAgl(Moi zX=`f}5s^K6_DFksdlJjH`DM`_2Bs3BP}p?UG!3N`j~+duw6v6)H*eze`8aXn1nuqZ zhzNl|0EfdtOG^uT_wEH?X=w>v*ONL3OwA;;@XSQ;!=bxL1rafaeB;IqDl03wbmE!I$vz$70 zih+Rvyk0NcwrwLA4AS4EmuqLd;UjRN3uxll^c(9i(D=;$aO zkB2{Wb+dDaf7(dT&Q`iJo0V9&#AZt!`1jZdE~kTg_wF$`ILP$$H1qTGhzS2J5kV=1 z-EPP2cH{AQ@cDcs1adqDOifK}(o-EhSkm2C(%mQ{#u)}9k2LV zU%Zaht5>0bx!^p5Lql|4|1%$4`8EIed(TH0mhT#N=Wj$n%s)P#G%!n=upD0eDv9{_ zKwh%C-03ctOIHelbHPL`IJp3-58e2gVROEZtbkGoD#_qKy!`U0@gWp500000NkvXX Hu0mjf_7n1r literal 0 HcmV?d00001 diff --git a/src/compas_eve/ghpython/components/Ce_Message/metadata.json b/src/compas_eve/ghpython/components/Ce_Message/metadata.json new file mode 100644 index 0000000..82fa9f4 --- /dev/null +++ b/src/compas_eve/ghpython/components/Ce_Message/metadata.json @@ -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." + } + ] + } +} diff --git a/src/compas_eve/ghpython/components/Ce_MqttTransport/code.py b/src/compas_eve/ghpython/components/Ce_MqttTransport/code.py new file mode 100644 index 0000000..ef0eba9 --- /dev/null +++ b/src/compas_eve/ghpython/components/Ce_MqttTransport/code.py @@ -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 MqttTransportConnect(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) diff --git a/src/compas_eve/ghpython/components/Ce_MqttTransport/icon.png b/src/compas_eve/ghpython/components/Ce_MqttTransport/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b5877cd8247fc79b8bda351c80c52f93fb51d89e GIT binary patch literal 1439 zcmV;Q1z`G#P)grcFvBpYU?HK!w#r3=38FRi zqQ+i`CMp=UYH*3QY7=X!Ce|uisTEhOOXJddp|MR|Nb4>(je^xNqM$HrZo@!fKxWR& z`FnvL#HDwAFTeNA_nhzl{{Kiq2=1J%`f$sfEmKTEvo0bcg69&dieLE2otdkAvSd86 zQRZcx-+f-cb#93+J}#bqQT+*o0z8fEQs?iOe=sdKy*vWIefrh}UvulU7$ixj)Aa%n z1ckzl6E{LJP8&G|Ij;bm?>hB%mqV(%Ux&-0M(z0;YNn_eynA($dfRUh$4 zG7w3aFfuY$te7#QM^6ha_~{@uX(*qrm_Y7lqx(PtZ2{JeU&r~2=NZHx{P>A8#RW^c zN(_<^0#Aj<-}O&dRQtnr9#%i3?wW^tj@JkjyO!1XrTokK1O7Xpm0|qj!Z`% z(C!(f9NBw>INrjQoK(NI_FI=EgaBvWj1q-gt{{U%bt+ z)yKH>$0cmo7{CCksb)yR5H{Z0h$-5nWmmrQH5Kkkl5kPQZI-NA!nm)-{Wsvb&h0tJ zwwc>dQL$sEnrbozXRzVk1})?B_?VkK7ZWBF6ihl3C2b`hlhxF-gFOX%*fDDdW!q2V zt$)%7kTWBPO%Go%^q zb<|m9WTJ^?WWh)Z))iohw`fh8|88dCu!R^fV8%=%jTE0LCT&z20D-Omh5ZT%hJ%C% zkz{vz);AUPOc3jcC6Po1GZ-^wj_*It9M^2zzqvJlJ=4yz{mby-LysOAnS-+qXuiR0 zAg3S)FJ5G1kb3I9|7LprKQb~Yq@V;tEFHg;o5yczepY@Kqq9fTNF#RaT)SVv_2bty zKYLC#QCLt=(98N)0nZgCOf0cjv9fl;H?%gjYTl%hNf=J~ z4z2cDz>5$sEgYJCP^&vLoxGPZ3@BPcdQSk@AR|%Qd|p@O~1{diDas;c!rT!!SmScxmD4FITl%%E(kKSP%#T zbo1c$1I>#~w)MP+Zbb%&08m3}q#r*K=ryzeq~})wLG6`Vt%)t!hJ`4e@{|BUS{r(I z6cuYBK!9Mk60HI9zR#Olx~z0cKefN4*J-CEgb;e63SBUyfL>@#O#Mv6IR?@Z=s>8T ti|jpN*(ehm7aPti%KHhPJ+%K*{{qXkFxK$2g!BLa002ovPDHLkV1i6jln4L- literal 0 HcmV?d00001 diff --git a/src/compas_eve/ghpython/components/Ce_MqttTransport/metadata.json b/src/compas_eve/ghpython/components/Ce_MqttTransport/metadata.json new file mode 100644 index 0000000..5288a2c --- /dev/null +++ b/src/compas_eve/ghpython/components/Ce_MqttTransport/metadata.json @@ -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." + } + ] + } +} diff --git a/src/compas_eve/ghpython/components/Ce_Publish/code.py b/src/compas_eve/ghpython/components/Ce_Publish/code.py new file mode 100644 index 0000000..a8c6837 --- /dev/null +++ b/src/compas_eve/ghpython/components/Ce_Publish/code.py @@ -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] diff --git a/src/compas_eve/ghpython/components/Ce_Publish/icon.png b/src/compas_eve/ghpython/components/Ce_Publish/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c0e24f703cb615c763830a7624a881a6a7bfecc1 GIT binary patch literal 1684 zcmV;F25b3=P)?O4 zsGG}VW?Z&VR73=$F>J{$X4w+h41~=Eh{+<7ku79*GC^ewahX%tbVEQW*S55@g_d&; zr#t&=lk5B-}4wd660eEhKDI1Tg5$dTj=ZW}JO&1D-u2euH@*ja zeeV24ENorC%o)?Dtf)W|on2i8C;st%-Jkz*bm`lN4{ina)Yeb=uID-J{4d#&SeBif zTyP>^1(IJ_`hbqT{a1Y&{q3E<>!B|{B48No)sehnuw&rdX3L9Wc~P8bF2H&~FYVkt z%E-|0kTyR5O)Z{&zwVvBOzWR{UboV>Mq&2u`=v0Rfai>t2X@W~d+{P71tkCvgQGW( z9J?dRQ>V`g5Y>o@2+)ZWAKaPEdnaVPn1B^-ei?3VF+>Z?adQic0qy_Yfh>5&+|TJZ zzyG5oDRt8q#P!hoE&9s2IRaPLx&|dle>m_bHO-il)qDNOTLNU~#4Eg_G1#FKAxK_- zdG+HP8aF@l6k!?eP+OW`DswCM*dzO{K1?;bxvCY@yWu3bbTk?eFnwzdrj zRskG5d#+uNt>379zuK>%jIVf6*+^6I6tAonZixWpEc6s#79Ek<#VQzABX9-Ci^VmV zNb10AhqSWo33YUK3ClZbc}11=b+r>%@#rHA`vFs?G|=4K%#DGYBvUu&I{P6S?xpK$ z5A%l}V0PzXE?m5V{60F)oFthXVDM&w1+A?#G)(1c&o$PpTEW=L3JS+oPcRdkW+y)S z=R3Io3Ks)B31eMmwG*KxRf=?Xy*P*XD=-yc~A#u!RVOS#hB$EL^E zP+U^PweD^#+h)dRTa%2P*pPT-?>0PWUnNy_$|d)ENoLDY^u%OkSzV>l&0-Q6npwFR=Cf zAN=rBSH+KC+$M}G6UkFvMUBd88)Wj!M|u-2?0}rY*K3^6_<=)ZC(N zJANwMT-8r$)Tz^_vj&4Olq8*NKd;7VGllWA<;889GHaen#?`3h-upGHb*XBb=7^l4 zV-7)ZsJFLoQEpxwNu-iVTsOkg>({Y-`Er)rw~V{%>v?L!Mh4P8zVA~KkFaC=b{eM5 z;=-j1R9989>*ueMN+d`nQy63D>+8e#{u@}a;wmRzrb*L3qvm;^SG=@RW#cC+@cnGm z+h5u>Qe!77H<~9vTetmWRH??-Hz~KcT+QDD{V0h>?+w;yj zlCV8*-C%$J!->)oT*tvO24h*H42&I9#^FN;?zkt}yJA^*u1hMFWU#*<%XQia102g3 zFs4Vg{k5)+&Q}Zb^XR{RorOyt#Bpp82w{vN8i`%G0) zxN(D9iJR*z*ZrCJZ~yLaU>Sq&`;)?P^WjhQG z43O^c-ESh^w{6!wDZ&4BkQG_N&jeF6Jp4sq0hV27Jg-;)Lqpe5*bX{^>;2ks-49R* e#vsfn2mb-R{GO?pn^->p0000EaNTzDf zoq79N0N?29*@TUKy|^pfj$m~)NFq8p>HgrK7aRZl&bwRApLz2DfMX3UD}SVE${79^ zvTiS#Qsw{@{VM=6pWX5RuM7=wA!cV2oSd9mv^G34!q0#4%LGsW7XZHe$}f34tY6d0mY|o>*vCuuj-Pm)5E=nIEi@+}m(82z@=+~fUby%nua8IA8os;a_tx2S1VFjWRjqle zAQcP)#mwwWk3PN|58b~RmSy3{(WB@HuR$~#MX-JaVv|vX@7aLN#W<2zfTreZ0B*Fk zu0||&1MAnX!>dP*z%Wg0>e+z3-`@vwE_JwAGy%wZP%rnhP%M%pi^U?h4Q%J-D?^-_ ziSs81e#U!xdI*4D`t{%Wy~`v3hTFs3_QW2h(rI2Bk8s<-0CTxq=_c-~5COR!0QL?% zxpzrE$3{muITd3vnPMaoApj1Xj`KivUSM==l!-)=Q?VFFhKH8;fAj>3P0Ib`xoo(NIh5#t30lJsf6Hp0&n%%`@I>S?M zoaWaDc5os(Nl4ne(7eHGBzf-qUwHJlud}hah26dPayF4-(J)FUdZ_;q27Mj|oGx~4 z=wULIB1z`+1twEz-naDu*4Ev@Umg1m-#K@lB+zc~P4S*RA#i3s)| zdIb%kYSe~8sH+WuAd<-xBIDz*NK{r;A>i{tmStSHbP35+8j;uxzWw+%`21dc9E(Ac zWrR2MWl+g7$Ws%vJMFUT@qHN7?U zZ0+nOATRP=(Ylt$j-Oz|r^0EV%zGVBDVzaTHm;(xx}K7)oPf+9KmXI){&WlR!i$51 zP$_gLoz?ZMXjny2UO8VIn`Z(j^Sss2+R3$jo7uT(D=U{bvbn93gNJ@js1CNQT)n6# znU+P8938vL)$Ml?LgW4y2f4DNoBn0>?7a7L?C9IVhSs}@GVgl|O!M^g^vouQ(*=^q zW-?G!9Z&7riT?h6Y~Ff5?rdqnle_mIkuzWz2K+7^hYlXZs`d_ibp0dLg@QQz>TAfR z)5vDB5JF&PW(LAA-iBoNg%no>o7b#oTlal*1%j+tzJlh07j*FD!}B>-Y*cMd0^otc zmlmaJc}puDzDl-re}+wK)=??1q_F!MB}q{tMm~Qs7Mp@)82~Lvl7JAR)Y5nF7{J8T z4fOW*p|i6Sqt_ zc@rBqKL|yU0RjXegn&)gA%wtOE(dZxun>S{5fjl#xZQ3391ge~cI2{iFfDT*gm~@~&H@1elCX-! z$8=ZuVUN39_WJ#Bdps}=1D0jMG))Ky$chXh1Y|`)GMU89>1oW)&SEZ|+9|2(FNpuv zZ;5~;1PsGyw(@h&*}Q>%kJp1@(SR&Vu<1Gofm|*J(t;!_NG1}<#ivgSUHhS|s+URN z{|c10B*G|~D_JOf0YEP#xlw4Ej{uO*-vq5OfM=m Date: Mon, 27 May 2024 14:00:13 +0200 Subject: [PATCH 2/2] Rename component --- .../{Ce_MqttTransport => Ce_MqttConnect}/code.py | 2 +- .../{Ce_MqttTransport => Ce_MqttConnect}/icon.png | Bin .../metadata.json | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename src/compas_eve/ghpython/components/{Ce_MqttTransport => Ce_MqttConnect}/code.py (96%) rename src/compas_eve/ghpython/components/{Ce_MqttTransport => Ce_MqttConnect}/icon.png (100%) rename src/compas_eve/ghpython/components/{Ce_MqttTransport => Ce_MqttConnect}/metadata.json (100%) diff --git a/src/compas_eve/ghpython/components/Ce_MqttTransport/code.py b/src/compas_eve/ghpython/components/Ce_MqttConnect/code.py similarity index 96% rename from src/compas_eve/ghpython/components/Ce_MqttTransport/code.py rename to src/compas_eve/ghpython/components/Ce_MqttConnect/code.py index ef0eba9..edae7d0 100644 --- a/src/compas_eve/ghpython/components/Ce_MqttTransport/code.py +++ b/src/compas_eve/ghpython/components/Ce_MqttConnect/code.py @@ -13,7 +13,7 @@ from compas_eve.mqtt import MqttTransport -class MqttTransportConnect(component): +class MqttConnectComponent(component): def RunScript(self, host, port, connect): mqtt_transport = None diff --git a/src/compas_eve/ghpython/components/Ce_MqttTransport/icon.png b/src/compas_eve/ghpython/components/Ce_MqttConnect/icon.png similarity index 100% rename from src/compas_eve/ghpython/components/Ce_MqttTransport/icon.png rename to src/compas_eve/ghpython/components/Ce_MqttConnect/icon.png diff --git a/src/compas_eve/ghpython/components/Ce_MqttTransport/metadata.json b/src/compas_eve/ghpython/components/Ce_MqttConnect/metadata.json similarity index 100% rename from src/compas_eve/ghpython/components/Ce_MqttTransport/metadata.json rename to src/compas_eve/ghpython/components/Ce_MqttConnect/metadata.json