From 821d0a944f8a874070303efbc101184cab005adb Mon Sep 17 00:00:00 2001 From: DewGew Date: Thu, 8 Feb 2024 06:58:46 +0100 Subject: [PATCH 1/8] 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 2/8] 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 3/8] 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 4/8] 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 5/8] 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 6/8] 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 7/8] 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 8/8] 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')