From e6eaa3ed3ee5d5e49369f8d0bb63f0e1a4d316a5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 27 Feb 2020 00:17:15 -1000 Subject: [PATCH] Additional battery percentage estimations * Battery percentage for the mars2 lock * Battery percentage for the keypad These mirror the name to percentage mappings currently used in home assistant --- august/doorbell.py | 17 ++- august/keypad.py | 21 +++- setup.py | 2 +- tests/fixtures/get_doorbell.battery_full.json | 105 ++++++++++++++++++ tests/fixtures/get_doorbell.battery_low.json | 105 ++++++++++++++++++ .../fixtures/get_doorbell.battery_medium.json | 105 ++++++++++++++++++ tests/test_api.py | 49 +++++++- 7 files changed, 398 insertions(+), 6 deletions(-) create mode 100644 tests/fixtures/get_doorbell.battery_full.json create mode 100644 tests/fixtures/get_doorbell.battery_low.json create mode 100644 tests/fixtures/get_doorbell.battery_medium.json diff --git a/august/doorbell.py b/august/doorbell.py index ac4c022..b03f3c8 100644 --- a/august/doorbell.py +++ b/august/doorbell.py @@ -72,7 +72,21 @@ def __init__(self, data): self._battery_level = None if "telemetry" in data: - self._battery_level = data["telemetry"].get("battery_soc", None) + telemetry = data["telemetry"] + if "battery_soc" in telemetry: + self._battery_level = telemetry.get("battery_soc", None) + elif telemetry.get("doorbell_low_battery"): + self._battery_level = 10 + elif "battery" in telemetry: + battery = telemetry["battery"] + if battery >= 4: + self._battery_level = 100 + elif battery >= 3.75: + self._battery_level = 75 + elif battery >= 3.50: + self._battery_level = 50 + else: + self._battery_level = 25 @property def status(self): @@ -112,6 +126,7 @@ def image_url(self, var): @property def battery_level(self): + """Return an approximation of the battery percentage.""" return self._battery_level @property diff --git a/august/keypad.py b/august/keypad.py index fe4a5e4..939a5ba 100644 --- a/august/keypad.py +++ b/august/keypad.py @@ -1,5 +1,9 @@ from august.device import DeviceDetail +BATTERY_LEVEL_FULL = "Full" +BATTERY_LEVEL_MEDIUM = "Medium" +BATTERY_LEVEL_LOW = "Low" + class KeypadDetail(DeviceDetail): def __init__(self, house_id, keypad_name, data): @@ -8,7 +12,7 @@ def __init__(self, house_id, keypad_name, data): keypad_name, house_id, data["serialNumber"], - data["currentFirmwareVersion"] + data["currentFirmwareVersion"], ) self._battery_level = data["batteryLevel"] @@ -20,3 +24,18 @@ def model(self): @property def battery_level(self): return self._battery_level + + @property + def battery_percentage(self): + """Return an approximation of the battery percentage.""" + if not self._battery_level: + return None + + if self._battery_level == BATTERY_LEVEL_FULL: + return 100 + if self._battery_level == BATTERY_LEVEL_MEDIUM: + return 60 + if self._battery_level == BATTERY_LEVEL_LOW: + return 10 + + return 0 diff --git a/setup.py b/setup.py index fb7e456..fcf0d31 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='py-august', - version='0.21.0', + version='0.22.0', packages=['august'], url='https://github.com/snjoetw/py-august', license='MIT', diff --git a/tests/fixtures/get_doorbell.battery_full.json b/tests/fixtures/get_doorbell.battery_full.json new file mode 100644 index 0000000..eec01a9 --- /dev/null +++ b/tests/fixtures/get_doorbell.battery_full.json @@ -0,0 +1,105 @@ +{ + "doorbellID": "did", + "serialNumber": "sr", + "appID": "august-iphone-v5", + "installUserID": "iid", + "name": "Front Door", + "installDate": "2019-02-25T05:32:11.263Z", + "pubsubChannel": "pubsub", + "settings": { + "ABREnabled": true, + "auto_contrast_mode": 0, + "backlight_comp": false, + "batteryChargeCurrent": 60, + "batteryLowThreshold": 3.1, + "batteryUseThreshold": 3.4, + "batteryRun": false, + "bellTimerConfig": 50, + "bitrateCeiling": 512000, + "brightness": 50, + "contrast": 50, + "directLink": true, + "debug": false, + "flashBrightness": 40, + "flashDuringCall": true, + "flashOnPIR": true, + "haloBrightnessX": 25, + "hue": 50, + "initialBitrate": 384000, + "IREnabled": true, + "irConfiguration": 16836880, + "irSensitivity": 70, + "IVAEnabled": false, + "JPGQuality": 70, + "keepEncoderRunning": true, + "maintainIVConnection": true, + "micVolume": 100, + "minACNoScaling": 40, + "minimumSnapshotInterval": 30, + "overlayEnabled": true, + "ringSoundEnabled": true, + "saturation": 50, + "sharpness": 50, + "speakerVolume": 92, + "turnOffCamera": false, + "buttonpush_notifications": true, + "motion_notifications": true, + "notify_when_offline": false, + "buttonpush_notifications_partners": false + }, + "type": "mars2", + "dvrSubscriptionSetupDone": true, + "secChipCertSerial": null, + "createdAt": "2019-02-25T05:32:11.263Z", + "updatedAt": "2019-02-25T05:50:03.087Z", + "status": "doorbell_call_status_online", + "statusUpdatedAtMs": 1582608961596, + "telemetry": { + "date": "2019-02-25 08:19:56", + "BSSID": "a:b:c", + "SSID": "none", + "wifi_freq": 2437, + "ip_addr": "4.3.3.2", + "link_quality": 70, + "signal_level": -35, + "uptime": "9499.66 7505.92", + "load_average": "0.42 0.39 0.45 2/180 5959", + "temperature": 49.25, + "steady_ac_in": 0, + "battery": 4.147, + "ac_in": 0, + "doorbell_low_battery": false, + "mcu_version": "900aecaf", + "mcu_temp": 61.470001, + "mcu_bat_cur": 63.779999, + "mcu_dc_in": 4.925, + "chg_state": "CHARGING", + "updated_at": "2019-02-25T08:19:58.678Z" + }, + "caps": ["reconnect", "webrtc", "no_iv"], + "doorbellServerURL": "https://doorbells.august.com", + "recentImage": { + "public_id": "pubid", + "version": 123, + "signature": "sig", + "width": 480, + "height": 640, + "format": "jpg", + "resource_type": "image", + "created_at": "2020-02-25T05:50:02Z", + "tags": [], + "bytes": 25330, + "type": "upload", + "etag": "etag", + "placeholder": false, + "url": "http://of.jpg", + "secure_url": "https://of.jpg", + "original_filename": "file" + }, + "messagingProtocol": "pubnub", + "chimes": [], + "firmwareVersion": "2.3.0-VULRC18+201812100947", + "invitations": [], + "HouseID": "houseid", + "HouseName": "housename" +} diff --git a/tests/fixtures/get_doorbell.battery_low.json b/tests/fixtures/get_doorbell.battery_low.json new file mode 100644 index 0000000..18d7be3 --- /dev/null +++ b/tests/fixtures/get_doorbell.battery_low.json @@ -0,0 +1,105 @@ +{ + "doorbellID": "did", + "serialNumber": "sr", + "appID": "august-iphone-v5", + "installUserID": "iid", + "name": "Front Door", + "installDate": "2019-02-25T05:32:11.263Z", + "pubsubChannel": "pubsub", + "settings": { + "ABREnabled": true, + "auto_contrast_mode": 0, + "backlight_comp": false, + "batteryChargeCurrent": 60, + "batteryLowThreshold": 3.1, + "batteryUseThreshold": 3.4, + "batteryRun": false, + "bellTimerConfig": 50, + "bitrateCeiling": 512000, + "brightness": 50, + "contrast": 50, + "directLink": true, + "debug": false, + "flashBrightness": 40, + "flashDuringCall": true, + "flashOnPIR": true, + "haloBrightnessX": 25, + "hue": 50, + "initialBitrate": 384000, + "IREnabled": true, + "irConfiguration": 16836880, + "irSensitivity": 70, + "IVAEnabled": false, + "JPGQuality": 70, + "keepEncoderRunning": true, + "maintainIVConnection": true, + "micVolume": 100, + "minACNoScaling": 40, + "minimumSnapshotInterval": 30, + "overlayEnabled": true, + "ringSoundEnabled": true, + "saturation": 50, + "sharpness": 50, + "speakerVolume": 92, + "turnOffCamera": false, + "buttonpush_notifications": true, + "motion_notifications": true, + "notify_when_offline": false, + "buttonpush_notifications_partners": false + }, + "type": "mars2", + "dvrSubscriptionSetupDone": true, + "secChipCertSerial": null, + "createdAt": "2019-02-25T05:32:11.263Z", + "updatedAt": "2019-02-25T05:50:03.087Z", + "status": "doorbell_call_status_online", + "statusUpdatedAtMs": 1582608961596, + "telemetry": { + "date": "2019-02-25 05:50:01", + "BSSID": "4:d:d", + "SSID": "zip", + "wifi_freq": 2437, + "ip_addr": "1.2.2.4", + "link_quality": 70, + "signal_level": -38, + "uptime": "504.12 380.94", + "load_average": "0.57 0.41 0.22 1/180 1149", + "temperature": 45.625, + "steady_ac_in": 0, + "battery": 3.023, + "ac_in": 0, + "doorbell_low_battery": true, + "mcu_version": "900aecaf", + "mcu_temp": 59.009998, + "mcu_bat_cur": 65, + "mcu_dc_in": 4.978, + "chg_state": "CHARGING", + "updated_at": "2020-02-25T05:50:03.087Z" + }, + "caps": ["reconnect", "webrtc", "no_iv"], + "doorbellServerURL": "https://doorbells.august.com", + "recentImage": { + "public_id": "pubid", + "version": 123, + "signature": "sig", + "width": 480, + "height": 640, + "format": "jpg", + "resource_type": "image", + "created_at": "2020-02-25T05:50:02Z", + "tags": [], + "bytes": 25330, + "type": "upload", + "etag": "etag", + "placeholder": false, + "url": "http://of.jpg", + "secure_url": "https://of.jpg", + "original_filename": "file" + }, + "messagingProtocol": "pubnub", + "chimes": [], + "firmwareVersion": "2.3.0-VULRC18+201812100947", + "invitations": [], + "HouseID": "houseid", + "HouseName": "housename" +} diff --git a/tests/fixtures/get_doorbell.battery_medium.json b/tests/fixtures/get_doorbell.battery_medium.json new file mode 100644 index 0000000..cb3a05f --- /dev/null +++ b/tests/fixtures/get_doorbell.battery_medium.json @@ -0,0 +1,105 @@ +{ + "doorbellID": "did", + "serialNumber": "sr", + "appID": "august-iphone-v5", + "installUserID": "iid", + "name": "Front Door", + "installDate": "2019-02-25T05:32:11.263Z", + "pubsubChannel": "pubsub", + "settings": { + "ABREnabled": true, + "auto_contrast_mode": 0, + "backlight_comp": false, + "batteryChargeCurrent": 60, + "batteryLowThreshold": 3.1, + "batteryUseThreshold": 3.4, + "batteryRun": false, + "bellTimerConfig": 50, + "bitrateCeiling": 512000, + "brightness": 50, + "contrast": 50, + "directLink": true, + "debug": false, + "flashBrightness": 40, + "flashDuringCall": true, + "flashOnPIR": true, + "haloBrightnessX": 25, + "hue": 50, + "initialBitrate": 384000, + "IREnabled": true, + "irConfiguration": 16836880, + "irSensitivity": 70, + "IVAEnabled": false, + "JPGQuality": 70, + "keepEncoderRunning": true, + "maintainIVConnection": true, + "micVolume": 100, + "minACNoScaling": 40, + "minimumSnapshotInterval": 30, + "overlayEnabled": true, + "ringSoundEnabled": true, + "saturation": 50, + "sharpness": 50, + "speakerVolume": 92, + "turnOffCamera": false, + "buttonpush_notifications": true, + "motion_notifications": true, + "notify_when_offline": false, + "buttonpush_notifications_partners": false + }, + "type": "mars2", + "dvrSubscriptionSetupDone": true, + "secChipCertSerial": null, + "createdAt": "2019-02-25T05:32:11.263Z", + "updatedAt": "2019-02-25T05:50:03.087Z", + "status": "doorbell_call_status_online", + "statusUpdatedAtMs": 1582608961596, + "telemetry": { + "date": "2019-02-25 08:19:56", + "BSSID": "a:b:c", + "SSID": "none", + "wifi_freq": 2437, + "ip_addr": "4.3.3.2", + "link_quality": 70, + "signal_level": -35, + "uptime": "9499.66 7505.92", + "load_average": "0.42 0.39 0.45 2/180 5959", + "temperature": 49.25, + "steady_ac_in": 0, + "battery": 3.82, + "ac_in": 0, + "doorbell_low_battery": false, + "mcu_version": "900aecaf", + "mcu_temp": 61.470001, + "mcu_bat_cur": 63.779999, + "mcu_dc_in": 4.925, + "chg_state": "CHARGING", + "updated_at": "2019-02-25T08:19:58.678Z" + }, + "caps": ["reconnect", "webrtc", "no_iv"], + "doorbellServerURL": "https://doorbells.august.com", + "recentImage": { + "public_id": "pubid", + "version": 123, + "signature": "sig", + "width": 480, + "height": 640, + "format": "jpg", + "resource_type": "image", + "created_at": "2020-02-25T05:50:02Z", + "tags": [], + "bytes": 25330, + "type": "upload", + "etag": "etag", + "placeholder": false, + "url": "http://of.jpg", + "secure_url": "https://of.jpg", + "original_filename": "file" + }, + "messagingProtocol": "pubnub", + "chimes": [], + "firmwareVersion": "2.3.0-VULRC18+201812100947", + "invitations": [], + "HouseID": "houseid", + "HouseName": "housename" +} diff --git a/tests/test_api.py b/tests/test_api.py index 70dbc2b..158ded3 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -151,10 +151,52 @@ def test_get_doorbell_offline(self, mock): self.assertEqual(81, doorbell.battery_level) self.assertEqual(False, doorbell.is_online) self.assertEqual(False, doorbell.is_standby) - self.assertEqual(dateutil.parser.parse("2019-02-20T23:52:46Z"), doorbell.image_created_at_datetime) + self.assertEqual( + dateutil.parser.parse("2019-02-20T23:52:46Z"), + doorbell.image_created_at_datetime, + ) self.assertEqual(True, doorbell.has_subscription) - self.assertEqual('https://res.cloudinary.com/x.jpg', doorbell.image_url) - self.assertEqual('hydra1', doorbell.model) + self.assertEqual("https://res.cloudinary.com/x.jpg", doorbell.image_url) + self.assertEqual("hydra1", doorbell.model) + + @requests_mock.Mocker() + def test_get_doorbell_gen2_full_battery_detail(self, mock): + mock.register_uri( + "get", + API_GET_DOORBELL_URL.format(doorbell_id="did"), + text=load_fixture("get_doorbell.battery_full.json"), + ) + + api = Api() + doorbell = api.get_doorbell_detail(ACCESS_TOKEN, "did") + + self.assertEqual(100, doorbell.battery_level) + + @requests_mock.Mocker() + def test_get_doorbell_gen2_medium_battery_detail(self, mock): + mock.register_uri( + "get", + API_GET_DOORBELL_URL.format(doorbell_id="did"), + text=load_fixture("get_doorbell.battery_medium.json"), + ) + + api = Api() + doorbell = api.get_doorbell_detail(ACCESS_TOKEN, "did") + + self.assertEqual(75, doorbell.battery_level) + + @requests_mock.Mocker() + def test_get_doorbell_gen2_low_battery_detail(self, mock): + mock.register_uri( + "get", + API_GET_DOORBELL_URL.format(doorbell_id="did"), + text=load_fixture("get_doorbell.battery_low.json"), + ) + + api = Api() + doorbell = api.get_doorbell_detail(ACCESS_TOKEN, "did") + + self.assertEqual(10, doorbell.battery_level) @requests_mock.Mocker() def test_get_locks(self, mock): @@ -246,6 +288,7 @@ def test_get_lock_detail_bridge_online(self, mock): self.assertEqual(88, lock.battery_level) self.assertEqual("AUG-SL02-M02-S02", lock.model) self.assertEqual("Medium", lock.keypad.battery_level) + self.assertEqual(60, lock.keypad.battery_percentage) self.assertEqual("5bc65c24e6ef2a263e1450a8", lock.keypad.device_id) self.assertIsInstance(lock.bridge, BridgeDetail) self.assertEqual(True, lock.bridge_is_online)