diff --git a/VERSION.md b/VERSION.md index 5cdd6dd..e68b0bf 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1,5 +1,4 @@ -24.3 -- Fixed DoorLockInverted -- Security Update. DZGA now reads smart-home-key.json file from config folder. Move .json file or upload a new. -- Added new device, Door Lock Inverted. -- Changed check version, get latest updates. +24.4 +- Fixes Lighting 4 devices +- Added battery level on dashboard devices +- Added Enerygystorgae trait uses to check battery level diff --git a/modules/domoticz.py b/modules/domoticz.py index 172992b..83b9879 100644 --- a/modules/domoticz.py +++ b/modules/domoticz.py @@ -106,7 +106,7 @@ def getAog(device, user_id=None): 'name': device.get('Name'), 'nicknames': [] } - if device.get('Type') in ['Light/Switch', 'Color Switch', 'Lighting 1', 'Lighting 2', 'Lighting 5', 'RFY', 'Value']: + if device.get('Type') in ['Light/Switch', 'Color Switch', 'Lighting 1', 'Lighting 2', 'Lighting 3','Lighting 4', 'Lighting 5', 'RFY', 'Value']: aog.type = 'action.devices.types.LIGHT' if device.get('Image') == 'WallSocket': aog.type = 'action.devices.types.OUTLET' @@ -168,7 +168,7 @@ def getAog(device, user_id=None): aog.customData['idx'] = device.get('idx') aog.customData['domain'] = domain aog.customData['protected'] = device.get('Protected') - aog.notificationSupportedByAgent = (True if domain in ['SmokeDetector', 'Doorbell', 'DoorLock', 'DoorLockInverted'] else False) + aog.notificationSupportedByAgent = (True if domain in ['SmokeDetector', 'Doorbell', 'DoorLock', 'DoorLockInverted'] else False) if domain == 'Scene': aog.type = 'action.devices.types.SCENE' @@ -342,6 +342,12 @@ def getAog(device, user_id=None): ], 'cameraStreamNeedAuthToken': False } + + batteryLevel = device.get('BatteryLevel') + if domain not in ['Group', 'Scene'] and batteryLevel != 255: + aog.traits.append('action.devices.traits.EnergyStorage') + aog.attributes['queryOnlyEnergyStorage'] = True + aog.attributes['isRechargeable'] = False return aog diff --git a/modules/trait.py b/modules/trait.py index ff5e53d..bb29b9e 100644 --- a/modules/trait.py +++ b/modules/trait.py @@ -124,8 +124,33 @@ def query(custom_data, device, user_id): response["isArmed"] = state['Data'] != "Normal" if response["isArmed"]: response["currentArmLevel"] = state['Data'] + + if 'action.devices.traits.EnergyStorage' in device['traits']: + if state['BatteryLevel'] != 255: + battery = state['BatteryLevel'] + if battery is not None: + if battery == 100: + descriptive_capacity_remaining = "FULL" + elif 75 <= battery < 100: + descriptive_capacity_remaining = "HIGH" + elif 25 <= battery < 75: + descriptive_capacity_remaining = "MEDIUM" + elif 10 <= battery < 25: + descriptive_capacity_remaining = "LOW" + elif 0 <= battery < 10: + descriptive_capacity_remaining = "CRITICALLY_LOW" + + response['descriptiveCapacityRemaining'] = descriptive_capacity_remaining + response['capacityRemaining'] = [{ + 'unit': 'PERCENTAGE', + 'rawValue': battery + }] + response['online'] = True + if domain not in ['Group', 'Scene'] and state['BatteryLevel'] != 255: + if state['BatteryLevel'] <= 10: # Report low battery below 10% + response['exceptionCode'] = 'lowBattery' return response @@ -251,7 +276,8 @@ def execute(device, command, params, user_id, challenge): response['online'] = True return response else: - return {"status": "ERROR", "errorCode": "streamUnavailable"} + raise SmartHomeError('streamUnavailable', + 'Unable to execute {} for {}'.format(command, device['id'])) if command == 'action.devices.commands.ArmDisarm': diff --git a/static/js/smarthome.js b/static/js/smarthome.js index 073c9cc..8ad4834 100644 --- a/static/js/smarthome.js +++ b/static/js/smarthome.js @@ -67,9 +67,22 @@ function refreshTemp(updateTemp) { var temp = jsonData.result[0].Temp; var setpoint = jsonData.result[0].SetPoint var lastUpdate = jsonData.result[0].LastUpdate + var batterylevel = jsonData.result[0].BatteryLevel if (lastUpdate != null){ $('#lastUpdate_' + idx).html(moment(lastUpdate).fromNow()) } + if (batterylevel != 255){ + $('#batteryLevel_' + idx).addClass('bi bi-battery-full') + if (batterylevel <= 50){ + $('#batteryLevel_' + idx).removeClass('bi bi-battery-full') + $('#batteryLevel_' + idx).addClass('bi bi-battery-half') + } + if (batterylevel <= 15){ + $('#batteryLevel_' + idx).removeClass('bi bi-battery-full') + $('#batteryLevel_' + idx).addClass('bi bi-battery').css('color','#ED2939') + } + $('#batteryLevel_' + idx).html(batterylevel + '% ') + }; $('button[id="switch_' + idx + '"]').html(data) $('#data_'+ idx).html(data) $('#actual_data_'+ idx).html(temp) @@ -87,9 +100,22 @@ function refreshSwitches(updateSwitches) { requestAPI(url).then(jsonData => { var data = jsonData.result[0].Data; var lastUpdate = jsonData.result[0].LastUpdate + var batterylevel = jsonData.result[0].BatteryLevel if (lastUpdate != null){ $('#lastUpdate_' + idx).html(moment(lastUpdate).fromNow()) }; + if (batterylevel != 255){ + $('#batteryLevel_' + idx).addClass('bi bi-battery-full') + if (batterylevel <= 50){ + $('#batteryLevel_' + idx).removeClass('bi bi-battery-full') + $('#batteryLevel_' + idx).addClass('bi bi-battery-half') + } + if (batterylevel <= 15){ + $('#batteryLevel_' + idx).removeClass('bi bi-battery-full') + $('#batteryLevel_' + idx).addClass('bi bi-battery').css('color','#ED2939') + } + $('#batteryLevel_' + idx).html(batterylevel + '% ') + }; $('button[id="switch_' + idx + '"]').html(data); $('#data_' + idx).html(data); @@ -149,6 +175,19 @@ function refreshSelectors(updateSelector) { if (lastUpdate != null){ $('#lastUpdate_' + idx).html(moment(lastUpdate).fromNow()) } + var batterylevel = jsonData.result[0].BatteryLevel + if (batterylevel != 255){ + $('#batteryLevel_' + idx).addClass('bi bi-battery-full') + if (batterylevel <= 50){ + $('#batteryLevel_' + idx).removeClass('bi bi-battery-full') + $('#batteryLevel_' + idx).addClass('bi bi-battery-half') + } + if (batterylevel <= 15){ + $('#batteryLevel_' + idx).removeClass('bi bi-battery-full') + $('#batteryLevel_' + idx).addClass('bi bi-battery').css('color','#ED2939') + } + $('#batteryLevel_' + idx).html(batterylevel + '% ') + }; btns = decodeBase64(levelnames).split('|'); $.each(btns, function (i, lvlname) { if (i != '0') { @@ -222,7 +261,19 @@ function refreshDimmers(updateDimmers) { if (lastUpdate != null){ $('#lastUpdate_' + idx).html(moment(lastUpdate).fromNow()) } - + var batterylevel = jsonData.result[0].BatteryLevel + if (batterylevel != 255){ + $('#batteryLevel_' + idx).addClass('bi bi-battery-full') + if (batterylevel <= 50){ + $('#batteryLevel_' + idx).removeClass('bi bi-battery-full') + $('#batteryLevel_' + idx).addClass('bi bi-battery-half') + } + if (batterylevel <= 15){ + $('#batteryLevel_' + idx).removeClass('bi bi-battery-full') + $('#batteryLevel_' + idx).addClass('bi bi-battery').css('color','#ED2939') + } + $('#batteryLevel_' + idx).html(batterylevel + '% ') + }; if (jsonData.result[0].Type == 'Color Switch'){ var color = JSON.parse(jsonData.result[0].Color) var color_decimal = color.r * 65536 + color.g * 256 + color.b diff --git a/templates/dashboard.html b/templates/dashboard.html index 030d747..4f308f3 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -115,7 +115,9 @@