def build(data, client, place=None, sensors=None): device = None if "widget" not in data or "uiClass" not in data: raise CozytouchException("Unable to identify device") device_class = DeviceType.from_str(data["widget"] if "widget" in data else data["uiClass"]) if device_class == DeviceType.OCCUPANCY: device = CozytouchOccupancySensor(data) elif device_class == DeviceType.POD: device = CozytouchPod(data) elif device_class == DeviceType.TEMPERATURE: device = CozytouchTemperatureSensor(data) elif device_class == DeviceType.OCCUPANCY: device = CozytouchOccupancySensor(data) elif device_class == DeviceType.ELECTRECITY: device = CozytouchElectricitySensor(data) elif device_class == DeviceType.CONTACT: device = CozytouchContactSensor(data) elif device_class in [DeviceType.HEATER, DeviceType.HEATER_PASV]: device = CozytouchHeater(data) device.sensors = sensors elif device_class in [DeviceType.WATER_HEATER]: device = CozytouchWaterHeater(data) device.sensors = sensors if device is None: raise CozytouchException( "Unknown device {type}".format(type=device_class)) device.client = client device.place = place return device
def set_comfort_temperature(self, temperature): if not self.has_state(DeviceState.COMFORT_TEMPERATURE_STATE): raise CozytouchException("Unsupported command {command}".format( command=DeviceCommand.SET_COMFORT_TEMP)) if self.client is None: raise CozytouchException("Unable to execute command") eco_temp = temperature - self.eco_temperature commands = CozytouchCommands("Set comfort temperature") action = CozytouchAction(device_url=self.deviceUrl) action.add_command( CozytouchCommand(DeviceCommand.SET_COMFORT_TEMP, temperature)) action.add_command( CozytouchCommand(DeviceCommand.SET_ECO_TEMP, eco_temp)) action.add_command( CozytouchCommand(DeviceCommand.REFRESH_LOWERING_TEMP_PROG)) action.add_command( CozytouchCommand(DeviceCommand.REFRESH_TARGET_TEMPERATURE)) commands.add_action(action) self.client.send_commands(commands) self.set_state(DeviceState.COMFORT_TEMPERATURE_STATE, temperature) self.set_state(DeviceState.ECO_TEMPERATURE_STATE, eco_temp)
def set_comfort_temperature(self, temperature): if not self.has_state(DeviceState.COMFORT_TEMPERATURE_STATE): raise CozytouchException("Unsupported command %s" % DeviceCommand.SET_COMFORT_TEMP) if self.client is None: raise CozytouchException("Unable to execute command") self.client.send_command("Change comfort temperature", self, DeviceCommand.SET_COMFORT_TEMP, [temperature])
def turn_away_mode_on(self): if not self.has_state(DeviceState.AWAY_STATE): raise CozytouchException("Unsupported command %s" % DeviceCommand.SET_AWAY_MODE) if self.client is None: raise CozytouchException("Unable to execute command") self.client.send_command("Change away mode", self, DeviceCommand.SET_AWAY_MODE, ["on"])
def set_operation_mode(self, mode): if not self.has_state(DeviceState.OPERATING_MODE_STATE): raise CozytouchException("Unsupported command %s" % DeviceCommand.SET_OPERATION_MODE) if self.client is None: raise CozytouchException("Unable to execute command") self.client.send_command("Change operation mode", self, DeviceCommand.SET_OPERATION_MODE, [mode])
def get_states(self, devices: list, *args): """ Get devices states """ headers = { 'User-Agent': USER_AGENT, 'Content-type': 'application/json' } payload = [{ "deviceURL": device.deviceUrl, "states": [{ 'name': state["name"] } for state in device.states] } for device in devices] response = self.session.post(COZYTOUCH_ENDPOINT + '/getStates', headers=headers, data=json.dumps(payload), timeout=self.timeout) self.__retry(response, self.get_states, *args) if response.status_code != 200: raise CozytouchException("Unable to retrieve devices states %s" % response.content) return response.json()
def find_place(device): place: CozytouchPlace = self.__find_place(device["placeOID"]) if place is None: raise CozytouchException( "Place {name} not found".format(name=device["placeOID"]) ) return place
def __build_devices(self, devices): sensors = [] heaters = [] for device in devices: if device["widget"] in [ DeviceType.HEATER.value, DeviceType.HEATER_PASV.value ]: heaters.append(device) else: sensors.append(device) def extract_id(url): if '#' not in url: return url return url[0:url.index("#")] for heater in heaters: place: CozytouchPlace = self.__find_place(heater["placeOID"]) if place is None: raise CozytouchException("Place %s not found" % heater["placeOID"]) heater_url = extract_id(heater["deviceURL"]) heater_sensors = [ CozytouchDevice.build(sensor, self.client, place) for sensor in sensors if extract_id(sensor["deviceURL"]) == heater_url ] heater = CozytouchHeater(heater) heater.sensors = heater_sensors heater.place = place heater.client = self.client self.heaters.append(heater)
def set_targeting_heating_level(self, level): if not self.has_state(DeviceState.TARGETING_HEATING_LEVEL_STATE): raise CozytouchException("Unsupported command {command}".format( command=DeviceCommand.SET_HEATING_LEVEL)) if self.client is None: raise CozytouchException("Unable to execute command") commands = CozytouchCommands("Change heating level") action = CozytouchAction(device_url=self.deviceUrl) action.add_command( CozytouchCommand(DeviceCommand.SET_HEATING_LEVEL, level)) commands.add_action(action) self.client.send_commands(commands) self.set_state(DeviceState.TARGETING_HEATING_LEVEL_STATE, level)
def turn_away_mode_on(self): if not self.has_state(DeviceState.AWAY_STATE): raise CozytouchException("Unsupported command {command}".format( command=DeviceCommand.SET_AWAY_MODE)) if self.client is None: raise CozytouchException("Unable to execute command") commands = CozytouchCommands("Set away mode ON") action = CozytouchAction(device_url=self.deviceUrl) action.add_command( CozytouchCommand(DeviceCommand.SET_AWAY_MODE, AwayModeState.ON)) commands.add_action(action) self.client.send_commands(commands) self.set_state(DeviceState.AWAY_STATE, AwayModeState.ON)
def update(self): if self.client is None: raise CozytouchException("Unable to update heater") time.sleep(2) for sensor in self.sensors: sensor.update() super(CozytouchHeater, self).update()
def set_operating_mode(self, mode): if not self.has_state(DeviceState.OPERATING_MODE_STATE): raise CozytouchException("Unsupported command {command}".format( command=DeviceCommand.SET_OPERATION_MODE)) if self.client is None: raise CozytouchException("Unable to execute command") commands = CozytouchCommands("Change operating mode") action = CozytouchAction(device_url=self.deviceUrl) action.add_command( CozytouchCommand(DeviceCommand.SET_OPERATION_MODE, mode)) action.add_command( CozytouchCommand(DeviceCommand.REFRESH_OPERATION_MODE)) commands.add_action(action) self.client.send_commands(commands) self.set_state(DeviceState.OPERATING_MODE_STATE, mode)
def get_devices(self, *args): """ Get cozytouch setup (devices, places) """ response = self.__make_request("devices") self.__retry(response, self.get_devices) if response.status_code != 200: raise CozytouchException( "Unable to retrieve devices: {response}".format( response=response.content)) return DevicesHandler(response.json(), self)
def __authenticate(self): """ Authenticate using username and userPassword """ headers = {'User-Agent': USER_AGENT} payload = {'userId': self.username, 'userPassword': self.password} response = self.session.post(COZYTOUCH_ENDPOINT + "login", headers=headers, data=payload, timeout=self.timeout) if response.status_code != 200: raise CozytouchException("Authentication failed")
def __authenticate(self): """ Authenticate using username and userPassword """ response = self.__make_request("login", method="POST", data={ 'userId': self.username, 'userPassword': self.password }, json_encode=False) if response.status_code != 200: raise CozytouchException("Authentication failed")
def build_url(cls, resource, data): """ Build url""" if resource not in COZYTOUCH_ENDPOINTS: raise CozytouchException( "Bad resource: {resource}".format(resource=resource)) url = COZYTOUCH_ENDPOINTS[resource] matches = re.findall("(?P<text>\\[(?P<param>[^] ]+)\\])", url) for text, key in matches: url = url.replace(text, urllib.parse.quote_plus(data[key])) return url
def get_setup(self, *args): """ Get cozytouch setup (devices, places) """ response = self.__make_request("setup", method="GET") self.__retry(response, self.get_setup) if response.status_code != 200: response_json = response.json() raise CozytouchException( "Unable to retrieve setup: {error}[{code}] ".format( error=response_json["error"], code=response_json["errorCode"])) return SetupHandler(response.json(), self)
def get_setup(self, *args): """ Get cozytouch setup (devices, places) """ headers = {'User-Agent': USER_AGENT} response = self.session.get(COZYTOUCH_ENDPOINT + '/getSetup', headers=headers, timeout=self.timeout) self.__retry(response, self.get_setup) if response.status_code != 200: raise CozytouchException("Unable to retrieve setup %s " % response.content) return SetupHandler(response.json(), self)
def get_device_info(self, device_url, *args): """ Get cozytouch setup (devices, places) """ response = self.__make_request("deviceInfo", data={"device_url": device_url}) self.__retry(response, self.get_devices, {"device_url": device_url}) if response.status_code != 200: response_json = response.json() raise CozytouchException( "Unable to retrieve device {device_url}: {error}[{code}] ". format(device_url=device_url, error=response_json["error"], code=response_json["errorCode"])) state = response.json() return state
def build(data, client, place): device = None if data["widget"] == DeviceType.OCCUPANCY.value: device = CozytouchOccupancySensor(data) elif data["widget"] == DeviceType.TEMPERATURE.value: device = CozytouchTemperatureSensor(data) elif data["widget"] == DeviceType.ELECTRECITY.value: device = CozytouchElectricitySensor(data) elif data["widget"] == DeviceType.CONTACT.value: device = CozytouchContactSensor(data) if device is None: raise CozytouchException("Unknown device %s" % data["widget"]) device.client = client device.place = place return device
def send_commands(self, commands, *args): """ Get devices states """ response = self.__make_request( "apply", method="POST", data=commands, headers={'Content-type': 'application/json'}) self.__retry(response, self.send_commands, *args) if response.status_code != 200: response_json = response.json() raise CozytouchException( "Unable to send command : {error}[{code}] ".format( error=response_json["error"], code=response_json["errorCode"])) return response.json()
def get_device_state(self, device_url, state_name, *args): """ Get cozytouch setup (devices, places) """ response = self.__make_request("stateInfo", data={ "device_url": device_url, "state_name": state_name }) kwargs = {"device_url": device_url, "state_name": state_name} self.__retry(response, self.get_devices, kwargs) if response.status_code != 200: raise CozytouchException( "Unable to retrieve state {state_name} from device {device_url} : {response}" .format(device_url=device_url, state_name=state_name, response=response.content)) return SetupHandler(response.json(), self)
def send_command(self, label, device, command: DeviceCommand, parameters=None, *args): """ Get devices states """ headers = { 'User-Agent': USER_AGENT, 'Content-type': 'application/json' } payload = { "label": label, "actions": [{ "deviceURL": device.deviceUrl, "commands": [{ "name": command.value, "parameters": parameters }] }] } response = self.session.post(COZYTOUCH_ENDPOINT + '/apply', headers=headers, data=json.dumps(payload), timeout=self.timeout) self.__retry(response, self.send_command, *args) if response.status_code != 200: raise CozytouchException("Unable to send command %s" % response.content) json_response = response.json() print(json_response) return json_response
def update(self): if self.client is None: raise CozytouchException("Unable to execute command") self.states = self.client.get_device_info(self.deviceUrl)
def __find_place(self, device): for place in self.places: if place.id == device["placeOID"]: return place raise CozytouchException( "Place {name} not found".format(name=device["placeOID"]))
def update(self): if self.client is None: raise CozytouchException("Unable to execute command") updated_data = self.client.get_states([self]) self.states = updated_data["devices"][0]["states"]