134 lines
5.3 KiB
Python
134 lines
5.3 KiB
Python
"""Offline tests for the business operations (transport stubbed)."""
|
|
|
|
import unittest
|
|
|
|
from franklinwh_agate_client.device_local import LocalDeviceClient
|
|
from franklinwh_agate_client.protocol import CommunicationCmd
|
|
|
|
|
|
def _client(handler):
|
|
client = LocalDeviceClient("SN", host="127.0.0.1", timeout=0.1)
|
|
calls = []
|
|
|
|
def fake_send_rpc(cmd, equip_no=None, operate=None, data=None,
|
|
envelope=None):
|
|
calls.append((cmd, equip_no, data))
|
|
return handler(cmd, equip_no, data)
|
|
|
|
client.send_rpc = fake_send_rpc
|
|
return client, calls
|
|
|
|
|
|
class TestBatterySocOp(unittest.TestCase):
|
|
def test_apower_win(self):
|
|
client, calls = _client(
|
|
lambda cmd, eq, data: {"dataArea": {"currentBatterySoc": 78}})
|
|
out = client.get_battery_soc()
|
|
self.assertEqual(out["value"], 78)
|
|
self.assertEqual(out["source"], "currentBatterySoc")
|
|
|
|
def test_bms_pack_fallback(self):
|
|
def handler(cmd, eq, data):
|
|
if cmd == CommunicationCmd.DEVICE_APOWER_INFO:
|
|
return {"dataArea": {"result": 1, "reason": -1}}
|
|
if (data or {}).get("id") == 1:
|
|
return {"dataArea": {"opt": 0, "result": 0, "id": 1,
|
|
"batSoc": 64, "batSoh": 99,
|
|
"batTotalVolt": 512}}
|
|
return {"dataArea": {"opt": 0, "result": 0, "id": 0,
|
|
"batSoc": 0, "batSoh": 0,
|
|
"batTotalVolt": 0}}
|
|
|
|
client, calls = _client(handler)
|
|
out = client.get_battery_soc()
|
|
self.assertEqual(out["value"], 64)
|
|
self.assertEqual(out["source"], "batSoc")
|
|
# discovery + apower + bms id=1 (empty id=0 never needed)
|
|
ids = [d.get("id") if isinstance(d, dict) else None
|
|
for _, _, d in calls]
|
|
self.assertIn(1, ids)
|
|
|
|
def test_empty_slots_skipped(self):
|
|
client, _ = _client(
|
|
lambda cmd, eq, data: {"dataArea": {"opt": 0, "result": 0,
|
|
"id": 0, "batSoc": 0,
|
|
"batSoh": 0,
|
|
"batTotalVolt": 0}})
|
|
out = client.get_battery_soc()
|
|
self.assertIsNone(out["value"])
|
|
|
|
def test_transport_error_propagates(self):
|
|
client, _ = _client(None)
|
|
|
|
def boom(cmd, equip_no=None, operate=None, data=None,
|
|
envelope=None):
|
|
raise ConnectionError("down")
|
|
|
|
client.send_rpc = boom
|
|
with self.assertRaises(ConnectionError):
|
|
client.get_battery_soc()
|
|
|
|
|
|
class TestWattageOp(unittest.TestCase):
|
|
def test_detail_win(self):
|
|
client, _ = _client(
|
|
lambda cmd, eq, data: {"dataArea": {"apowerCount": 2,
|
|
"totalPower": 1872.5}})
|
|
out = client.get_household_wattage()
|
|
self.assertEqual(out["value"], 1872.5)
|
|
self.assertEqual(out["source"], "totalPower")
|
|
|
|
def test_ems_math_fallback(self):
|
|
def handler(cmd, eq, data):
|
|
if cmd == CommunicationCmd.EMS:
|
|
return {"dataArea": {"gridVol1": 120.0, "gridVol2": 120.0,
|
|
"loadCurr1": 5.0, "loadCurr2": 5.0}}
|
|
return {"dataArea": {"result": 1, "reason": -1}}
|
|
|
|
client, _ = _client(handler)
|
|
out = client.get_household_wattage()
|
|
self.assertAlmostEqual(out["value"], 1200.0)
|
|
self.assertEqual(out["source"], "ems(loadCurr*V)")
|
|
|
|
def test_inventory(self):
|
|
client, _ = _client(
|
|
lambda cmd, eq, data: {
|
|
"cmdType": 1102, "equipNo": "IBG",
|
|
"dataArea": {"opt": 0, "result": 0, "FHP_SN": ["A", "B"],
|
|
"BMS_SN": ["C"], "protocolVer": "V1"}})
|
|
out = client.get_device_inventory()
|
|
self.assertEqual(out["ibg_sn"], "IBG")
|
|
self.assertEqual(out["fhp_sn"], ["A", "B"])
|
|
self.assertEqual(out["protocol_ver"], "V1")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|
|
|
|
|
|
class TestWifiOps(unittest.TestCase):
|
|
def test_join_home_wifi_shape(self):
|
|
from franklinwh_agate_client.protocol import direct_connect_request
|
|
from franklinwh_agate_client.protocol import CommunicationCmd
|
|
from franklinwh_agate_client.protocol import CommunicationOperate
|
|
env = direct_connect_request(
|
|
CommunicationCmd.CONNECT_WIFI, "SN",
|
|
data={"ssid": "Home", "password": "pw",
|
|
"wifi_SSID": "Home", "wifi_Pw": "pw"},
|
|
operate=CommunicationOperate.SET)
|
|
d = env.to_dict()
|
|
self.assertEqual(d["cmdType"], 1111) # socket id of connectWifi
|
|
self.assertEqual(d["type"], 1) # SET
|
|
self.assertEqual(d["dataArea"]["opt"], 1)
|
|
self.assertEqual(d["dataArea"]["ssid"], "Home")
|
|
|
|
def test_scan_and_status_shape(self):
|
|
from franklinwh_agate_client.protocol import direct_connect_request
|
|
from franklinwh_agate_client.protocol import CommunicationCmd
|
|
scan = direct_connect_request(CommunicationCmd.SCAN_WIFI_LIST, "SN")
|
|
self.assertEqual(scan.cmd_type, 1109)
|
|
self.assertEqual(scan.to_dict()["dataArea"], {"opt": 0})
|
|
status = direct_connect_request(
|
|
CommunicationCmd.CONNECTION_STATUS, "SN")
|
|
self.assertEqual(status.cmd_type, 1113)
|