JuiceRescue / juicepassproxy

Proxy UDP requests to/from Juicebox EV chargers to MQTT discoverable by Home Assistant
Apache License 2.0
86 stars 12 forks source link

Control commands in reply to status telemetry #54

Closed FalconFour closed 5 months ago

FalconFour commented 7 months ago

In JB protocol, every telemetry message should result in a reply from the server telling the box what its status should be - containing the running current limit (amps, or 0 if it's a Time-of-Use "off" period or you otherwise want to stop charging), as well as the current day-of-week/time-of-day and a few other parameters. In a quick review of the code, I only saw it parsing and ingesting telemetry messages, but didn't see anything (I may have missed it) to trigger/formulate a response.

I think there may be some refactoring needed to fully implement both sides of the protocol - in particular, to implement scheduling. This may be as simple as an interface through which to tell juicepassproxy to "enable" or "disable" charging (and persist it for runtime), as well as an interface to control amperage - or simply make that one control command (as it truly is in the protocol - amps=0 to disable, or amps>=6 to enable). Then it can be scheduled using Home Assistant automations/schedules, for example.

Everything else, e.g. storing energy/charging history, debug messages, plug state, etc., ends up being "passively" handled by HA's existing database and interfaces, I think which puts this really close to being a reality. Would be curious to know how HA handles periodic debug messages as strings, though.

Note that commands are also allowed asynchronously - i.e. you can send a "CMD" string without having received a telemetry message to reply to - it's perfectly OK and the box will accept/respond with another telemetry string.

snicker commented 7 months ago

right now the proxy is a complete passthrough, man-in-the-middle style, but there's no reason that messages traveling in either direction couldn't be intercepted, augmented, stopped, or replied to using the current implementation, in remote_data_handler for incoming messages and local_data_handler for outgoing messages.

the missing piece is just using pyproxy to manifest messages directly to the device masquerading as the server (ala what remote_data_handler does by simply allowing the data to pass through without augmentation)

FalconFour commented 7 months ago

Aye, the local server system is made a bit weirder by the usage of UDP instead of TCP. Since it's stateless, you can simply synthesize new packets and send it in reply to the src port, which is random for each "connection" or session. Have to remember the src port to send replies or asynchronous messages.

So, illustrated, JuiceBox --[src=port 24341 (random), dst=8042]--> Server [src=port 24341, dst=8042] Server [src=8042, dst=24341] -> JuiceBox [src=8042, dst=24341]

I think, just from memory. Might need some Wireshark love on that one.

Anyway, was hoping juicepassproxy could transform into being completely independent, allowing us to choose whether or not we even want to pass data along to Enel's app ;) Especially as it gets phased out over time, inevitably. Old boxes speaking an older protocol are already left in limbo, which could be supported by a local instance, so that's a thing worth fighting for :)

ivanfmartinez commented 5 months ago

After the async rewrite wich made more "easy" to send data to the juicebox I had made first implementation in #69

Only send command to juicebox when a change is requested on the currents.

But now we can make more tests and see what is the best behaviour to be implemented.

Snuffy2 commented 5 months ago

Referenced from #77 Please post further comments there.