def setConfigItem(Key=None, Value=None): Config = {} try: Config = Domoticz.Configuration() if (Key != None): Config[Key] = Value else: Config = Value # set whole configuration if no key specified Domoticz.Configuration(Config) except Exception as inst: Domoticz.Error("Domoticz.Configuration operation failed: '" + str(inst) + "'") return Config
def setConfigItemDB(Key=None, Value=None): Config = {} try: Config = Domoticz.Configuration() if (Key != None): Config[Key] = Value else: Config = Value # set whole configuration if no key specified Config = Domoticz.Configuration(Config) except Exception as inst: Domoticz.Error( 'Domoticz.Configuration operation failed: {}'.format(inst)) return Config
def setConfigItem(Key=None, Value=None): Config = {} if type(Value) not in (str, int, float, bool, bytes, bytearray, list, dict): Domoticz.Error("A value is specified of a not allowed type: '" + str(type(Value)) + "'") return Config try: Config = Domoticz.Configuration() if (Key != None): Config[Key] = Value else: Config = Value # set whole configuration if no key specified Config = Domoticz.Configuration(Config) except Exception as inst: Domoticz.Error("Domoticz.Configuration operation failed: '" + str(inst) + "'") return Config
def getConfigItemDB(Key=None, Default={}): Value = Default try: Config = Domoticz.Configuration() if (Key != None): Value = Config[Key] # only return requested key if there was one else: Value = Config # return the whole configuration if no key except KeyError: Value = Default except Exception as inst: Domoticz.Error('Domoticz.Configuration read failed: {}'.format(inst)) return Value
def getConfigItem(Key=None, Attribute="", Default={}): Value = Default try: Config = Domoticz.Configuration() Value = Config if Key is None else Config[Key] except KeyError: Value = Default except Exception as inst: Domoticz.Error( "getConfigItem - Domoticz.Configuration read failed: '" + str(inst) + "'" ) return repair_dict_after_load(Value, Attribute)
def setConfigItem(Key=None, Attribute="", Value=None): Config = {} if not isinstance(Value, (str, int, float, bool, bytes, bytearray, list, dict)): Domoticz.Error("setConfigItem - A value is specified of a not allowed type: '" + str(type(Value)) + "'") return Config if isinstance(Value, dict): # There is an issue that Configuration doesn't allow None value in dictionary ! # Replace none value to 'null' Value = prepare_dict_for_storage(Value, Attribute) try: Config = Domoticz.Configuration() if Key is None: Config = Value # set whole configuration if no key specified else: Config[Key] = Value Config = Domoticz.Configuration(Config) except Exception as inst: Domoticz.Error("setConfigItem - Domoticz.Configuration operation failed: '" + str(inst) + "'") return None return Config
def onStart(self): Domoticz.Debug("onStart called") #read out parameters for local connection self.ip_address = Parameters["Address"].strip() self.port_number = Parameters["Port"].strip() self.otp_code = Parameters['Mode1'] self.runCounter = int(Parameters['Mode2']) self.log_level = Parameters['Mode4'] self.account_password = Parameters['Mode3'] self.account_email = Parameters['Mode5'] self.machine_name = Parameters['Mode6'] if self.log_level == 'Debug': Domoticz.Debugging(2) DumpConfigToLog() if self.log_level == 'Verbose': Domoticz.Debugging(1 + 2 + 4 + 8 + 16 + 64) DumpConfigToLog() if self.log_level == 'Reset': Domoticz.Log( "Plugin config will be erased to retreive new cloud account data" ) Config = {} Config = Domoticz.Configuration(Config) #PureLink needs polling, get from config Domoticz.Heartbeat(10) self.checkVersion(self.version) mqtt_client_id = "" #create a Dyson account deviceList = self.get_device_names() if deviceList != None and len(deviceList) > 0: Domoticz.Debug( "Number of devices found in plugin configuration: '" + str(len(deviceList)) + "'") else: Domoticz.Log( "No devices found in plugin configuration, request from Dyson cloud account" ) #new authentication Domoticz.Debug( "=== start making connection to Dyson account, new method as of 2021 ===" ) dysonAccount2 = DysonAccount() challenge_id = getConfigItem(Key="challenge_id", Default="") setConfigItem(Key="challenge_id", Value="") #clear after use if challenge_id == "": #request otp code via email when no code entered challenge_id = dysonAccount2.login_email_otp( self.account_email, "NL") setConfigItem(Key="challenge_id", Value=challenge_id) Domoticz.Log( '==== An OTP verification code had been requested, please check email and paste code into plugin=====' ) return else: #verify the received code if len(self.otp_code) < 6: Domoticz.Error("invalid verification code supplied") return dysonAccount2.verify(self.otp_code, self.account_email, self.account_password, challenge_id) setConfigItem( Key="challenge_id", Value="") #reset challenge id as it is no longer valid Parameters['Mode1'] = "0" #reset the stored otp code #get list of devices info's deviceList = dysonAccount2.devices() deviceNames = list(deviceList.keys()) Domoticz.Log("Received new devices: " + str(deviceNames) + ", they will be stored in plugin configuration") i = 0 for device in deviceList: setConfigItem( Key="{0}.name".format(i), Value=deviceNames[i]) #store the name of the machine Domoticz.Debug('Key="{0}.name", Value = {1}'.format( i, deviceNames[i])) #store the name of the machine setConfigItem( Key="{0}.credential".format( deviceList[deviceNames[i]].name), Value=deviceList[ deviceNames[i]].credential) #store the credential Domoticz.Debug('Key="{0}.credential", Value = {1}'.format( deviceList[deviceNames[i]].name, deviceList[ deviceNames[i]].credential)) #store the credential setConfigItem( Key="{0}.serial".format( deviceList[deviceNames[i]].name), Value=deviceList[ deviceNames[i]].serial) #store the serial Domoticz.Debug('Key="{0}.serial", Value = {1}'.format( deviceList[deviceNames[i]].name, deviceList[deviceNames[i]].serial)) #store the serial setConfigItem(Key="{0}.product_type".format( deviceList[deviceNames[i]].name), Value=deviceList[deviceNames[i]].product_type ) #store the product_type Domoticz.Debug( 'Key="{0}.product_type" , Value = {1}'.format( deviceList[deviceNames[i]].name, deviceList[deviceNames[i]].product_type) ) #store the product_type i = i + 1 if deviceList == None or len(deviceList) < 1: Domoticz.Error( "No devices found in plugin configuration or Dyson cloud account" ) return else: Domoticz.Debug("Number of devices in plugin: '" + str(len(deviceList)) + "'") if deviceList != None and len(deviceList) > 0: if len(self.machine_name) > 0: if self.machine_name in deviceList: password, serialNumber, deviceType = self.get_device_config( self.machine_name) Domoticz.Debug( "password: {0}, serialNumber: {1}, deviceType: {2}". format(password, serialNumber, deviceType)) self.myDevice = DysonPureLinkDevice( password, serialNumber, deviceType, self.machine_name) else: Domoticz.Error( "The configured device name '" + self.machine_name + "' was not found in the cloud account. Available options: " + str(list(deviceList))) return elif len(deviceList) == 1: self.myDevice = deviceList[list(deviceList)[0]] Domoticz.Log( "1 device found in plugin, none configured, assuming we need this one: '" + self.myDevice.name + "'") else: #more than 1 device returned in cloud and no name configured, which the the plugin can't handle Domoticz.Error( "More than 1 device found in cloud account but no device name given to select. Select and filter one from available options: " + str(list(deviceList))) return #the Domoticz connection object takes username and pwd from the Parameters so write them back Parameters[ 'Username'] = self.myDevice.serial #take username from account Parameters[ 'Password'] = self.myDevice.password #override the default password with the one returned from the cloud else: Domoticz.Error("No usable credentials found") return #check, per device, if it is created. If not,create it Options = { "LevelActions": "|||", "LevelNames": "|OFF|ON|AUTO", "LevelOffHidden": "true", "SelectorStyle": "1" } if self.fanModeUnit not in Devices: Domoticz.Device(Name='Fan mode', Unit=self.fanModeUnit, TypeName="Selector Switch", Image=7, Options=Options).Create() if self.fanStateUnit not in Devices: Domoticz.Device(Name='Fan state', Unit=self.fanStateUnit, Type=244, Subtype=62, Image=7, Switchtype=0).Create() if self.heatStateUnit not in Devices: Domoticz.Device(Name='Heating state', Unit=self.heatStateUnit, Type=244, Subtype=62, Image=7, Switchtype=0).Create() if self.nightModeUnit not in Devices: Domoticz.Device(Name='Night mode', Unit=self.nightModeUnit, Type=244, Subtype=62, Switchtype=0, Image=9).Create() Options = { "LevelActions": "|||||||||||", "LevelNames": "OFF|1|2|3|4|5|6|7|8|9|10|AUTO", "LevelOffHidden": "false", "SelectorStyle": "1" } if self.fanSpeedUnit not in Devices: Domoticz.Device(Name='Fan speed', Unit=self.fanSpeedUnit, TypeName="Selector Switch", Image=7, Options=Options).Create() if self.fanOscillationUnit not in Devices: Domoticz.Device(Name='Oscilation mode', Unit=self.fanOscillationUnit, Type=244, Subtype=62, Image=7, Switchtype=0).Create() if self.standbyMonitoringUnit not in Devices: Domoticz.Device(Name='Standby monitor', Unit=self.standbyMonitoringUnit, Type=244, Subtype=62, Image=7, Switchtype=0).Create() if self.filterLifeUnit not in Devices: Options: {'Custom': '1;hrs'} Domoticz.Device(Name='Remaining filter life', Unit=self.filterLifeUnit, TypeName="Custom", Options=Options).Create() if self.resetFilterLifeUnit not in Devices: Domoticz.Device(Name='Reset filter: 0 hrs', Unit=self.resetFilterLifeUnit, TypeName="Switch", Image=9).Create() if self.tempHumUnit not in Devices: Domoticz.Device(Name='Temperature and Humidity', Unit=self.tempHumUnit, TypeName="Temp+Hum").Create() if self.volatileUnit not in Devices: Domoticz.Device(Name='Volatile organic', Unit=self.volatileUnit, TypeName="Air Quality").Create() if self.sleepTimeUnit not in Devices: Domoticz.Device(Name='Sleep timer', Unit=self.sleepTimeUnit, TypeName="Custom").Create() if self.particlesUnit not in Devices: Domoticz.Device(Name='Dust', Unit=self.particlesUnit, TypeName="Air Quality").Create() if self.qualityTargetUnit not in Devices: Options = { "LevelActions": "|||", "LevelNames": "|Normal|Sensitive (Medium)|Very Sensitive (High)|Off", "LevelOffHidden": "true", "SelectorStyle": "1" } Domoticz.Device(Name='Air quality setpoint', Unit=self.qualityTargetUnit, TypeName="Selector Switch", Image=7, Options=Options).Create() if self.particles2_5Unit not in Devices: Domoticz.Device(Name='Dust (PM 2,5)', Unit=self.particles2_5Unit, TypeName="Air Quality").Create() if self.particles10Unit not in Devices: Domoticz.Device(Name='Dust (PM 10)', Unit=self.particles10Unit, TypeName="Air Quality").Create() if self.particlesMatter25Unit not in Devices: Domoticz.Device(Name='Particles (PM 25)', Unit=self.particlesMatter25Unit, TypeName="Air Quality").Create() if self.particlesMatter10Unit not in Devices: Domoticz.Device(Name='Particles (PM 10)', Unit=self.particlesMatter10Unit, TypeName="Air Quality").Create() if self.fanModeAutoUnit not in Devices: Domoticz.Device(Name='Fan mode auto', Unit=self.fanModeAutoUnit, Type=244, Subtype=62, Image=7, Switchtype=0).Create() if self.fanFocusUnit not in Devices: Domoticz.Device(Name='Fan focus mode', Unit=self.fanFocusUnit, Type=244, Subtype=62, Image=7, Switchtype=0).Create() if self.nitrogenDioxideDensityUnit not in Devices: Domoticz.Device(Name='Nitrogen Dioxide Density (NOx)', Unit=self.nitrogenDioxideDensityUnit, TypeName="Air Quality").Create() if self.heatModeUnit not in Devices: Options = { "LevelActions": "||", "LevelNames": "|Off|Heating", "LevelOffHidden": "true", "SelectorStyle": "1" } Domoticz.Device(Name='Heat mode', Unit=self.heatModeUnit, TypeName="Selector Switch", Image=7, Options=Options).Create() if self.heatTargetUnit not in Devices: Domoticz.Device(Name='Heat target', Unit=self.heatTargetUnit, Type=242, Subtype=1).Create() if self.deviceStatusUnit not in Devices: Domoticz.Device(Name='Machine status', Unit=self.deviceStatusUnit, TypeName="Text", Image=7).Create() Domoticz.Log("Device instance created: " + str(self.myDevice)) self.base_topic = self.myDevice.device_base_topic Domoticz.Debug("base topic defined: '" + self.base_topic + "'") #create the connection if self.myDevice != None: self.mqttClient = MqttClient(self.ip_address, self.port_number, mqtt_client_id, self.onMQTTConnected, self.onMQTTDisconnected, self.onMQTTPublish, self.onMQTTSubscribed)