rzw
rzw copied to clipboard
The some aspects of the send/receive model are unreliable
I've been having some fun playing with this crate, but as I have added more nodes to my network, things have become unstable. There are assumptions made about the order in which messages will come out of the controller that don't really hold. For instance, functions like switch_binary_get()
on Node
sends a get command over the air, then reads whatever the next message it gets from the driver, assuming that it will be the report
back from the switch. This isn't necessarily the case, as the next message may have been sent from another node, or be from the same node, but of a different type (most commonly in my case, a METER report).
In general, I don't think it will be safe to assume anything about the order in which messages come out of the driver, let alone their origin. Without making the Controller
much more sophisticated, I'm not sure what the best way is around this. Unless there is some sort of Controller
message buffer/queue/whatever that it can pick through to find the correct message to parse and return (for instance from a binary_switch_get()
call), it probably isn't possible to reliably return anything. Let me know if I misunderstand what's happening under the hood.
I can think of a few alternatives:
- Don't return anything meaningful from
get()
-like stuff. Just return whether the message parsed and sent okay. Leave it up to the client to use ahandle_messages()
function or read messages from the controller in a loop to capture and respond to the correspondingreport
. - Add some internal message storage to the
Controller
to read/parse and store incoming messages that aren't valid responses to the last*_get()
until it gets one, then return the result. This might be limiting for some use cases...
I think the first is the easiest thing to do, but it would break existing code :(. But! going forward it would allow people to write their own fancy message grabber/dispatcher code, and not affect the overall complexity of the crate.
I should also mention that I have issues initializing a Controller
when there is a switch pinging me with METER
messages. I think this is causing the initialization code that expects an ACK to get confused. If I re-try the initialization a few times in quick succession, everything works okay. I think this is happening because my USB controller has a few METER
messages sitting in a buffer that are the first things to come out. Somewhat related to the above; the code assumes after talking to the device that the first thing out will be an ACK.
Sorry for the long issue. Let me know if you want me to take a crack at any of this.
Hi @youngmit,
I'm with you and think for now we should go with option 1 and option 2 can be added later if needed. When I wrote this crate the ZWave Specifcation have been not public available. With this have changed in the last year, a lot more things are clearified. The ACK is more or less written as in die Specification defined here: https://www.silabs.com/documents/login/user-guides/INS12350-Serial-API-Host-Appl.-Prg.-Guide.pdf
The API needs to change completly. So i will branch the reporisotry and start more or less from scratch in the master and only copy code over which can be reused easily.
Thanks for the link. I look forward to seeing what you come up with. In the meantime, I will start doing some experimentation of my own, get comfortable with z wave stuff, then hopefully I will be able to contribute
Hello from 2024.
I’m interested in making a ZWave / Rust tool to steer home appliances - and starting by looking at this code.
@akauppi Feel free to look into to code. I don't have to time to do a rewrite on my own right now. But please feel free to submit PRs and push this library forward.