a87dbe200e34110d4a0ed3672fdad590abef99c3
Reconstruct the app's Dart-layer behaviour (blutter over libapp.so, jadx over base.apk — see docs/RE_DART_FINDINGS.md) as working Python, replacing the library stubs with a real local-connect stack. protocol/ (new package, hardware-independent): - commands: CommunicationMode / CommunicationOperate / CommunicationCmd enums with the raw values recovered from the Dart object pool - envelope: CommunicationObject with the app's exact JSON key order - crypto: SN-derived secret key and the position-dependent additive cipher (encrypt/decrypt; radix 16 default, 32 documented alternate) - crc: CRC-16/MODBUS with the app's hi/lo swap + 4-hex string form, CRC32 envelope check, little-endian int16 helpers - framing: BLE frame build/parse (0x5AA5 data / 0x4AA4 ACK magics, CRC slots, MTU chunking) and local-socket int16LE length framing plus a streaming SocketFrameDecoder wifi.py (rewritten): - derive_hotspot_credentials(): the AP_<sn> SSID/password rules (20-char SN branch, full-SN fallback with the app's warning log) - WifiBackend abstraction: NmcliWifiBackend for Linux hosts via nmcli, NoOpWifiBackend for radio-less containers - WifiManager keeps the original stub method names for API compat and adds join_device_hotspot(sn) / leave_device_hotspot() / local_ip() device_local.py (new): LocalDeviceClient for the mode==local path — the /terminal/* HTTP endpoint family (hotspot info, aGate info, overall info, MQTT relay, ...) and direct-connect socket RPC (envelope -> cipher -> length frame -> decrypt -> JSON) with convenience query_* RPCs. docs/RE_DART_FINDINGS.md (new): the full findings — transport selector, wire envelope, crypto, CRCs, MQTT (AWS IoT + Cognito), socket, BLE + ESP provisioning, hotspot credential derivation, local/cloud HTTP layers, and the Java glue — plus the open items; README now links to it. Unconfirmed candidates (local port 18000, cipher key radix, BLE field order, X-Device-* header values) are flagged in the docs and kept configurable in code.
FranklinWH AGATE Client
Python client library for interacting with FranklinWH AGATE energy storage device.
Repository
Gitea: http://192.168.1.74:30008/WesternTechnologies/franklinwh-agate-client
Documentation
- Dart AOT Reverse-Engineering Findings — detailed protocol
analysis recovered from the app's
libapp.sowith blutter (transports, wire envelope, command/topic enums, crypto/CRC, BLE framing, hotspot credentials).
Reverse Engineering Summary
This library was reverse engineered from the official FranklinWH Family Energy Android app (com.Franklinwh.FamilyEnergy).
Network I/O Stack
The device communicates via:
- Bluetooth LE: Direct connection to AGATE device
- Onboard Wi-Fi: Local network connection via device hotspot
- Cloud APIs:
https://e-api.franklinwh.com,https://energy.franklinwh.com
Key Operations Discovered
queryAgateInfo- Get device informationqueryDeviceInfoHttp- HTTP device info queryqueryModesByHttp- Query operating modesqueryConnectWifi- Wi-Fi connection managementconnectViaBluetooth- Bluetooth connectionstartBluetoothHeartbeat- KeepaliveBluetoothManager- Bluetooth service managementWifiOnboarding- Wi-Fi setup flows
Endpoints Found
https://e-api.franklinwh.com/api/appapihttps://energy.franklinwh.com/api-energy/deviceGroup/electrichttps://energy.franklinwh.com/hes-gatewayhttps://dev.franklinwh.com/hes-gatewayhttps://uat.franklinwh.com/api-vpp-portal
Usage
from franklinwh_agate_client import AgateClient
client = AgateClient()
device_info = client.query_agate_info(device_id)
Development
This library is a work in progress. Additional operations will be added as reverse engineering continues.
License
Internal use only. Reverse engineering findings for research purposes.
Description
Python client library for FranklinWH AGATE device network I/O (Bluetooth & Wi-Fi) - reverse engineered
466 KiB
0 Stars
2 Watchers
0 Forks
Languages
Python
91.8%
Shell
8.2%