Skip to content

Python library to build and parse UDP messages for Juicebox EV chargers

License

Notifications You must be signed in to change notification settings

philipkocanda/juicebox-protocol

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Juicebox Protocol

Basic library for building and parsing Juicebox UDP messages. Shoutout to @FalconFour and @jesserockz who were instrumental in getting this to work and whose code I've reused in this library. See this issue for more.

Used to implement local control for Juicepassproxy in this pull request.

Features

  • Build command (CMD) messages

TODO

  • Figure out what the "command" field does (naming is mine, not sure if it's actually a command)
  • Figure out what the counter is for.
  • Integrate into Juicepassproxy (JPP) to get it to actually send a message to the Juicebox (HA > MQTT > JPP > Juicebox)
  • Support parsing status messages
  • Nice to have for consistency: Support parsing command messages

Tested devices

  • Juicebox 32A 3-phase 2018 (v7)

Usage

Building a message:

from juicebox.message import Message

m = Message()
m.offline_amperage = 20
m.instant_amperage = 16
m.command = 6 # TODO: figure out what this does
m.counter = 1

print(m.build())
# CMD52324A20M16C006S001!5RE$

print(m.inspect())
# {'offline_amperage': 20, 'instant_amperage': 16, 'payload_str': 'CMD52324A20M16C006S001', 'checksum_str': '5RE', 'checksum_computed': '5RE'}

Parsing a message:

from juicebox.message import Message

m = Message().from_string('CMD41325A0040M040C006S638!5N5$')
print(m.inspect())
# {'offline_amperage': 0, 'instant_amperage': 0, 'payload_str': 'CMD41325A0040M040C006S638', 'checksum_str': '5N5', 'checksum_computed': '5N5'}

NOTE: Only the payload as a whole is parsed, the contents are not. This exists mostly for testing purposes.

Unit Tests

Run all unit tests:

bin/test

Command Message Format

Command messages sent to the Juicebox by the server on regular intervals:

CMD62210A20M18C006S006!31Y$
^^^^^^^^^^^^^^^^^^^^^^ ^^^
          |             |
       payload       checksum

CMD    # Prefix
6      # Day of week (6 = Saturday, 0 = Sunday).
2210   # Local time (22:10)
A20    # Offline Amperage
M18    # Instant Amperage
C006   # Command?
S006   # Message counter?
!      # Delimiter between payload and checksum
31Y    # Checksum (base35) calculated from payload
$      # Postfix

Day of week and local time

Sets the internal clock based on the local time zone for offline time of use.

Source: FalconFour

Offline Amperage (aka Wire Rating)

Stored in the microcontroller's EEPROM as "wire rating", and it takes effect immediately on startup.

Source: FalconFour

Instant Amperage

When online, tells the box how many amps to allow. Anything below 6A disallows/disables charging, causing the Charge LED to flash when plugged in.

The "instant amperage" command is fleeting, it only matters while the box is online/receiving regular CMD reports from each of its runtime report packets.

Precedence of amperage limit is: Unit rating > Offline amperage > Runtime amperage. So if unit rating is 32, sending offline amperage 40 / runtime 40, the unit rating (baked into firmware code, non-modifiable) takes precedence and you get 32 amps. If unit rating=40, offline=32, runtime=16, you get 16 amps. Similarly, unit=40, offline=16, runtime=32, you ought to get 16 amps, but server architecture always prevented that from being sent, so the behavior may be undefined (if it's online, it should go 32, but if it goes offline / hasn't received a command in about 5 minutes, you may get 16).

Source: FalconFour

Command (?)

Alternates between C242, C244, C008, C006. Purpose unclear.

Message counter (?)

Increments by one for every message until 999 then it loops back to 001. Purpose unclear.

TBD

There is also a bit mask in there that determines "whether the user is looking at the app now", which increases the report interval from 10 seconds when charging (I believe) and 30 seconds when idle, to 3 seconds for both modes.

if I'm recalling/reading correctly, the first part of the command (several numeric digits) is setting the clock, and the final one is sending time-of-use hours with a bit mask (weekday start, weekday end, weekend start, weekend end) - this is all inherited from wayyyy old protocol back in 2014 or so when this silly protocol was first devised.

Source: FalconFour

About

Python library to build and parse UDP messages for Juicebox EV chargers

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published