From 821d0a944f8a874070303efbc101184cab005adb Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 06:58:46 +0100 Subject: [PATCH 01/10] Add timer trait --- modules/domoticz.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/modules/domoticz.py b/modules/domoticz.py index b3ad4d2..14cf1b5 100644 --- a/modules/domoticz.py +++ b/modules/domoticz.py @@ -127,6 +127,8 @@ def getAog(device, user_id=None): aog.type = 'action.devices.types.SWITCH' if domain in ['DoorLock', 'DoorLockInverted']: aog.type = 'action.devices.types.LOCK' + if domain in ['OnOff', 'Dimmer', 'ColorSwitch']: + aog.traits.append('action.devices.traits.Timer') aog.customData['check_state'] = True # Try to get device specific voice control configuration from Domoticz @@ -181,7 +183,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' @@ -425,3 +427,16 @@ def getDomoticzState(user_id, idx, device='id'): data = d return data + + +def getDzUser(user_id): + + url = "?type=command¶m=getusers" + try: + r = json.loads(queryDomoticz(user_id, url)) + if r['status'] == 'OK': + return True + else: + return False + except Exception as err: + return False From e90ba6db027e05e19b79f54eedcb70845decc62c Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 06:59:47 +0100 Subject: [PATCH 02/10] Add timer trait --- modules/trait.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/modules/trait.py b/modules/trait.py index d06ecbb..905cd61 100644 --- a/modules/trait.py +++ b/modules/trait.py @@ -327,8 +327,8 @@ def execute(device, command, params, user_id, challenge): url += "setsecstatus&secstatus=2" else: if state['Data'] == "Normal" and check_state: - raise SmartHomeError('alreadyInState', - 'Unable to execute {} for {}. Already in state '.format(command, device['id'])) + raise SmartHomeError('alreadyDisarmed', + 'Unable to execute {} for {}. Already disarmed '.format(command, device['id'])) else: url += "setsecstatus&secstatus=0" @@ -348,6 +348,14 @@ def execute(device, command, params, user_id, challenge): slevel = str(levelName.index(key) * 10) url += 'switchlight&idx=' + idx + '&switchcmd=Set%20Level&level=' + slevel + + if command == 'action.devices.commands.TimerStart': + + url = 'customevent&event=TIMER&data={"idx":' + idx + ',"time":' + str(params['timerTimeSec']) + ',"on":true}' + + if command == 'action.devices.commands.TimerCancel': + + url = 'customevent&event=TIMER&data={"idx":' + idx + ',"cancel":true}' if state['Protected'] is True: url = url + '&passcode=' + challenge.get('pin') From 46036104283471fb3f283914b7228767a4f6945c Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 07:00:42 +0100 Subject: [PATCH 03/10] Add getDzUser --- modules/routes.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/modules/routes.py b/modules/routes.py index 6a3fc70..c278225 100644 --- a/modules/routes.py +++ b/modules/routes.py @@ -9,7 +9,7 @@ from werkzeug.security import generate_password_hash, check_password_hash from modules.reportstate import ReportState from modules.database import db, User, Settings -from modules.domoticz import saveJson, getDomoticzDevices +from modules.domoticz import saveJson, getDomoticzDevices, getDzUser from modules.helpers import logger, get_devices, generateToken, remove_user, getVersion from sqlalchemy import or_ @@ -44,6 +44,7 @@ def devices(): devices = get_devices(current_user.username) dbuser = User.query.filter_by(username=current_user.username).first() version = getVersion() + dzUserAdmin = getDzUser(current_user.username) if request.method == "POST": @@ -180,7 +181,8 @@ def devices(): reportstate=reportstate, devices=devices, _csrf_token=session['_csrf_token'], - version = version + version = version, + dzUserAdmin = dzUserAdmin ) @@ -302,6 +304,7 @@ def settings(): reportstate = report_state.report_state_enabled() devices = get_devices(current_user.username) version = getVersion() + dzUserAdmin = getDzUser(current_user.username) return render_template('settings.html', user=User.query.filter_by(username=current_user.username).first(), @@ -310,7 +313,8 @@ def settings(): reportstate=reportstate, devices=devices, _csrf_token=session['_csrf_token'], - version = version + version = version, + dzUserAdmin = dzUserAdmin ) From 08465c9243539f346c8e30ceb2634afe541a7ae1 Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 07:02:19 +0100 Subject: [PATCH 04/10] Rewrite getDzUser --- templates/devices.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/templates/devices.html b/templates/devices.html index 28b8d38..baa5b1e 100644 --- a/templates/devices.html +++ b/templates/devices.html @@ -96,12 +96,12 @@
Description | {{ v['name']['name'] }}

- Turns on/off already in state error message + Turns on/off 'already in state' error message
-
- {% if v['notificationSupportedByAgent'] == True %}User can turn on or off notifications in Google Home App{% endif %} +
+ {% if v['notificationSupportedByAgent'] == True %}User can turn on/off notifications in Google Home App{% endif %}
@@ -118,10 +118,10 @@
Description | {{ v['name']['name'] }}
- + (Set device as protected in Domoticz) + {% if dzUserAdmin is not true %} (Set device as protected in Domoticz){% endif %}
@@ -319,9 +319,9 @@
Description | {{ v['name']['name'] }}
{% if v['customData']['protected'] == False %} - From fbba694e6c39aed7fd21a2050d7e99f234770fe4 Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 07:03:12 +0100 Subject: [PATCH 05/10] Rewrite getDzUser --- templates/settings.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/templates/settings.html b/templates/settings.html index b2cb1c8..4ca42fd 100644 --- a/templates/settings.html +++ b/templates/settings.html @@ -73,7 +73,7 @@
User settings | {{ user.username }}
- +
@@ -126,6 +126,4 @@
User settings | {{ user.username }}
} }); -getUser("{{ user.domouser }}") - From 73648f421400ea663e3053c96537a2a88c1fb839 Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 07:04:21 +0100 Subject: [PATCH 06/10] Remove getUser function --- static/js/smarthome.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/static/js/smarthome.js b/static/js/smarthome.js index 0e3e5f6..8387c0e 100644 --- a/static/js/smarthome.js +++ b/static/js/smarthome.js @@ -365,17 +365,6 @@ function setSelectorLevel(div, idx, protect) { requestAPI(requesturl) } -function getUser(user) { - var url = "/api?type=command¶m=getusers" - requestAPI(url).then(jsonData => { - var data = jsonData - if (data.status == 'ERR' || data.status == null) { - $('#domoticzAdmin').val('No') - } else { - $('#domoticzAdmin').val('Yes') - } - }); -} function getDzVersion() { var url = "/api?type=command¶m=getversion" requestAPI(url).then(jsonData => { From 90d05fc494043573253e8658fade1350af608055 Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 10:22:37 +0100 Subject: [PATCH 07/10] Add timer trait --- modules/domoticz.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/domoticz.py b/modules/domoticz.py index 14cf1b5..c677ea5 100644 --- a/modules/domoticz.py +++ b/modules/domoticz.py @@ -127,8 +127,6 @@ def getAog(device, user_id=None): aog.type = 'action.devices.types.SWITCH' if domain in ['DoorLock', 'DoorLockInverted']: aog.type = 'action.devices.types.LOCK' - if domain in ['OnOff', 'Dimmer', 'ColorSwitch']: - aog.traits.append('action.devices.traits.Timer') aog.customData['check_state'] = True # Try to get device specific voice control configuration from Domoticz @@ -352,6 +350,11 @@ def getAog(device, user_id=None): ], 'cameraStreamNeedAuthToken': False } + + if domain in ['OnOff', 'Dimmer', 'ColorSwitch']: + aog.traits.append('action.devices.traits.Timer') + aog.attributes['maxTimerLimitSec'] = 7200 + aog.attributes['commandOnlyTimer'] = True batteryLevel = device.get('BatteryLevel') if domain not in ['Group', 'Scene'] and batteryLevel != 255: From 0599b8600bd9e8c5882f359b68b1576ec22452ae Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 10:23:06 +0100 Subject: [PATCH 08/10] Update trait.py --- modules/trait.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/trait.py b/modules/trait.py index 905cd61..58fcdfd 100644 --- a/modules/trait.py +++ b/modules/trait.py @@ -351,11 +351,11 @@ def execute(device, command, params, user_id, challenge): if command == 'action.devices.commands.TimerStart': - url = 'customevent&event=TIMER&data={"idx":' + idx + ',"time":' + str(params['timerTimeSec']) + ',"on":true}' + url += 'customevent&event=TIMER&data={"idx":' + idx + ',"time":' + str(params['timerTimeSec']) + ',"on":true}' if command == 'action.devices.commands.TimerCancel': - url = 'customevent&event=TIMER&data={"idx":' + idx + ',"cancel":true}' + url += 'customevent&event=TIMER&data={"idx":' + idx + ',"cancel":true}' if state['Protected'] is True: url = url + '&passcode=' + challenge.get('pin') From a0b0b9068670755fc99c95a59e748e81768a85ec Mon Sep 17 00:00:00 2001 From: DewGew Date: Sat, 10 Feb 2024 19:26:10 +0100 Subject: [PATCH 09/10] Update domoticz.py --- modules/domoticz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/domoticz.py b/modules/domoticz.py index b3ad4d2..dd09a39 100644 --- a/modules/domoticz.py +++ b/modules/domoticz.py @@ -352,7 +352,7 @@ def getAog(device, user_id=None): } batteryLevel = device.get('BatteryLevel') - if domain not in ['Group', 'Scene'] and batteryLevel != 255: + if domain not in ['Group', 'Scene'] and batteryLevel is not None and batteryLevel != 255: aog.traits.append('action.devices.traits.EnergyStorage') aog.attributes['queryOnlyEnergyStorage'] = True aog.attributes['isRechargeable'] = False From 435838636260e4cf76314f270bd7b00836c17a85 Mon Sep 17 00:00:00 2001 From: DewGew Date: Sat, 10 Feb 2024 19:31:54 +0100 Subject: [PATCH 10/10] Update trait.py --- modules/trait.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/trait.py b/modules/trait.py index d06ecbb..e3a91f7 100644 --- a/modules/trait.py +++ b/modules/trait.py @@ -126,9 +126,9 @@ def query(custom_data, device, user_id): response["currentArmLevel"] = state['Data'] if 'action.devices.traits.EnergyStorage' in device['traits']: - if state['BatteryLevel'] != 255: + if state['BatteryLevel'] is not None: battery = state['BatteryLevel'] - if battery is not None: + if battery != 255: if battery == 100: descriptive_capacity_remaining = "FULL" elif 50 <= battery < 100: @@ -148,7 +148,7 @@ def query(custom_data, device, user_id): response['online'] = True - if domain not in ['Group', 'Scene'] and state['BatteryLevel'] != 255: + if domain not in ['Group', 'Scene'] and state['BatteryLevel'] is not None and state['BatteryLevel'] != 255: if state['BatteryLevel'] <= 10: # Report low battery below 10% response['exceptionCode'] = 'lowBattery'