meshtastic / python

The Python CLI and API for talking to Meshtastic devices
https://meshtastic.org
335 stars 150 forks source link

gpio-wrb ack #567

Open jna-358 opened 1 month ago

jna-358 commented 1 month ago

When sending a message to a remote node for setting one of its gpio pins, the confirmation message is shown, even when the node is offline: meshtastic --host localip --gpio-wrb 13 1 --dest '!remoteid' -> Writing GPIO mask 0x2000 with value 0x2000 to !remoteid

When adding an --ack, the command never terminates even when the node is online and the message is successfully sent: meshtastic --host localip --gpio-wrb 13 1 --dest '!remoteid' --ack -> Aborting due to: Timed out waiting for an acknowledgment

This behaviour seems strange, as its vital to have a gpio command acknowledged.

ianmcorvidae commented 1 month ago

I think that I see what's happening here with --ack, but I don't have any nodes using the remote hardware module, so I'm not sure I can test the change. If I put something together, would you be able to install a test version from git to see if it improves this behavior? If so, I can put something together later probably.

jna-358 commented 1 month ago

Sure, I can do that.

ianmcorvidae commented 1 month ago

Alright, perfect. When you get a chance, could you try out the code at https://github.com/ianmcorvidae/meshtastic-python/tree/gpio-wrb

The change I've made is to pass a response handler that should properly record the ack, so this should, hopefully, mean that passing --gpio-wrb along with --ack shouldn't time out (as long as it actually does get an acknowledgement, of course).

Thanks for helping with the testing here!

jna-358 commented 1 month ago

Thanks for the quick fix. I tested the updated code and now I am receiving NAK instead of timeout errors: Received a NAK, error reason: NO_RESPONSE If the command is not delivered (tested with the receiving node turned off) I see a timeout error.

So currently it seems to behave like this:

While I can now distinguish between timeouts and successful transmissions, this behavior still seems counterintuitive.

ianmcorvidae commented 4 weeks ago

I'm looking at this again -- it seems, perhaps frustratingly, that the firmware itself doesn't send normal acknowledgements on WRITE_GPIOS messages, so that NO_RESPONSE is actually all it knows how to send back. I think that probably this needs to be improved in the firmware so it knows to send a NONE "error" (which is a normal acknowledgement), or possibly to send a GPIOS_CHANGED remote hardware message. I think it'd be reasonable to make an issue in that repository (meshtastic/firmware), which can of course be linked back to this issue. I don't know how many (if any) firmware devs are using this module, of course, so I can't speak to when it might or might not get fixed there. I'll leave this open for the time being, since it seems like it maybe wouldn't make sense to merge my change right now.

One workaround/possible solution you might try would be to run a --gpio-watch separately, which I believe would send an update when the value changes. There could be weirdness having multiple clients connected to the same local node, however; it might work better as a dedicated script of some sort.

Based on my limited understanding of this module, I think something in this vein (given an established connection as interface, a destination node ID in destination_node_id, and appropriate values in bitmask and value):

rhc = remote_hardware.RemoteHardwareClient(interface)

rhc.watchGPIOs(destination_node_id, bitmask)
rhc.writeGPIOs(destination_node_id, bitmask, value)
while not interface.gotResponse:
    time.sleep(1)

No warranty on that code, obviously, check for yourself, etc. -- but maybe it can provide something to help in this case for the time being, at least.