Local channel¶
Direct access to the box on the LAN (TCP port 400). See the local channels protocol notes for the frame format.
client
¶
LAN channel to the Daisy box (DaisyApplication#sendDM).
One TCP connection per command to <box ip>:400: write the obfuscated frame
(no newline), read one plaintext line. A line containing "ACK" means the box
accepted the command. The box's IP is only known through the cloud status item
NET_PARAM of the box device, or can be configured by the user.
This channel only sends commands: device state is never readable locally.
LocalClient
¶
LocalClient(
host: str,
*,
port: int = LOCAL_PORT,
connect_timeout: float = LOCAL_CONNECT_TIMEOUT,
)
Send commands to a Daisy box on the local network.
crypto
¶
Obfuscation used on the Daisy box LAN channel (TCP port 400).
Port of DaisyApplication#encrypt:
- pick
rin0..27and rotate the 28-char key left byr; - take the epoch seconds as a 10-digit string
tsand turn each pair of digits into one character (chr(int("12")) == "\x0c"); - plaintext =
chr(ts[0:2])+ message, withchr(ts[2:4]),chr(ts[4:6])andchr(ts[6:8])inserted before the characters at indexes 50, 70 and 90 of the original message (only if the message is long enough), +chr(ts[8:10]); - XOR every UTF-16 code unit with the rotated key, encode as UTF-8, Base64 it;
- prefix
"S"(scenario) or"M"(anything else) andALPHABET[r].
The box answers with a plaintext line; a line containing "ACK" means success.
encrypt
¶
encrypt(
message: str,
*,
scenario: bool = False,
rotation: int | None = None,
timestamp: int | None = None,
) -> str
Obfuscate message the way the app does before sending it to port 400.
rotation and timestamp are only meant for tests; by default they are
random and the current time, like the app.