diff --git a/README.md b/README.md index 3ec4996..5fe1c7e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Travis (.com)](https://img.shields.io/travis/com/dewgew/Domoticz-Google-Assistant?logo=travis)](https://travis-ci.com/DewGew/Domoticz-Google-Assistant) [![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/dewgew/domoticz-google-assistant?logo=docker)](https://hub.docker.com/r/dewgew/domoticz-google-assistant) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/dewgew/Domoticz-Google-Assistant?logo=github) [![Discord](https://img.shields.io/discord/664815298284748830?logo=discord)](https://discordapp.com/invite/AmJV6AC) +![GitHub release (latest by date)](https://img.shields.io/github/v/release/dewgew/Domoticz-Google-Assistant?logo=github) [![Discord](https://img.shields.io/discord/664815298284748830?logo=discord)](https://discordapp.com/invite/AmJV6AC) # Domoticz-Google-Assistant drawing diff --git a/const.py b/const.py index 5afd6df..8c1d8ed 100644 --- a/const.py +++ b/const.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- """Constants for Google Assistant.""" -VERSION = '1.22.25' +VERSION = '1.22.32' PUBLIC_URL = 'https://[your public url]' CONFIGFILE = 'config/config.yaml' LOGFILE = 'dzga.log' @@ -90,7 +90,7 @@ 'dishwasher': 'Dishwasher', 'dryer': 'Dryer', 'fan': 'Fan', - 'garage': 'GarageSensor', + 'garage': 'GarageDoor', 'gate': 'Gate', 'group': 'Group', 'heater': 'Heater', diff --git a/smarthome.py b/smarthome.py index 0dc9c40..3b75e1e 100644 --- a/smarthome.py +++ b/smarthome.py @@ -159,8 +159,7 @@ def AogGetDomain(device): return DOMAINS['selector'] elif 'Smoke Detector' == device["SwitchType"]: return DOMAINS['smokedetector'] - elif 'Camera_Stream' in configuration and True == device["UsedByCamera"] and True == \ - configuration['Camera_Stream']['Enabled']: + elif 'Camera_Stream' in configuration and True == device["UsedByCamera"] and True == configuration['Camera_Stream']['Enabled']: return DOMAINS['camera'] elif device["Image"] == 'Generic': return DOMAINS['switch'] @@ -548,7 +547,7 @@ def sync_serialize(self, agent_user_id): device = { 'id': state.entity_id, - 'notificationSupportedByAgent': (True if state.domain == 'Doorbell' else False), + 'notificationSupportedByAgent': (True if state.domain in [DOMAINS['doorbell'], DOMAINS['smokedetector']] else False), 'name': { 'name': state.name }, @@ -575,7 +574,7 @@ def sync_serialize(self, agent_user_id): if room: device['roomHint'] = room - if state.domain == 'Doorbell': + if state.domain == DOMAINS['doorbell']: device['traits'].append('action.devices.traits.ObjectDetection') return device @@ -741,13 +740,12 @@ def smarthome_post(self, s): def notification_post(self, s): logger.debug(s.headers) a = s.headers.get('Authorization', None) - token = None if a is not None: types, tokenH = a.split() if types.lower() == 'bearer': token = Auth['tokens'].get(tokenH, None) - + if token is None: raise SmartHomeError(ERR_PROTOCOL_ERROR, 'not authorized access!!') @@ -755,9 +753,9 @@ def notification_post(self, s): string.digits, k=10)) request_id = ''.join(random.choices(string.digits, k=20)) - + message = s.body - message = message.replace('|', ' ').split() + if '|' in message: message = message.replace('|', ' ').split() if '>>' in message: message.remove('>>') devid = message[0] state = message[1] @@ -790,9 +788,36 @@ def notification_post(self, s): } } } + ReportState.call_homegraph_api(REPORT_STATE_BASE_URL, data) + elif aog.domain in DOMAINS['smokedetector']: + data = { + 'requestId': str(request_id), + 'agentUserId': token.get('userAgentId', None), + 'eventId': str(event_id), + 'payload': { + 'devices': { + 'states': { + devid: { + 'on': (True if state.lower() in ['on'] else False) + }, + }, + 'notifications': { + devid: { + 'SensorState': { + 'priority': 0, + 'name': 'SmokeLevel', + 'currentSensorState': 'smoke detected' + } + } + } + } + } + } ReportState.call_homegraph_api(REPORT_STATE_BASE_URL, data) else: logger.info('Notification is not supported for ' + message[0]) + elif message == 'Domoticz test message!': + logger.info('Great! Test is working, Now add custom message e.g "light123|$value" in the device notification settings') else: logger.error('Something went wrong, check your notification settings!') diff --git a/trait.py b/trait.py index 39ca212..a207225 100644 --- a/trait.py +++ b/trait.py @@ -157,7 +157,6 @@ def supported(domain, features): DOMAINS['oven'], DOMAINS['push'], DOMAINS['sensor'], - DOMAINS['smokedetector'], DOMAINS['speaker'], DOMAINS['switch'], #DOMAINS['vacuum'], @@ -169,7 +168,7 @@ def sync_attributes(self): """Return OnOff attributes for a sync request.""" domain = self.state.domain response = {} - if domain in [DOMAINS['sensor'], DOMAINS['smokedetector'], DOMAINS['doorbell']]: + if domain in [DOMAINS['sensor'], DOMAINS['doorbell']]: response['queryOnlyOnOff'] = True return response @@ -193,7 +192,7 @@ def execute(self, command, params): domain = self.state.domain protected = self.state.protected - if domain not in [DOMAINS['sensor'], DOMAINS['smokedetector']]: + if domain not in [DOMAINS['sensor']]: if domain == DOMAINS['group']: url = DOMOTICZ_URL + '/json.htm?type=command¶m=switchscene&idx=' + self.state.id + '&switchcmd=' + ( 'On' if params['on'] else 'Off') @@ -349,8 +348,11 @@ def supported(domain, features): def sync_attributes(self): """Return OpenClose attributes for a sync request.""" features = self.state.attributes + domain = self.state.domain response = {} + if domain != DOMAINS['blinds']: + response['queryOnlyOpenClose'] = True if features & ATTRS_PERCENTAGE != True: response['discreteOnlyOpenClose'] = True @@ -391,16 +393,16 @@ def execute(self, command, params): url = DOMOTICZ_URL + '/json.htm?type=command¶m=switchlight&idx=' + self.state.id + '&switchcmd=' - if p == 100 and state in ['Closed', 'Stopped', 'On']: - # open - url += 'Open' - elif p == 0 and state in ['Open', 'Stopped', 'Off']: - # close - url += 'Close' - else: - raise SmartHomeError(ERR_ALREADY_IN_STATE, - 'Unable to execute {} for {}. Already in state '.format(command, - self.state.entity_id)) + if p == 100 and state in ['Closed', 'Stopped', 'On']: + # open + url += 'Open' + elif p == 0 and state in ['Open', 'Stopped', 'Off']: + # close + url += 'Close' + else: + raise SmartHomeError(ERR_ALREADY_IN_STATE, + 'Unable to execute {} for {}. Already in state '.format(command, + self.state.entity_id)) if protected: url = url + '&passcode=' + configuration['Domoticz']['switchProtectionPass'] @@ -443,7 +445,7 @@ def query_attributes(self): domain = self.state.domain response = {} if domain == DOMAINS['blinds']: - response['isRunning'] = True + response['isRunning'] = False else: response['isRunning'] = self.state.state != 'Off' @@ -980,10 +982,10 @@ class CameraStreamTrait(_Trait): @staticmethod def supported(domain, features): """Test if state is supported.""" - if configuration['Camera_Stream']['Enabled']: + if 'Camera_Stream' in configuration and configuration['Camera_Stream']['Enabled']: return domain in [DOMAINS['camera'], DOMAINS['doorbell']] - - return False + else: + return False def sync_attributes(self): """Return stream attributes for a sync request.""" @@ -1284,15 +1286,15 @@ def supported(domain, features): def sync_attributes(self): """Return attributes for a sync request.""" domain = self.state.domain - if domain == DOMAIN['smokedetector']: + if domain == DOMAINS['smokedetector']: return { - "sensorStatesSupported": [ + 'sensorStatesSupported': [ { - "name": "SmokeLevel", - "descriptiveCapabilities": { - "availableStates": [ - "smoke detected", - "no smoke detected" + 'name': 'SmokeLevel', + 'descriptiveCapabilities': { + 'availableStates': [ + 'smoke detected', + 'no smoke detected' ] } } @@ -1302,12 +1304,13 @@ def sync_attributes(self): def query_attributes(self): """Return the attributes of this trait for this entity.""" domain = self.state.domain - if self.state.state is not None: + state = self.state.state + if state is not None: return { - "currentSensorStateData": [ + 'currentSensorStateData': [ { - "name": "SmokeLevel", - "currentSensorState": "smoke detected", + 'name': 'SmokeLevel', + 'currentSensorState': ('smoke detekted' if state == 'on' else 'no smoke detected'), } ] }