{ "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 1, "revision" : 6, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 177.0, 94.0, 1257.0, 888.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Menlo", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-35", "linecount" : 3, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 366.0, 631.0, 211.0, 48.0 ], "text" : "some NTP methods could be devised to find concrete diff/latency" } } , { "box" : { "id" : "obj-4", "maxclass" : "led", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "int" ], "parameter_enable" : 0, "patching_rect" : [ 610.0, 412.0, 24.0, 24.0 ] } } , { "box" : { "id" : "obj-33", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 218.0, 76.0, 59.0, 22.0 ], "text" : "connect" } } , { "box" : { "id" : "obj-30", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 231.0, 117.0, 342.0, 20.0 ], "text" : "connect " } } , { "box" : { "bubble" : 1, "fontname" : "Arial", "fontsize" : 13.0, "id" : "obj-28", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 394.0, 330.0, 239.0, 25.0 ], "text" : "try connection on object instanciation" } } , { "box" : { "bubble" : 1, "fontname" : "Arial", "fontsize" : 13.0, "id" : "obj-26", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 394.0, 284.0, 184.0, 25.0 ], "text" : "MQTT sesssion cleanliness" } } , { "box" : { "bubble" : 1, "fontname" : "Arial", "fontsize" : 13.0, "id" : "obj-24", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 640.0, 261.0, 130.0, 25.0 ], "text" : "Broker credentials" } } , { "box" : { "bubble" : 1, "fontname" : "Arial", "fontsize" : 13.0, "id" : "obj-22", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 640.0, 238.0, 118.0, 25.0 ], "text" : "Broker host/port" } } , { "box" : { "attr" : "password", "id" : "obj-18", "maxclass" : "attrui", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 459.0, 261.0, 177.0, 22.0 ] } } , { "box" : { "attr" : "user", "id" : "obj-16", "maxclass" : "attrui", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 265.0, 261.0, 192.0, 22.0 ] } } , { "box" : { "attr" : "port", "id" : "obj-9", "maxclass" : "attrui", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 522.0, 238.0, 114.0, 22.0 ], "text_width" : 50.0 } } , { "box" : { "attr" : "clean", "id" : "obj-8", "maxclass" : "attrui", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 265.0, 284.0, 123.0, 22.0 ] } } , { "box" : { "attr" : "autoconnect", "id" : "obj-5", "maxclass" : "attrui", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 265.0, 330.0, 123.0, 22.0 ] } } , { "box" : { "attr" : "id", "id" : "obj-2", "maxclass" : "attrui", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 265.0, 215.0, 371.0, 22.0 ] } } , { "box" : { "id" : "obj-29", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 1042.0, 622.0, 139.0, 22.0 ], "text" : "setup patate/bounk" } } , { "box" : { "format" : 6, "id" : "obj-27", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 1006.0, 537.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-25", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 937.0, 538.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-23", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 868.0, 540.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-21", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 990.0, 816.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-19", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 920.0, 812.0, 50.0, 22.0 ] } } , { "box" : { "format" : 6, "id" : "obj-17", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 856.0, 810.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-14", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 856.0, 729.0, 139.0, 22.0 ], "text" : "route patate/bounk" } } , { "box" : { "id" : "obj-13", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 856.0, 622.0, 153.0, 22.0 ], "text" : "prepend patate/bounk" } } , { "box" : { "id" : "obj-12", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 3, "outlettype" : [ "float", "float", "float" ], "patching_rect" : [ 856.0, 768.0, 95.0, 22.0 ], "text" : "unpack f f f" } } , { "box" : { "id" : "obj-10", "maxclass" : "newobj", "numinlets" : 3, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 854.5, 588.0, 81.0, 22.0 ], "text" : "pack f f f" } } , { "box" : { "id" : "obj-7", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 856.0, 692.0, 182.0, 22.0 ], "text" : "mqtt @presume vec" } } , { "box" : { "id" : "obj-6", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 564.0, 484.0, 66.0, 22.0 ], "text" : "@presume" } } , { "box" : { "id" : "obj-171", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 0, "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 1, "revision" : 6, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 34.0, 56.0, 1026.0, 1110.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-7", "linecount" : 8, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 739.0, 85.0, 150.0, 114.0 ], "text" : "float int (min, max, exp)\nascii\nrawbytes\nvec\ntuple (mixed list)\njson\nmatrix\npacked-osc" } } , { "box" : { "id" : "obj-5", "linecount" : 5, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 846.0, 497.0, 150.0, 74.0 ], "text" : "some inspiration from https://github.com/mqtt-smarthome/mqtt-smarthome/blob/master/Architecture.md" } } , { "box" : { "id" : "obj-3", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 418.0, 241.0, 298.0, 34.0 ], "text" : "setup topic qos persistence type min max\n" } } , { "box" : { "id" : "obj-2", "linecount" : 11, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 418.0, 85.0, 298.0, 167.0 ], "text" : "/family/group/parameter_name\n /_value bytes\n /_state 0,1,2\n /_info\n /_label \"parameter name\"\n /_desc \"something bla bla.\"\n /_type [sel]\n /_spec (range? auto-vs-polled?)\n /_ts (ms since set)\n /_tc (ms since change)\n /_get() (poll)\n" } } , { "box" : { "id" : "obj-1", "linecount" : 40, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 80.0, 85.0, 301.0, 556.0 ], "text" : "MQTT is a raw binary protocol, meaning that the raw bytes published will be copied \"blindly\" by the broker to subscribed client.\n\nIt is convenient to use the protocol as an ASCII protocol as all clients, including human terminal forms, can exchange data in a readable manner. The straight 7-bit ASCII string is the simplest form; structured protocols such as JSON are popular higher-level approaches that allows more complex expression while maintaining ASCII simplicity.\n\nBut it is only a presumption; nothing prevents the underlying system to send around structures such as jitter matrice, or OSC packets, or MSP buffers, or MIDI events, or executable bytecode (and optionally apply compression to the packets — it is actually how encryption works in MQTT). It however diminishes intercompatibility in heterogenous networks as the receivers must know (or deduce) the encoding of the received packets, and have the capabiity to turn the binary data into the correct representation of it's contained values.\n\nSo if you're setting up something between 2 clients that you control, you can send whatever you want as you control both ends. \n\nIf you intend to bring in additioonal \n\nBy design MQTT does not provide a \"meta\" layer, or descriptors of the topics. It is up to the local applicationo.\n\n\nConcretely it means building some form of meta-protoccol that will bring \"intelligence\" to the low-level MQTT stuff being passed around. \n\n\n" } } , { "box" : { "id" : "obj-122", "linecount" : 32, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 418.0, 290.0, 298.0, 435.0 ], "text" : "Rant about TCP/UDP, binary vs ASCII, etc.\n\nMQTT is raw binary TCP protocol. Conventionally we've been trying to implement things in a structured format (ex: OSC) in order to normalize/restrict types while minimizing loss (even if padding is often into play). \n\nLikewise it's been said that as a \"send and forget\" protocol UDP is better suited for low-latency, time-critical event (such as sensor data), because no ACK overheard, and if a packet is late, it is already useless; retrying is pointless. \n\nThere are some advantages to TCP: it is inherently a bidirectional connection, so a scheme like the MQTT broker is easy to implement (with UDP, \"calling back\" the origin host is not so simple to do automatically/reliably if dynamic IPs and/or NAT is involved). And of course TCP is reliable so if you're sending an event that must be received, TCP will garantee it.\n\nIf you're building an instrument with sensors operating at 500Hz and aim for \"near physical\" latency, i hope you're doing it on a Bela with a tight interrupt callback method, and not through an Internet connection over your home wifi ending up in an event-driven-yet-polled, graphically specificed processing graph. \n\nFor everything else, MQTT/TCP is pretty great." } } ], "lines" : [ ] } , "patching_rect" : [ 600.0, 667.0, 110.0, 22.0 ], "saved_object_attributes" : { "description" : "", "digest" : "", "globalpatchername" : "", "tags" : "" } , "text" : "p RANT (draft)" } } , { "box" : { "id" : "obj-170", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 0, "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 1, "revision" : 6, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 59.0, 81.0, 558.0, 289.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "id" : "obj-20", "linecount" : 17, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 12.0, 14.0, 493.0, 234.0 ], "text" : "About MQTT Client IDs\n\nThe MQTT protocol requires all clients to have unique IDs -- the broker will abruptly and silently disconnect clients using the same ID until only one is left. The MQTT protocol does not provide feedback when that happens, so if your object systematically disconnects after a short moment, check that you're not getting kicked out because other clients are using the same ID.\n\nIf the attribute @id is not set, a random ID will be generated at object instanciation. In most cases it is probably OK (it does not affect the ability to subscribe and publish; access control of topics are unrelated to client IDs), unless you have special requirements tied to specific clients, or complex/arbitrary subscriptions that you want to maintain in non-clean-sessions.\n\nIt is probably a simpler design to re-subscribe your desired topics upon connection than rely on the broker to remember them in non-clean-sessions. (the global state is somewhat opaque, even if you control the MQTT broker)" } } ], "lines" : [ ] } , "patching_rect" : [ 600.0, 631.0, 124.0, 22.0 ], "saved_object_attributes" : { "description" : "", "digest" : "", "globalpatchername" : "", "tags" : "" } , "text" : "p MQTT-Client-ID" } } , { "box" : { "id" : "obj-168", "maxclass" : "newobj", "numinlets" : 0, "numoutlets" : 0, "patcher" : { "fileversion" : 1, "appversion" : { "major" : 8, "minor" : 1, "revision" : 6, "architecture" : "x64", "modernui" : 1 } , "classnamespace" : "box", "rect" : [ 59.0, 81.0, 584.0, 654.0 ], "bglocked" : 0, "openinpresentation" : 0, "default_fontsize" : 12.0, "default_fontface" : 0, "default_fontname" : "Arial", "gridonopen" : 1, "gridsize" : [ 15.0, 15.0 ], "gridsnaponopen" : 1, "objectsnaponopen" : 1, "statusbarvisible" : 2, "toolbarvisible" : 1, "lefttoolbarpinned" : 0, "toptoolbarpinned" : 0, "righttoolbarpinned" : 0, "bottomtoolbarpinned" : 0, "toolbars_unpinned_last_save" : 0, "tallnewobj" : 0, "boxanimatetime" : 200, "enablehscroll" : 1, "enablevscroll" : 1, "devicewidth" : 0.0, "description" : "", "digest" : "", "tags" : "", "style" : "", "subpatcher_template" : "", "assistshowspatchername" : 0, "boxes" : [ { "box" : { "fontname" : "Arial", "fontsize" : 13.0, "id" : "obj-21", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 5, "outlettype" : [ "", "", "", "", "" ], "patching_rect" : [ 158.0, 374.0, 112.0, 23.0 ], "text" : "regexp ^forum(.*)" } } , { "box" : { "id" : "obj-3", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 156.0, 192.0, 92.0, 22.0 ], "text" : "sprintf forum%s" } } , { "box" : { "id" : "obj-40", "linecount" : 3, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 98.0, 582.5, 163.0, 47.0 ], "text" : "i get around 12ms roundtrip, which is pretty much the same as what ping reports" } } , { "box" : { "id" : "obj-31", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 44.0, 595.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-29", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 70.0, 533.0, 24.0, 24.0 ] } } , { "box" : { "id" : "obj-27", "maxclass" : "button", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "bang" ], "parameter_enable" : 0, "patching_rect" : [ 44.0, 533.0, 24.0, 24.0 ] } } , { "box" : { "id" : "obj-25", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 2, "outlettype" : [ "float", "" ], "patching_rect" : [ 44.0, 568.0, 45.0, 22.0 ], "text" : "timer" } } , { "box" : { "id" : "obj-24", "maxclass" : "slider", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "parameter_enable" : 0, "patching_rect" : [ 107.0, 531.0, 132.0, 24.0 ] } } , { "box" : { "id" : "obj-23", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 107.0, 490.0, 101.0, 22.0 ], "text" : "route /osc/peanut" } } , { "box" : { "id" : "obj-22", "maxclass" : "slider", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "parameter_enable" : 0, "patching_rect" : [ 107.0, 35.0, 132.0, 24.0 ] } } , { "box" : { "id" : "obj-11", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 312.0, 102.0, 167.0, 22.0 ], "text" : "subscribe forum/osc/#" } } , { "box" : { "id" : "obj-8", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 107.0, 102.0, 138.0, 22.0 ], "text" : "udpsend 127.0.0.1 8889" } } , { "box" : { "id" : "obj-5", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 107.0, 465.0, 97.0, 22.0 ], "text" : "udpreceive 8888" } } , { "box" : { "id" : "obj-4", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 107.0, 76.0, 87.0, 22.0 ], "text" : "/osc/peanut $1" } } , { "box" : { "id" : "obj-2", "maxclass" : "toggle", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "int" ], "parameter_enable" : 0, "patching_rect" : [ 174.0, 319.0, 24.0, 24.0 ] } } , { "box" : { "id" : "obj-166", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 156.0, 243.0, 94.0, 22.0 ], "text" : "prepend publish" } } , { "box" : { "id" : "obj-165", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 156.0, 217.0, 116.0, 22.0 ], "text" : "zl join" } } , { "box" : { "id" : "obj-164", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 253.0, 192.0, 57.0, 22.0 ], "text" : "tosymbol" } } , { "box" : { "id" : "obj-163", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 156.0, 162.0, 112.0, 22.0 ], "text" : "zl slice 1" } } , { "box" : { "id" : "obj-162", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 156.0, 137.0, 97.0, 22.0 ], "text" : "udpreceive 8889" } } , { "box" : { "id" : "obj-161", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 181.25, 435.0, 138.0, 22.0 ], "text" : "udpsend 127.0.0.1 8888" } } , { "box" : { "id" : "obj-160", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 181.25, 405.0, 114.75, 22.0 ], "text" : "zl join" } } , { "box" : { "id" : "obj-159", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 277.0, 374.0, 71.0, 22.0 ], "text" : "fromsymbol" } } , { "box" : { "id" : "obj-158", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 156.0, 348.0, 140.0, 22.0 ], "text" : "unpack s s" } } , { "box" : { "id" : "obj-157", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 312.0, 75.0, 239.0, 22.0 ], "text" : "connect w.artificiel.org 1883 forum maxmsp" } } , { "box" : { "id" : "obj-156", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 156.0, 293.0, 32.0, 22.0 ], "text" : "mqtt" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-156", 0 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-158", 0 ], "source" : [ "obj-156", 0 ] } } , { "patchline" : { "destination" : [ "obj-2", 0 ], "source" : [ "obj-156", 1 ] } } , { "patchline" : { "destination" : [ "obj-156", 0 ], "source" : [ "obj-157", 0 ] } } , { "patchline" : { "destination" : [ "obj-159", 0 ], "source" : [ "obj-158", 1 ] } } , { "patchline" : { "destination" : [ "obj-21", 0 ], "source" : [ "obj-158", 0 ] } } , { "patchline" : { "destination" : [ "obj-160", 1 ], "source" : [ "obj-159", 0 ] } } , { "patchline" : { "destination" : [ "obj-161", 0 ], "source" : [ "obj-160", 0 ] } } , { "patchline" : { "destination" : [ "obj-163", 0 ], "source" : [ "obj-162", 0 ] } } , { "patchline" : { "destination" : [ "obj-164", 0 ], "source" : [ "obj-163", 1 ] } } , { "patchline" : { "destination" : [ "obj-3", 0 ], "source" : [ "obj-163", 0 ] } } , { "patchline" : { "destination" : [ "obj-165", 1 ], "source" : [ "obj-164", 0 ] } } , { "patchline" : { "destination" : [ "obj-166", 0 ], "source" : [ "obj-165", 0 ] } } , { "patchline" : { "destination" : [ "obj-156", 0 ], "source" : [ "obj-166", 0 ] } } , { "patchline" : { "destination" : [ "obj-160", 0 ], "source" : [ "obj-21", 1 ] } } , { "patchline" : { "destination" : [ "obj-27", 0 ], "midpoints" : [ 116.5, 63.5, 53.5, 63.5 ], "order" : 1, "source" : [ "obj-22", 0 ] } } , { "patchline" : { "destination" : [ "obj-4", 0 ], "order" : 0, "source" : [ "obj-22", 0 ] } } , { "patchline" : { "destination" : [ "obj-24", 0 ], "order" : 0, "source" : [ "obj-23", 0 ] } } , { "patchline" : { "destination" : [ "obj-29", 0 ], "order" : 1, "source" : [ "obj-23", 0 ] } } , { "patchline" : { "destination" : [ "obj-31", 0 ], "source" : [ "obj-25", 0 ] } } , { "patchline" : { "destination" : [ "obj-25", 0 ], "source" : [ "obj-27", 0 ] } } , { "patchline" : { "destination" : [ "obj-25", 1 ], "source" : [ "obj-29", 0 ] } } , { "patchline" : { "destination" : [ "obj-165", 0 ], "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-8", 0 ], "source" : [ "obj-4", 0 ] } } , { "patchline" : { "destination" : [ "obj-23", 0 ], "source" : [ "obj-5", 0 ] } } ] } , "patching_rect" : [ 600.0, 596.0, 232.0, 22.0 ], "saved_object_attributes" : { "description" : "", "digest" : "", "globalpatchername" : "", "tags" : "" } , "text" : "p MQTT-OSC bidirectional bridge" } } , { "box" : { "id" : "obj-155", "linecount" : 7, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 615.0, 3.0, 169.0, 104.0 ], "text" : "unlike unix paths, MQTT does not specify a toplevel slash (/). But you can put one in; it adds an unneeded level but that's OK." } } , { "box" : { "id" : "obj-154", "linecount" : 2, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 564.0, 164.0, 196.0, 34.0 ], "text" : "+ is single level wildcard\n# is unlimited wildcard" } } , { "box" : { "id" : "obj-153", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 522.0, 122.0, 131.0, 20.0 ], "text" : "subscribe " } } , { "box" : { "id" : "obj-152", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 231.0, 133.0, 342.0, 20.0 ], "text" : "connect " } } , { "box" : { "id" : "obj-151", "linecount" : 3, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 797.0, 170.0, 342.0, 48.0 ], "text" : "publish \npublish \npublish " } } , { "box" : { "id" : "obj-150", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 231.0, 149.0, 342.0, 20.0 ], "text" : "connect " } } , { "box" : { "id" : "obj-148", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 459.0, 444.0, 160.0, 20.0 ], "text" : "(100 Hz stream)" } } , { "box" : { "id" : "obj-147", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 269.0, 760.0, 150.0, 20.0 ], "text" : "clock jitter" } } , { "box" : { "id" : "obj-141", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 421.0, 809.0, 74.0, 20.0 ], "text" : "- on time" } } , { "box" : { "id" : "obj-142", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 421.0, 779.0, 95.0, 20.0 ], "text" : "- 1ms early" } } , { "box" : { "id" : "obj-143", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 421.0, 840.0, 88.0, 20.0 ], "text" : "- 1ms late" } } , { "box" : { "id" : "obj-140", "maxclass" : "multislider", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "" ], "parameter_enable" : 0, "patching_rect" : [ 216.0, 786.0, 203.0, 62.0 ], "setstyle" : 3 } } , { "box" : { "id" : "obj-139", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 252.0, 852.0, 131.0, 20.0 ], "text" : "1 sec running avg" } } , { "box" : { "id" : "obj-132", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "float" ], "patching_rect" : [ 216.0, 759.0, 52.0, 22.0 ], "text" : "/ 100." } } , { "box" : { "id" : "obj-131", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 216.0, 733.0, 52.0, 22.0 ], "text" : "zl.sum" } } , { "box" : { "id" : "obj-129", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 216.0, 703.0, 102.0, 22.0 ], "text" : "zl.stream 100" } } , { "box" : { "id" : "obj-121", "linecount" : 6, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 40.0, 345.0, 161.0, 90.0 ], "text" : "The object maintains a thread to receive network events which triggers a callback that emits the message to the outlet" } } , { "box" : { "id" : "obj-120", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 697.0, 495.0, 500.0, 20.0 ], "text" : "MQTT QOS -- level 0 is probably what you want but see http://" } } , { "box" : { "id" : "obj-119", "linecount" : 3, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 757.0, 108.0, 410.0, 48.0 ], "text" : "Clean Session (a clean session's subscriptions are purged upon disconnect, otherwisee they are remembered by the broker on a client ID basis (see below)" } } , { "box" : { "id" : "obj-118", "linecount" : 5, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 697.0, 412.0, 500.0, 76.0 ], "text" : "MQTT Persistence flag (thenlast value is maintained by the broker, and emitted on future subscriptions). for instance, a work/state topic can contain a persistent state, and upon connection, a given worker can put itself in a given state. It is very cool as it turns the broker into a stateful model of your data." } } , { "box" : { "id" : "obj-117", "linecount" : 6, "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 797.0, 287.0, 319.0, 90.0 ], "text" : "this will silently fail as the forum user is not authorized to access topics outside of the namespace used in this example. you may use your own broker, or contact sysadmin@artificiel.org if you want to use our broker for other things." } } , { "box" : { "format" : 6, "id" : "obj-114", "maxclass" : "flonum", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 797.0, 225.0, 50.0, 22.0 ] } } , { "box" : { "id" : "obj-112", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 797.0, 255.0, 196.0, 22.0 ], "text" : "publish forum/mything $1" } } , { "box" : { "id" : "obj-110", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 267.0, 440.0, 93.0, 22.0 ], "text" : "\"30.000000\"" } } , { "box" : { "id" : "obj-107", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 366.0, 610.0, 211.0, 20.0 ], "text" : "time diff (should be stable)" } } , { "box" : { "id" : "obj-106", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 366.0, 555.0, 81.0, 20.0 ], "text" : "max uptime" } } , { "box" : { "id" : "obj-102", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 216.0, 555.0, 146.0, 22.0 ] } } , { "box" : { "id" : "obj-101", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "bang", "" ], "patching_rect" : [ 216.0, 440.0, 45.0, 22.0 ], "text" : "t b s" } } , { "box" : { "id" : "obj-100", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 394.0, 497.0, 160.0, 20.0 ], "text" : "system time on broker" } } , { "box" : { "id" : "obj-92", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "int", "int" ], "patching_rect" : [ 216.0, 640.0, 45.0, 22.0 ], "text" : "t i i" } } , { "box" : { "id" : "obj-79", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "int" ], "patching_rect" : [ 216.0, 675.0, 37.0, 22.0 ], "text" : "!- 0" } } , { "box" : { "id" : "obj-78", "maxclass" : "newobj", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "int" ], "patching_rect" : [ 216.0, 584.0, 37.0, 22.0 ], "text" : "!- 0" } } , { "box" : { "id" : "obj-75", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 216.0, 610.0, 146.0, 22.0 ] } } , { "box" : { "id" : "obj-73", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "float" ], "patching_rect" : [ 216.0, 527.0, 66.0, 22.0 ], "text" : "cpuclock" } } , { "box" : { "id" : "obj-72", "maxclass" : "number", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "bang" ], "parameter_enable" : 0, "patching_rect" : [ 242.0, 497.0, 146.0, 22.0 ] } } , { "box" : { "id" : "obj-70", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 242.0, 470.0, 81.0, 22.0 ], "text" : "fromsymbol" } } , { "box" : { "bubble" : 1, "fontname" : "Arial", "fontsize" : 13.0, "id" : "obj-34", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 640.0, 215.0, 116.0, 25.0 ], "text" : "MQTT Client ID" } } , { "box" : { "bubble" : 1, "fontname" : "Arial", "fontsize" : 13.0, "id" : "obj-32", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 394.0, 307.0, 255.0, 25.0 ], "text" : "print non-error messages to the console" } } , { "box" : { "id" : "obj-45", "maxclass" : "newobj", "numinlets" : 3, "numoutlets" : 3, "outlettype" : [ "", "", "" ], "patching_rect" : [ 216.0, 416.0, 269.0, 22.0 ], "text" : "route forum/time@100Hz forum/mything" } } , { "box" : { "id" : "obj-3", "maxclass" : "message", "numinlets" : 2, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 17.5, 196.0, 196.0, 22.0 ], "text" : "subscribe forum/#" } } , { "box" : { "id" : "obj-1", "maxclass" : "newobj", "numinlets" : 1, "numoutlets" : 2, "outlettype" : [ "", "" ], "patching_rect" : [ 216.0, 379.0, 521.0, 22.0 ], "text" : "mqtt @host w.artificiel.org @user forum @password maxmsp @autoconnect 1" } } , { "box" : { "attr" : "host", "id" : "obj-11", "maxclass" : "attrui", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 265.0, 238.0, 255.0, 22.0 ] } } , { "box" : { "attr" : "verbose", "id" : "obj-15", "maxclass" : "attrui", "numinlets" : 1, "numoutlets" : 1, "outlettype" : [ "" ], "patching_rect" : [ 265.0, 307.0, 123.0, 22.0 ] } } , { "box" : { "id" : "obj-31", "maxclass" : "comment", "numinlets" : 1, "numoutlets" : 0, "patching_rect" : [ 231.0, 100.0, 342.0, 20.0 ], "text" : "connect" } } ], "lines" : [ { "patchline" : { "destination" : [ "obj-4", 0 ], "source" : [ "obj-1", 1 ] } } , { "patchline" : { "destination" : [ "obj-45", 0 ], "source" : [ "obj-1", 0 ] } } , { "patchline" : { "destination" : [ "obj-13", 0 ], "source" : [ "obj-10", 0 ] } } , { "patchline" : { "destination" : [ "obj-70", 0 ], "source" : [ "obj-101", 1 ] } } , { "patchline" : { "destination" : [ "obj-73", 0 ], "source" : [ "obj-101", 0 ] } } , { "patchline" : { "destination" : [ "obj-78", 0 ], "source" : [ "obj-102", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-11", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-112", 0 ] } } , { "patchline" : { "destination" : [ "obj-112", 0 ], "source" : [ "obj-114", 0 ] } } , { "patchline" : { "destination" : [ "obj-17", 0 ], "source" : [ "obj-12", 0 ] } } , { "patchline" : { "destination" : [ "obj-19", 0 ], "source" : [ "obj-12", 1 ] } } , { "patchline" : { "destination" : [ "obj-21", 0 ], "source" : [ "obj-12", 2 ] } } , { "patchline" : { "destination" : [ "obj-131", 0 ], "source" : [ "obj-129", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 0 ], "source" : [ "obj-13", 0 ] } } , { "patchline" : { "destination" : [ "obj-132", 0 ], "source" : [ "obj-131", 0 ] } } , { "patchline" : { "destination" : [ "obj-140", 0 ], "source" : [ "obj-132", 0 ] } } , { "patchline" : { "destination" : [ "obj-12", 0 ], "source" : [ "obj-14", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-15", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-16", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-18", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-2", 0 ] } } , { "patchline" : { "destination" : [ "obj-10", 0 ], "source" : [ "obj-23", 0 ] } } , { "patchline" : { "destination" : [ "obj-10", 1 ], "source" : [ "obj-25", 0 ] } } , { "patchline" : { "destination" : [ "obj-10", 2 ], "source" : [ "obj-27", 0 ] } } , { "patchline" : { "destination" : [ "obj-7", 0 ], "source" : [ "obj-29", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-3", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-33", 0 ] } } , { "patchline" : { "destination" : [ "obj-101", 0 ], "source" : [ "obj-45", 0 ] } } , { "patchline" : { "destination" : [ "obj-110", 1 ], "source" : [ "obj-45", 1 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-5", 0 ] } } , { "patchline" : { "destination" : [ "obj-14", 0 ], "source" : [ "obj-7", 0 ] } } , { "patchline" : { "destination" : [ "obj-72", 0 ], "source" : [ "obj-70", 0 ] } } , { "patchline" : { "destination" : [ "obj-78", 1 ], "source" : [ "obj-72", 0 ] } } , { "patchline" : { "destination" : [ "obj-102", 0 ], "source" : [ "obj-73", 0 ] } } , { "patchline" : { "destination" : [ "obj-92", 0 ], "source" : [ "obj-75", 0 ] } } , { "patchline" : { "destination" : [ "obj-75", 0 ], "source" : [ "obj-78", 0 ] } } , { "patchline" : { "destination" : [ "obj-129", 0 ], "source" : [ "obj-79", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-8", 0 ] } } , { "patchline" : { "destination" : [ "obj-1", 0 ], "source" : [ "obj-9", 0 ] } } , { "patchline" : { "destination" : [ "obj-79", 0 ], "source" : [ "obj-92", 1 ] } } , { "patchline" : { "destination" : [ "obj-79", 1 ], "source" : [ "obj-92", 0 ] } } ], "dependency_cache" : [ { "name" : "mqtt.mxo", "type" : "iLaX" } ], "autosave" : 0 } }