"""Offline tests for battery SoC extraction (no radio/hardware needed).""" import unittest from franklinwh_agate_client.battery import extract_soc class TestExtractSoc(unittest.TestCase): def test_current_battery_soc_wins(self): reply = {"cmdType": 25, "data": {"currentBatterySoc": 78, "soc": 10}} out = extract_soc(reply) self.assertEqual(out["value"], 78) self.assertEqual(out["source"], "currentBatterySoc") def test_soc_fallback(self): out = extract_soc({"data": {"soc": "55"}}) self.assertEqual(out["value"], 55) self.assertEqual(out["source"], "soc") def test_soc_array_averaged(self): out = extract_soc({"data": {"socArray": [80, 90]}}) self.assertEqual(out["value"], 85) self.assertEqual(out["source"], "socArray(avg)") def test_nested_data_string(self): import json reply = {"data": json.dumps({"aPower": {"soc": 62}})} out = extract_soc(reply) self.assertEqual(out["value"], 62) def test_missing_soc(self): out = extract_soc({"data": {"foo": 1}}) self.assertIsNone(out["value"]) self.assertIsNone(out["source"]) if __name__ == "__main__": unittest.main() class TestBmsSoc(unittest.TestCase): def test_batsoc_key(self): from franklinwh_agate_client.battery import SOC_KEYS self.assertIn("batSoc", SOC_KEYS) def test_batsoc_extracted(self): reply = {"cmdType": 1706, "dataArea": {"opt": 0, "result": 0, "id": 1, "batSoc": 87, "batSoh": 100}} out = extract_soc(reply) self.assertEqual(out["value"], 87) self.assertEqual(out["source"], "batSoc") def test_bms_query_carries_pack_id(self): from franklinwh_agate_client.protocol import ( CommunicationCmd, direct_connect_request) env = direct_connect_request(CommunicationCmd.BMS, "SN", data={"id": 2}) self.assertEqual(env.to_dict()["dataArea"], {"opt": 0, "id": 2}) self.assertEqual(env.cmd_type, 1705)