I’m currently working on a binding for Yamaha MusicCast (multi room music player). Until now every model/device is created as a Thing. To be able to detect the other models/devices in the network, I use the REST API. That works fine and basic functionality is almost finished.
For statusupdates there is a polling job. But now the request came to implement an UDP Listener to capture the events and update the Thing. After an API call, the updates are sent via UDP every 10 minutes. Tested and confirmed via curl and netcat.
As the binding (or OH instance) will making the API calls, all UDP events will be sent to the OH instance. The received JSON contains the info and the ID of the model/device. Data needs to be dispatched to the correct model/device and thus correct Thing. When multiple models/devices are present, which model/device will capture what update?
Is the following setup a correct/good one? Create a Bridge which will be responsible for the UDP Listener. JSON will be decoded and updates sent to the linked Things. No further configuration of the Bridge is needed. Things acts as they do now (except for the polling job). Bridge can also be used get the other things instead of the REST API.
Is there a tutorial available how to setup/implement a Bridge? I could not find any. I studied other bindings but it is not yet completely clear to me.
Is the UDP Listener implementation of the Doorbird binding a good start? I understand what is happening and is comparable to other tutorials online.
Thank you for reading my extended question(s). Hopefully I have made my questions clear enough.
If there is no „physical“ bridge, you can also implement a OSGi-service that receives and distributes the UDP packets. This service is then injected in the handler factory and passed to the thing handlers. The thing handlers register themselves with the UdpCommunicationService (example name) during initialization and unregister on disposal. This is similar to the SnmpService in the SNMP binding.
Since the user has nothing to configure, this would probably be preferred to creating a virtual bridge.
It really depends how complicated your conversation is - simplest UDP stuff I managed to get running is there:
It allows to “push” a request from discovery service as well as propagate answer back. If you take a closer look actual “infrastructure” part is really opening DatagramSocket. Rest is really sending and receiving bytes.
Do you know from the packet content which packet belongs to which thing? If so (e.g. identifier in packet ), the thing could register itself with the service and the service stores that registration in a Map<identifier, thing handler>, if a packet is received, the service extracts the identifier, gets the handler and calls a method handler.process(data) or discards the packet if no handler could be found.
If you don‘t know before, you could just register all handlers with the service, store these in a Set and call set.foreach(h -> h.process(data)) and leave it to the handler to figure out if it can use the data or not.
There is device id available in the JSON and via API from the thing/model itself.
I copied parts of the code of the SNMP binding into my binding to see what it gives and to better understand what is happening. I get one error in the end: The blank final field udpService may not have been initialized
If I leave out the final keyword, everything compiles but the binding crashes
To good to be true.
I don’t see the difference with the SNMP binding but I will keep on playing around.
My goal is to have the service initialised with just some entries in the log. If that works, I can continue with the UDP events.
@J-N-K: Created a branch and started from scratch.
During retyping (copy/paste) I think I’ve found my error, Jar is compiled and Service is showing up in the logs.
So already many thanks for the first hint. Now I must figure out the DatagramPacket stuff
EDIT: UDP packages are received but now the handler is missing: UNINITIALIZED - HANDLER_MISSING_ERROR
I know what to do this weekend