Probes 10.100.1.1:9000,18000, sends 0x19/0x1D/0x1E envelopes, extracts currentBatterySoc/soc/avg(socArray). Includes offline extract_soc tests, BATTERY_POC docs, README usage, and empirical port-9000 RE notes.
53 lines
1.3 KiB
Python
53 lines
1.3 KiB
Python
"""
|
|
FranklinWH AGATE Device Client
|
|
|
|
Reverse engineered from com.Franklinwh.FamilyEnergy Android app.
|
|
Provides access to Bluetooth and Wi-Fi network I/O stack for AGATE devices.
|
|
"""
|
|
|
|
from .client import AgateClient
|
|
from .bluetooth import BluetoothManager
|
|
from .wifi import (
|
|
DEVICE_GATEWAY_IP,
|
|
FALLBACK_PASSWORD,
|
|
VALID_SN_LENGTH,
|
|
HotspotJoinError,
|
|
HotspotProfile,
|
|
NoOpWifiBackend,
|
|
NmcliWifiBackend,
|
|
WifiBackend,
|
|
WifiManager,
|
|
derive_hotspot_credentials,
|
|
)
|
|
from .api import ApiClient
|
|
|
|
__version__ = "0.1.0"
|
|
__all__ = [
|
|
"AgateClient",
|
|
"BluetoothManager",
|
|
"ApiClient",
|
|
"WifiManager",
|
|
"WifiBackend",
|
|
"NmcliWifiBackend",
|
|
"NoOpWifiBackend",
|
|
"HotspotProfile",
|
|
"HotspotJoinError",
|
|
"derive_hotspot_credentials",
|
|
"extract_soc",
|
|
"get_battery",
|
|
"SOCKET_PORT_CANDIDATES",
|
|
"DEVICE_GATEWAY_IP",
|
|
"FALLBACK_PASSWORD",
|
|
"VALID_SN_LENGTH",
|
|
]
|
|
|
|
|
|
def __getattr__(name: str):
|
|
# Lazy so `python -m franklinwh_agate_client.battery` does not import
|
|
# the submodule twice (avoids a runpy RuntimeWarning).
|
|
if name in {"extract_soc", "get_battery", "SOCKET_PORT_CANDIDATES"}:
|
|
from . import battery as _battery
|
|
|
|
return getattr(_battery, name)
|
|
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|