From 729b0a88f543945286d8d61cc51cda21fa138ce5 Mon Sep 17 00:00:00 2001 From: Matt Zimmerman Date: Mon, 17 Feb 2025 15:19:52 -0800 Subject: [PATCH 1/6] Add support for cover sensor --- smarttub/__main__.py | 9 ++++++++- smarttub/api.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/smarttub/__main__.py b/smarttub/__main__.py index cfada5b..cb58649 100644 --- a/smarttub/__main__.py +++ b/smarttub/__main__.py @@ -14,7 +14,7 @@ async def info_command(spas, args): for spa in spas: print(f"= Spa '{spa.name}' =\n") if args.all or args.status or args.location or args.locks: - status = await spa.get_status() + status = await spa.get_status_full() if args.all or args.status: print("== Status ==") @@ -70,6 +70,12 @@ async def info_command(spas, args): pprint(await energy_usage_day) print() + if args.all or args.sensors: + print("== Sensors ==") + for sensor in status.sensors: + print(sensor) + print() + if args.all or args.debug: debug_status = await spa.get_debug_status() print("== Debug status ==") @@ -152,6 +158,7 @@ async def main(argv): info_parser.add_argument("--reminders", action="store_true") info_parser.add_argument("--locks", action="store_true") info_parser.add_argument("--debug", action="store_true") + info_parser.add_argument("--sensors", action="store_true") info_parser.add_argument("--energy", action="store_true") set_parser = subparsers.add_parser("set", help="Change settings on the spa") diff --git a/smarttub/api.py b/smarttub/api.py index 5c43c78..c9ef225 100644 --- a/smarttub/api.py +++ b/smarttub/api.py @@ -373,6 +373,9 @@ def __init__(self, spa: Spa, state: dict): self.pumps = [ SpaPump(spa, **pump_props) for pump_props in self.properties["pumps"] ] + self.sensors = [ + SpaSensor(spa, **sensor_props) for sensor_props in self.properties["sensors"] + ] class SpaWaterState(SpaState): @@ -557,6 +560,20 @@ async def unlock(self): def __str__(self): return f"" +class SpaSensor: + def __init__(self, spa: Spa, **properties): + self.spa = spa + self.address = properties["address"] + self.name = properties["name"] + self.type = properties["type"] + + self.magnet = properties["magnet"] + self.pressure = properties["pressure"] + self.motion = properties["motion"] + self.fill_drain = properties["fill_drain"] + + def __str__(self): + return f" Date: Mon, 17 Feb 2025 15:23:10 -0800 Subject: [PATCH 2/6] use fullstatus response for lights and pumps in main --- smarttub/__main__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smarttub/__main__.py b/smarttub/__main__.py index cb58649..58dc9fa 100644 --- a/smarttub/__main__.py +++ b/smarttub/__main__.py @@ -32,13 +32,13 @@ async def info_command(spas, args): if args.all or args.pumps: print("== Pumps ==") - for pump in await spa.get_pumps(): + for pump in status.pumps: print(pump) print() if args.all or args.lights: print("== Lights ==") - for light in await spa.get_lights(): + for light in status.lights: print(light) print() From 18dfc50b2d8a60cb6605f48260900b02707c11e5 Mon Sep 17 00:00:00 2001 From: Matt Zimmerman Date: Mon, 17 Feb 2025 17:02:10 -0800 Subject: [PATCH 3/6] populate subtype --- smarttub/api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smarttub/api.py b/smarttub/api.py index c9ef225..ba559c1 100644 --- a/smarttub/api.py +++ b/smarttub/api.py @@ -566,12 +566,13 @@ def __init__(self, spa: Spa, **properties): self.address = properties["address"] self.name = properties["name"] self.type = properties["type"] + self.subType = properties["subType"] self.magnet = properties["magnet"] self.pressure = properties["pressure"] self.motion = properties["motion"] self.fill_drain = properties["fill_drain"] - + def __str__(self): return f" Date: Sun, 23 Feb 2025 12:08:59 -0800 Subject: [PATCH 4/6] flake8 --- smarttub/api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/smarttub/api.py b/smarttub/api.py index ba559c1..a2fa8af 100644 --- a/smarttub/api.py +++ b/smarttub/api.py @@ -560,6 +560,7 @@ async def unlock(self): def __str__(self): return f"" + class SpaSensor: def __init__(self, spa: Spa, **properties): self.spa = spa @@ -576,6 +577,7 @@ def __init__(self, spa: Spa, **properties): def __str__(self): return f" Date: Sun, 23 Feb 2025 12:15:17 -0800 Subject: [PATCH 5/6] add tests, fallback --- smarttub/api.py | 2 +- tests/test_spa.py | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/smarttub/api.py b/smarttub/api.py index a2fa8af..9f432ad 100644 --- a/smarttub/api.py +++ b/smarttub/api.py @@ -374,7 +374,7 @@ def __init__(self, spa: Spa, state: dict): SpaPump(spa, **pump_props) for pump_props in self.properties["pumps"] ] self.sensors = [ - SpaSensor(spa, **sensor_props) for sensor_props in self.properties["sensors"] + SpaSensor(spa, **sensor_props) for sensor_props in self.properties.get("sensors", []) ] diff --git a/tests/test_spa.py b/tests/test_spa.py index d241ac6..b810ef3 100644 --- a/tests/test_spa.py +++ b/tests/test_spa.py @@ -209,6 +209,8 @@ async def test_get_status_full(mock_api, spa): "mode": "AWAY", "status": "INACTIVE", }, + "sensors": [ + ], "setTemperature": 38.3, "state": "NORMAL", "time": "14:05:00", @@ -336,6 +338,31 @@ async def test_null_blowout(mock_api, spa): "mode": "AWAY", "status": "INACTIVE", }, + "sensors": [ + { + "id": 13914100, + "spaId": "1", + "address": "C7:54:EE:BB:AA:AA", + "type": "ibs0x", + "name": "{cover-sensor-1}", + "subType": "magnet", + "voltage": 3.07, + "rssi": -56, + "age": 0, + "fill_drain": None, + "configState": "{\"drainBit\":0,\"mode\":null,\"sensorSetTime\":null}", + "motion": None, + "magnet": True, + "digital": None, + "button": False, + "triggeredCount": 18, + "missedCount": 0, + "snoozeUntil": "2025-02-17T19:19:38.879670Z", + "pressure": None, + "updatedAt": None, + "createdAt": "2025-02-17T19:19:38.879695Z" + } + ], "setTemperature": 38.3, "state": "NORMAL", "time": "14:05:00", From 695c183c7460d3b492724ab157d004602e703088 Mon Sep 17 00:00:00 2001 From: Matt Zimmerman Date: Sun, 23 Feb 2025 12:18:16 -0800 Subject: [PATCH 6/6] add tests, fallback --- tests/test_spa.py | 49 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/tests/test_spa.py b/tests/test_spa.py index b810ef3..5c2bbc8 100644 --- a/tests/test_spa.py +++ b/tests/test_spa.py @@ -209,8 +209,7 @@ async def test_get_status_full(mock_api, spa): "mode": "AWAY", "status": "INACTIVE", }, - "sensors": [ - ], + "sensors": [], "setTemperature": 38.3, "state": "NORMAL", "time": "14:05:00", @@ -339,29 +338,29 @@ async def test_null_blowout(mock_api, spa): "status": "INACTIVE", }, "sensors": [ - { - "id": 13914100, - "spaId": "1", - "address": "C7:54:EE:BB:AA:AA", - "type": "ibs0x", - "name": "{cover-sensor-1}", - "subType": "magnet", - "voltage": 3.07, - "rssi": -56, - "age": 0, - "fill_drain": None, - "configState": "{\"drainBit\":0,\"mode\":null,\"sensorSetTime\":null}", - "motion": None, - "magnet": True, - "digital": None, - "button": False, - "triggeredCount": 18, - "missedCount": 0, - "snoozeUntil": "2025-02-17T19:19:38.879670Z", - "pressure": None, - "updatedAt": None, - "createdAt": "2025-02-17T19:19:38.879695Z" - } + { + "id": 13914100, + "spaId": "1", + "address": "C7:54:EE:BB:AA:AA", + "type": "ibs0x", + "name": "{cover-sensor-1}", + "subType": "magnet", + "voltage": 3.07, + "rssi": -56, + "age": 0, + "fill_drain": None, + "configState": '{"drainBit":0,"mode":null,"sensorSetTime":null}', + "motion": None, + "magnet": True, + "digital": None, + "button": False, + "triggeredCount": 18, + "missedCount": 0, + "snoozeUntil": "2025-02-17T19:19:38.879670Z", + "pressure": None, + "updatedAt": None, + "createdAt": "2025-02-17T19:19:38.879695Z", + } ], "setTemperature": 38.3, "state": "NORMAL",