Files

157 lines
4.9 KiB
Python

"""Transport selector, operation codes and command ids.
Recovered from the object pool (``pp.txt``) of ``libapp.so`` — see
``docs/RE_DART_FINDINGS.md`` §2, §4.
"""
from __future__ import annotations
from enum import IntEnum
class CommunicationMode(IntEnum):
"""Transport selector (raw values as in the Dart enum)."""
MQTT = 0
SOCKET = 1
BLUETOOTH = 2
HTTP = 3
LOCAL = 4
class CommunicationOperate(IntEnum):
"""``type`` field of the wire envelope."""
QUERY = 0
SET = 1
COMMAND = 2
MODIFY = 5
class CommunicationCmd(IntEnum):
"""``cmdType`` field of the wire envelope.
Gaps 0x09, 0x1B, 0x2C, 0x31 are not surfaced as instances in the pool.
``WIFI_FREQUECY`` keeps the app's spelling.
"""
QUERY_DEVICE_INFO = 0x00
NETWORK_INFO = 0x01
RESOURCE_ADDRESS = 0x02
SUNSPEC_MODBUS = 0x03
NETWORK_SWITCH = 0x04
FEEDING_GRID_POWER = 0x05
MODE = 0x06
MODE_V2 = 0x07
MODE_SETTING_V2 = 0x08
SOLAR_INFO = 0x0A
ENERGY_MANAGE_INFO = 0x0B
GENERATOR_INFO = 0x0C
BLUETOOTH_HEARTBEAT = 0x0D
SCAN_WIFI_LIST = 0x0E
CONNECT_WIFI = 0x0F
CONNECTION_STATUS = 0x10
NETWORK_CHANNEL_STATUS = 0x11
NETWORK_CHANNEL = 0x12
PAIR_POWER = 0x13
PROCESS_PAIR_POWER = 0x14
CHECK_BLUETOOTH_PASSWORD = 0x15
GO_OFF_GRID_STATUS = 0x16
A_POWER_LED_SWITCH = 0x17
DEVICE_DETAIL_INFO = 0x18
DEVICE_APOWER_INFO = 0x19
DEVICE_ALARMS = 0x1A
PE = 0x1C
BMS = 0x1D
EMS = 0x1E
MPPT = 0x1F
A_HUB = 0x20
CT_TEST_REVERSE = 0x21
DEVICE_DATA = 0x22
LOAD_STATUS = 0x23
LOAD_STATUS_2 = 0x24
SMART_LOAD = 0x25
SMART_LOAD_2 = 0x26
REBOOT_DEVICE = 0x27
DEBUG_MODE = 0x28
POWER_ON = 0x29
CHARGE_DEVICE = 0x2A
CLEAR_FAULT = 0x2B
DEVICE_ADDRESS_INFO = 0x2D
OVERLOAD_CUT_OFF = 0x2E
WIFI_FREQUECY = 0x2F # sic
BREAKER_COMMISSION_NOTIFY = 0x30
BREAKER_COM_STATE = 0x32
BREAKER_LOAD_STATUS = 0x33
BREAKER_IDENTIFY_ME = 0x34
#: ``cmdType`` values on the socket/Bluetooth/local transports.
#:
#: ``CommunicationCmd::cmd(cmd, mode)`` returns the *second* id field
#: (``off_14`` in the pool) for ``socket``/``bluetooth``/``local`` modes and
#: throws for ``http`` — verified live: a PCAPdroid capture of the app shows
#: ``{"cmdType":1101, ...}`` (``QUERY_DEVICE_INFO`` here, ``off_8`` ``0x00``)
#: with the S1-plaintext-first framing (see ``docs/RE_DART_FINDINGS.md``
#: §5). The ``off_8`` values above are *not* used on the wire for these
#: transports. Entries mapped to ``None`` have no pool id (``0xFFFF…``).
SOCKET_CMD_TYPE = {
CommunicationCmd.QUERY_DEVICE_INFO: 0x44D,
CommunicationCmd.NETWORK_INFO: 0x45D,
CommunicationCmd.RESOURCE_ADDRESS: 0x4B5,
CommunicationCmd.SUNSPEC_MODBUS: 0x4B5,
CommunicationCmd.NETWORK_SWITCH: 0x45F,
CommunicationCmd.FEEDING_GRID_POWER: 0x6A5,
CommunicationCmd.MODE: 0x57B,
CommunicationCmd.MODE_V2: 0x6BD,
CommunicationCmd.MODE_SETTING_V2: 0x6BF,
CommunicationCmd.SOLAR_INFO: 0x76F,
CommunicationCmd.ENERGY_MANAGE_INFO: 0x4B3,
CommunicationCmd.GENERATOR_INFO: 0x76D,
CommunicationCmd.BLUETOOTH_HEARTBEAT: 0x7D7,
CommunicationCmd.SCAN_WIFI_LIST: 0x455,
CommunicationCmd.CONNECT_WIFI: 0x457,
CommunicationCmd.CONNECTION_STATUS: 0x459,
CommunicationCmd.NETWORK_CHANNEL_STATUS: 0x46D,
CommunicationCmd.NETWORK_CHANNEL: 0x46B,
CommunicationCmd.PAIR_POWER: 0x44F,
CommunicationCmd.PROCESS_PAIR_POWER: 0x451,
CommunicationCmd.CHECK_BLUETOOTH_PASSWORD: 0x7D5,
CommunicationCmd.GO_OFF_GRID_STATUS: 0x6BB,
CommunicationCmd.A_POWER_LED_SWITCH: None,
CommunicationCmd.DEVICE_DETAIL_INFO: 0x515,
CommunicationCmd.DEVICE_APOWER_INFO: 0x51B,
CommunicationCmd.DEVICE_ALARMS: 0x725,
CommunicationCmd.PE: 0x6A7,
CommunicationCmd.BMS: 0x6A9,
CommunicationCmd.EMS: 0x6AB,
CommunicationCmd.MPPT: 0x6B5,
CommunicationCmd.A_HUB: 0x771,
CommunicationCmd.CT_TEST_REVERSE: None,
CommunicationCmd.DEVICE_DATA: None,
CommunicationCmd.LOAD_STATUS: 0x583,
CommunicationCmd.LOAD_STATUS_2: 0x587,
CommunicationCmd.SMART_LOAD: 0x581,
CommunicationCmd.SMART_LOAD_2: 0x585,
CommunicationCmd.REBOOT_DEVICE: 0x6B9,
CommunicationCmd.DEBUG_MODE: 0x71D,
CommunicationCmd.POWER_ON: 0x71F,
CommunicationCmd.CHARGE_DEVICE: 0x721,
CommunicationCmd.CLEAR_FAULT: 0x6AD,
CommunicationCmd.DEVICE_ADDRESS_INFO: 0x4B1,
CommunicationCmd.OVERLOAD_CUT_OFF: 0x6A5,
CommunicationCmd.WIFI_FREQUECY: 0x46F,
CommunicationCmd.BREAKER_COMMISSION_NOTIFY: None,
CommunicationCmd.BREAKER_COM_STATE: None,
CommunicationCmd.BREAKER_LOAD_STATUS: 0x471,
CommunicationCmd.BREAKER_IDENTIFY_ME: 0x473,
}
def socket_cmd_type(cmd: CommunicationCmd) -> int:
"""Wire ``cmdType`` for *cmd* on the socket transport (``cmd()``)."""
value = SOCKET_CMD_TYPE[cmd]
if value is None:
raise KeyError(f"{cmd} has no socket-transport command id")
return int(value)