def read(self, mac): result = {} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return if (mac in globals.KNOWN_DEVICES and globals.KNOWN_DEVICES[mac]['model'] == 'xiaomiht/xiaomiht_cleargrass'): Firm = bytearray(conn.readCharacteristic('0x2a')) else: Firm = bytearray(conn.readCharacteristic('0x24')) batt = bytearray(conn.readCharacteristic('0x18')) battery = batt[0] result['battery'] = battery firmware = "".join(map(chr, Firm)) result['firmware'] = firmware notification = Notification(conn, XiaomiHT) conn.writeCharacteristic('0x10', '0100', response=True) notification.subscribe(2) result['id'] = mac logging.debug('XIAOMIHT------' + str(result)) return result except Exception as e: logging.error(str(e)) return result
def read(self, mac): result = {} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return batteryFirm = bytearray(conn.readCharacteristic('0x38')) conn.writeCharacteristic('0x33', 'a01f', response=True) battery = batteryFirm[0] firmware = "".join(map(chr, batteryFirm[2:])) notification = Notification(conn, Miflora) conn.writeCharacteristic('0x36', '0100', response=True) result['battery'] = battery result['firmware'] = firmware result['id'] = mac received = bytearray(conn.readCharacteristic('0x35')) temperature = float(received[1] * 256 + received[0]) / 10 if temperature > 3276.8: temperature = 0 - (6553.6 - temperature) sunlight = received[4] * 256 + received[3] moisture = received[7] fertility = received[9] * 256 + received[8] result['sunlight'] = sunlight result['moisture'] = moisture result['fertility'] = fertility result['temperature'] = temperature result['source'] = globals.daemonname logging.debug(str(result)) globals.JEEDOM_COM.add_changes('devices::' + conn.mac, result) return result except Exception, e: logging.error(str(e))
def read(self,mac): result={} try: conn = Connector(mac) conn.connect(type='random') if not conn.isconnected: conn.connect(type='random') if not conn.isconnected: return battery = struct.unpack('2B',conn.readCharacteristic('0x2e')) temperature = struct.unpack('2B',conn.readCharacteristic('0x34')) humidity = struct.unpack('2B',conn.readCharacteristic('0x3c')) pression = struct.unpack('4B',conn.readCharacteristic('0x44')) temperature = int(str(hex(temperature[0])[2:].zfill(2) + hex(temperature[1])[2:].zfill(2)),16) humidity = int(str(hex(humidity[0])[2:].zfill(2) + hex(humidity[1])[2:].zfill(2)),16) logging.debug(str(pression)) pression = int(str(hex(pression[0])[2:].zfill(2) + hex(pression[1])[2:].zfill(2)+ hex(pression[2])[2:].zfill(2)+ hex(pression[3])[2:].zfill(2)),16) battery = int(str(hex(battery[0])[2:].zfill(2) + hex(battery[1])[2:].zfill(2)),16) result['temperature'] = float(temperature)/10 result['humidity'] = float(humidity)/10 result['pressure'] = float(pression)/100 result['batteryvoltage'] = round(float(battery)*0.00051029,2) if round(float(battery)*0.00051029,2) > 3: battery = 100 elif round(float(battery)*0.00051029,2) < 2: battery = 0 else: battery = round((float(battery)*0.00051029 - 2) *100,0) result['battery'] = battery except Exception,e: logging.error('HECTOR------'+str(e)) conn.disconnect()
def read(self, mac, connection=''): result = {} try: if mac in globals.KEEPED_CONNECTION: logging.debug('Already a connection for ' + mac + ' use it') conn = globals.KEEPED_CONNECTION[mac] else: if connection != '': conn = connection else: logging.debug('Creating a new connection for ' + mac) conn = Connector(mac) globals.KEEPED_CONNECTION[mac] = conn conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return refreshlist = globals.KNOWN_DEVICES[mac]['refreshlist'] logging.debug('Here is the list to refresh ' + str(refreshlist)) if 'color' in refreshlist: try: color = utils.tuple_to_hex( struct.unpack( '4B', conn.readCharacteristic(refreshlist['color']))) if color[0:2] != '00': color = 'FFFFFF' else: color = color[2:] result['color'] = '#' + color except Exception, e: logging.debug(str(e)) if 'effect' in refreshlist: try: effect = utils.tuple_to_hex( struct.unpack( '8B', conn.readCharacteristic(refreshlist['effect']))) mode = effect[8:10] if mode == '04': result['mode'] = 'Bougie' elif mode == '01': result['mode'] = 'Fondu uni' elif mode == '00': result['mode'] = 'Flash uni' elif mode == '02': result['mode'] = 'Flash arc-en-ciel' elif mode == '03': result['mode'] = 'Fondu arc-en-ciel' else: result['mode'] = 'Aucun' speed = 255 - int(effect[12:14], 16) result['speed'] = speed except Exception, e: logging.debug(str(e))
def action(self,message): type ='' mac = message['device']['id'] handle = message['command']['handle'] value = message['command']['value'] if 'type' in message['command']: type = message['command']['type'] if mac in globals.KEEPED_CONNECTION: logging.debug('Already a connection for ' + mac + ' use it') conn = globals.KEEPED_CONNECTION[mac] else: logging.debug('Creating a new connection for ' + mac) conn = Connector(mac) globals.KEEPED_CONNECTION[mac]=conn conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return if type == 'speed': init = utils.tuple_to_hex(struct.unpack('8B',conn.readCharacteristic(handle))) speed = 255-int(value); if speed == 0: speed = 1 value = str(init)[0:12]+ hex(speed)[2:].zfill(2)+ str(init)[14:16] elif type == 'effect': init = utils.tuple_to_hex(struct.unpack('8B',conn.readCharacteristic(handle))) initcolor = utils.tuple_to_hex(struct.unpack('4B',conn.readCharacteristic(message['command']['color']))) value = str(initcolor) + value + '00' + str(init)[12:16] elif type == 'color': initeffect = utils.tuple_to_hex(struct.unpack('8B',conn.readCharacteristic(message['command']['effect']))) if str(initeffect)[8:10] == '04': valueprep = str(initeffect)[0:8] + 'ff' + '00' + str(initeffect)[12:16] result = conn.writeCharacteristic(message['command']['effect'],valueprep) if not result: conn.disconnect() logging.debug("Failed to write to device probably bad bluetooth connection") elif type == 'luminosity': value = utils.getTintedColor(message['command']['secondary'],value) arrayValue = [int('0x'+value[i:i+2],16) for i in range(0, len(value), 2)] result = conn.writeCharacteristic(handle,value) if not result: result = conn.writeCharacteristic(handle,value) if not result: logging.debug("Failed to write to device probably bad bluetooth connection") data={} data = self.read(mac,conn) if len(data)>2: data['source'] = globals.daemonname if type == 'luminosity': data['luminosity'] = luminosityvalue globals.JEEDOM_COM.add_changes('devices::'+mac,data) conn.disconnect() return
def read(self, mac): result = {} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return batteryDatas = bytearray(conn.readCharacteristic('0x2c')) if len(batteryDatas) == 10: battery = batteryDatas[0] status = batteryDatas[9] cycle = batteryDatas[7] + batteryDatas[8] year = str(batteryDatas[1] + 2000) month = str(batteryDatas[2] + 1) day = str(batteryDatas[3]) hour = str(batteryDatas[4]) minutes = str(batteryDatas[5]) seconds = str(batteryDatas[6]) if status == 1: status = 'Faible' elif status == 2: status = 'En charge' elif status == 3: status = 'Branché Full' elif status == 4: status = 'Débranché' else: status = 'Inconnu' result['battery'] = battery result['status'] = status result['cycle'] = cycle result[ 'lastcharge'] = day + '/' + month + '/' + year + ' ' + hour + 'h' + minutes + 'min' + seconds + 's' firmwareDatas = bytearray(conn.readCharacteristic('0x12')) firmware = str(firmwareDatas[15]) + '.' + str( firmwareDatas[14]) + '.' + str(firmwareDatas[13]) + '.' + str( firmwareDatas[12]) stepsDatas = conn.readCharacteristic('0x1d') steps = ord(stepsDatas[0]) + (ord(stepsDatas[1]) << 8) result['steps'] = steps result['firmware'] = firmware result['id'] = mac logging.debug(str(result)) conn.disconnect() return result except Exception as e: logging.error(str(e)) conn.disconnect() return result
def read(self, mac): result = {} try: conn = Connector(mac) conn.connect(type='random') if not conn.isconnected: conn.connect(type='random') if not conn.isconnected: return batteryDatas = bytearray( conn.readCharacteristic('0x43', type='random')) if len(batteryDatas) >= 11: battery = batteryDatas[1] status = batteryDatas[2] cycle = batteryDatas[7] + batteryDatas[8] year = str( int( str( hex(batteryDatas[12])[2:].zfill(2) + hex(batteryDatas[11])[2:].zfill(2)), 16)) month = str(batteryDatas[13]) day = str(batteryDatas[14]) hour = str(batteryDatas[15]) minutes = str(batteryDatas[16]) seconds = str(batteryDatas[17]) lastchargelevel = str(batteryDatas[19]) if status == 0: status = 'Débranché' elif status == 1: status = 'En charge' else: status = 'Inconnu' result['battery'] = battery result['status'] = status result['firmware'] = str( conn.readCharacteristic('0x10')) + '/' + str( conn.readCharacteristic('0x12')) result['lastchargelevel'] = lastchargelevel result[ 'lastcharge'] = day + '/' + month + '/' + year + ' ' + hour + 'h' + minutes + 'min' + seconds + 's' result['id'] = mac #conn.writeCharacteristic('0x51','0100',type='random') #notification = Notification(conn,Miband2,{'action':'write','handle':'0x3d','value':'02','type':'random'}) #notification.subscribe(10) #conn.writeCharacteristic('0x50', '0200',type='random') logging.debug(str(result)) except Exception, e: logging.error(str(e))
def read(self, mac, connection=''): if 'localname' in globals.KNOWN_DEVICES[mac.upper()]: # Make it works directly with devices paired by remote control (for testing) if globals.KNOWN_DEVICES[mac.upper()]['localname'].startswith( "R-"): self.mesh_name = globals.KNOWN_DEVICES[ mac.upper()]['localname'] self.mesh_password = P_DEFAULTPASSWORD if mac in globals.KEEPED_CONNECTION: logging.debug('Already a connection for ' + mac + ' use it') conn = globals.KEEPED_CONNECTION[mac] else: logging.debug('Creating a new connection for ' + mac) conn = Connector(mac) globals.KEEPED_CONNECTION[mac] = conn i = 1 authresult = False while i <= 2: i = i + 1 if not conn.isconnected: try: conn.connect(retry=1) except: pass if conn.isconnected: authresult = self.auth(conn) if authresult: break else: time.sleep(1) if not authresult: logging.debug( 'Ending action due to authentication error on device') globals.PENDING_ACTION = False return result # send message notification = Notification(conn, Awoxmesh, { 'mac': conn.mac, 'session': self.session_key }) notification.subscribe(timer=NOTIF_TIMEOUT, disconnect=False) conn.readCharacteristic(STATUS_CHAR_UUID) return {}
def read(self, mac): result = {} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return logging.debug('read batteryFirm') batteryFirm = bytearray(conn.readCharacteristic('0x18')) battery = batteryFirm[0] firmware = "".join(map(chr, batteryFirm[2:])) notification = Notification(conn, Mithermaff) logging.debug('write 0x10 0100 to get sensor values') conn.writeCharacteristic('0x10', '0100', response=True) notification.subscribe(2) result['battery'] = battery result['firmware'] = firmware result['id'] = mac logging.debug(str(result)) return result except Exception, e: logging.error(str(e))
def parse(self, data, mac, name): action = {} action['present'] = 1 action['version'] = 'awox' if mac.upper() not in globals.KNOWN_DEVICES and globals.LEARN_MODE: if name.lower() == P_DEFAULTNAME and self.auto_pairing: self.setMeshPairing(mac, name, self.mesh_name, self.mesh_password, self.mesh_longtermkey) if mac in globals.KEEPED_CONNECTION: conn = globals.KEEPED_CONNECTION[mac] else: conn = Connector(mac) conn.connect() char = conn.readCharacteristic(MODEL_UUID) conn.disconnect() logging.debug('Version is ' + char) if char.lower().startswith('EF'): action['version'] = 'awox' if char.lower().startswith('ERCUm'): action['version'] = 'awoxremote' if char.lower().startswith('ESMLm'): # ESMLm_c9 and ESMLm_c13 action['version'] = 'awox' return action
def action(self, message): logging.debug('toto') type = '' mac = message['device']['id'] handle = message['command']['handle'] value = message['command']['value'] if 'type' in message['command']: type = message['command']['type'] if mac in globals.KEEPED_CONNECTION: logging.debug('Already a connection for ' + mac + ' use it') conn = globals.KEEPED_CONNECTION[mac] else: logging.debug('Creating a new connection for ' + mac) conn = Connector(mac) globals.KEEPED_CONNECTION[mac] = conn conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return if type == 'pair': conn.writeCharacteristic('0x12', '4367' + self.key) time.sleep(5) if type == 'switch': conn.writeCharacteristic('0x12', '4367' + self.key) conn.writeCharacteristic(handle, value.ljust(36, '0')) if type == 'color': conn.writeCharacteristic('0x12', '4367' + self.key) if value == '000000': conn.writeCharacteristic(handle, ('434002').ljust(36, '0')) else: conn.writeCharacteristic(handle, ('4341' + value).ljust(36, '0')) if type == 'brightness': init = utils.tuple_to_hex( struct.unpack('18B', conn.readCharacteristic('0x12'))) conn.writeCharacteristic('0x12', '4367' + self.key) if str(init)[0:4] == '4343': logging.debug(str(init)[0:8]) conn.writeCharacteristic( handle, str(init)[0:8] + hex(int(value))[2:].zfill(2) + str(init)[10:36]) else: conn.writeCharacteristic( handle, str(init)[0:12] + hex(int(value))[2:].zfill(2) + str(init)[14:36]) if type == 'white': conn.writeCharacteristic('0x12', '4367' + self.key) logging.debug('4343' + (hex(int(value))[2:].zfill(4) + '00').ljust(36, '0')) conn.writeCharacteristic(handle, ('4343' + hex(int(value))[2:].zfill(4) + '00').ljust(36, '0')) conn.disconnect() return
def read(self, mac): result = {} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return #check pairing state first pairing = conn.readCharacteristic('0x3a') # check pairing state if pairing: #initiate pairing sequence conn.writeCharacteristic( '0x3a', '00', response=True) # set pairing state to 0 conn.writeCharacteristic('0x33', '0100', response=True) # tbd?? conn.writeCharacteristic('0x32', '00', response=True) # reset history days firmw = str(conn.readCharacteristic('0x18')) # get fw version name = str(conn.readCharacteristic('0x28')) # get name conn.writeCharacteristic('0x42', '0100', response=True) # tbd?? curdate = datetime.datetime.today().strftime('%y%m%d%H%M%S') conn.writeCharacteristic( '0x2b', binascii.hexlify(curdate), response=True) #set current time ascii: aammddhhmmss conn.writeCharacteristic('0x41', '00000000', response=True) conn.writeCharacteristic('0x42', '0000', response=True) # tbd?? notification = Notification(conn, BeeWiSmartDoor) logging.debug('BeeWi read firmw=' + str(firmw) + ' Name: ' + str(name)) notification.subscribe(2) else: battery = ord(conn.readCharacteristic('0x25')) result['battery'] = battery logging.debug('BeeWi read Battery=' + str(battery)) result['id'] = mac return result except Exception, e: logging.error(str(e))
def read(self, mac): logging.debug('read: ' + mac) result = {} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return result['sunlight'] = self.__convertSunlightData( conn.readCharacteristic( self.characteristicHandles['sunlight'])) result['soilec'] = self.__convertSoilECData( conn.readCharacteristic(self.characteristicHandles['soilec'])) result['soiltemp'] = self.__convertTempData( conn.readCharacteristic( self.characteristicHandles['soiltemp'])) result['airtemp'] = self.__convertTempData( conn.readCharacteristic(self.characteristicHandles['airtemp'])) result['soilmoisture'] = self.__convertSoilMoistureData( conn.readCharacteristic( self.characteristicHandles['soilmoisture'])) result['calibratedsoilmoisture'] = self.__convertFloatData( conn.readCharacteristic( self.characteristicHandles['calibratedsoilmoisture'])) result['calibratedairtemp'] = self.__convertFloatData( conn.readCharacteristic( self.characteristicHandles['calibratedairtemp'])) result['calibratedli'] = self.__convertFloatData( conn.readCharacteristic( self.characteristicHandles['calibratedli'])) result['color'] = self.__convertColorData( conn.readCharacteristic(self.characteristicHandles['color'])) result['battery'] = self.__convertBatteryData( conn.readCharacteristic(self.characteristicHandles['battery'])) result['id'] = mac logging.debug(str(result)) return result except Exception as e: logging.error(str(e)) return result
def read(self,mac): result={} try: conn = Connector(mac) conn.connect(type='random') if not conn.isconnected: conn.connect(type='random') if not conn.isconnected: return battery = struct.unpack('2B',conn.readCharacteristic('0x2e')) battery = int(str(hex(battery[0])[2:].zfill(2) + hex(battery[1])[2:].zfill(2)),16) temperature = struct.unpack('2B',conn.readCharacteristic('0x34')) temperature = int(str(hex(temperature[0])[2:].zfill(2) + hex(temperature[1])[2:].zfill(2)),16) humidity = struct.unpack('2B',conn.readCharacteristic('0x3c')) humidity = int(str(hex(humidity[0])[2:].zfill(2) + hex(humidity[1])[2:].zfill(2)),16) # If pression == Ox00014601 (83457) -> read again at least for 3 attempts # Hector's sensor seems to always return Ox00014601 at first read attempt pression = struct.unpack('4B',conn.readCharacteristic('0x44')) pression = int(str(hex(pression[0])[2:].zfill(2) + hex(pression[1])[2:].zfill(2)+ hex(pression[2])[2:].zfill(2)+ hex(pression[3])[2:].zfill(2)),16) pression_read = 0 while (pression <= 14601 and pression_read < 3): time.sleep(1) pression = struct.unpack('4B',conn.readCharacteristic('0x44')) pression = int(str(hex(pression[0])[2:].zfill(2) + hex(pression[1])[2:].zfill(2)+ hex(pression[2])[2:].zfill(2)+ hex(pression[3])[2:].zfill(2)),16) pression_read += 1 logging.debug(str(pression)) result['temperature'] = float(temperature)/10 result['humidity'] = float(humidity)/10 result['pressure'] = float(pression)/100 result['batteryvoltage'] = round(float(battery)*0.00051029,2) if round(float(battery)*0.00051029,2) > 3: battery = 100 elif round(float(battery)*0.00051029,2) < 2: battery = 0 else: battery = round((float(battery)*0.00051029 - 2) *100,0) result['battery'] = battery except Exception,e: logging.error('HECTOR------'+str(e)) conn.disconnect()
def read(self,mac): result={} try: conn = Connector(mac) conn.connect(type='random') if not conn.isconnected: conn.connect(type='random') if not conn.isconnected: return batteryDatas = bytearray(conn.readCharacteristic('0x47',type='random')) if len(batteryDatas) >= 11: battery = batteryDatas[1] status = batteryDatas[2] cycle = batteryDatas[7] + batteryDatas[8] year = str(int(str(hex(batteryDatas[12])[2:].zfill(2) + hex(batteryDatas[11])[2:].zfill(2)),16)) month = str(batteryDatas[13]) day = str(batteryDatas[14]) hour = str(batteryDatas[15]) minutes = str(batteryDatas[16]) seconds = str(batteryDatas[17]) lastchargelevel = str(batteryDatas[19]) if status == 0: status = 'Débranché' elif status ==1: status = 'En charge' else: status = 'Inconnu' result['battery'] = battery result['status'] = status result['firmware'] = str(conn.readCharacteristic('0x10'))+'/'+str(conn.readCharacteristic('0x12')) result['lastchargelevel'] = lastchargelevel result['lastcharge'] = day+'/'+month+'/'+year+' '+hour+'h'+minutes+'min'+seconds+'s' result['id'] = mac logging.debug(str(result)) except Exception as e: logging.error(str(e)) return result
def read(self, mac, connection=''): result = {} chars = [] try: if mac in globals.KEEPED_CONNECTION: logging.debug('Already a connection for ' + mac + ' use it') conn = globals.KEEPED_CONNECTION[mac] else: if connection != '': conn = connection else: logging.debug('Creating a new connection for ' + mac) conn = Connector(mac) conn.connect(type='random') if not conn.isconnected: return if (mac in globals.KNOWN_DEVICES): if ('specificconfiguration' in globals.KNOWN_DEVICES[mac] and len(globals.KNOWN_DEVICES[mac] ['specificconfiguration']) > 0): logging.debug('Already known handles ' + str( globals.KNOWN_DEVICES[mac]['specificconfiguration'])) chars = [ globals.KNOWN_DEVICES[mac]['specificconfiguration'] ['batteryhandle'] ] if chars == []: logging.debug('Not known handles searching') chars = self.findCharacteristics(mac, conn) globals.JEEDOM_COM.add_changes( 'devices::' + mac, { "id": mac, "specificconfiguration": { "batteryhandle": chars[0] } }) char = chars[0] batteryDatas = bytearray( conn.readCharacteristic(char, type='random')) logging.debug(str(batteryDatas)) result['battery'] = batteryDatas[0] result['id'] = mac logging.debug(str(result)) return result except Exception as e: logging.error(str(e)) conn.disconnect() conn.disconnect() return result
def parse(self, data, mac, name, manuf): action = {} action['present'] = 1 try: conn = Connector(mac) conn.connect() if not conn.isconnected: return notification = Notification(conn, KST1) conn.writeCharacteristic('0x2c', '0100', response=True) batteryData = (conn.readCharacteristic('0x3a')).hex() logging.debug(str(batteryData)) action['battery'] = int(batteryData, 16) notification.subscribe(20) except Exception as e: logging.error(str(e)) return action
def read(self, mac): result = {} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return batterytrame = conn.readCharacteristic('0x1b') logging.debug('GIGASET------Parsing data ' + batterytrame) battery = int(batterytrame.encode("hex"), 16) result['battery'] = battery result['present'] = 1 except Exception, e: logging.error(str(e)) conn.disconnect()
def read(self, mac): result = {} try: conn = Connector(mac) conn.connect(type='random') if not conn.isconnected: conn.connect(type='random') if not conn.isconnected: return batteryDatas = bytearray(conn.readCharacteristic('0x17'), type='random') result['battery'] = batteryDatas[0] result['id'] = mac logging.debug(str(result)) return result except Exception, e: logging.error(str(e)) conn.disconnect()
def read(self,mac): result={} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return batt = bytearray(conn.readCharacteristic('0x3a')) battery = batt[0] conn.writeCharacteristic('0x38','0100',response=True) conn.writeCharacteristic('0x46','f40100',response=True) notification = Notification(conn,Lywsd03) notification.subscribe(10) result['battery'] = battery result['id'] = mac logging.debug('LYWSD03------'+str(result)) return result except Exception as e: logging.error(str(e)) return result
def read(self, mac): result = {} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return Firm = bytearray(conn.readCharacteristic('0x24')) batt = bytearray(conn.readCharacteristic('0x18')) battery = batt[0] firmware = "".join(map(chr, Firm)) notification = Notification(conn, XiaomiHT) conn.writeCharacteristic('0x10', '0100', response=True) notification.subscribe(2) result['battery'] = battery result['firmware'] = firmware result['id'] = mac logging.debug('XIAOMIHT------' + str(result)) return result except Exception, e: logging.error(str(e))
def read(self,mac): result={} try: conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return batteryFirm = bytearray(conn.readCharacteristic('0x38')) conn.writeCharacteristic('0x33','a01f',response=True) battery = batteryFirm[0] firmware = "".join(map(chr, batteryFirm[2:])) notification = Notification(conn,Miflora) conn.writeCharacteristic('0x36','0100',response=True) notification.subscribe(2) result['battery'] = battery result['firmware'] = firmware result['id'] = mac logging.debug(str(result)) return result except Exception,e: logging.error(str(e))
def setMeshPairing(self, mac, localname, new_mesh_name, new_mesh_password, new_mesh_long_term_key): if mac in globals.KEEPED_CONNECTION: conn = globals.KEEPED_CONNECTION[mac] else: conn = Connector(mac) conn.connect() defaultmeshname = localname.encode() is_a_remote = False char = conn.readCharacteristic(MODEL_UUID) if char.lower() == 'ERCUm': #if this is a remote is_a_remote = True logging.info( "[Unpaired device] Remote detected, trying with name " + defaultmeshname) if defaultmeshname == self.mesh_name: logging.info( "Device already paired to Jeedom. Do a reset of the device beforehand" ) else: session_random = urandom(8) message = make_pair_packet(defaultmeshname, P_DEFAULTPASSWORD, session_random) conn.writeCharacteristic(PAIR_CHAR_UUID, message) conn.writeCharacteristic(STATUS_CHAR_UUID, '01') reply = bytearray(conn.readCharacteristic(PAIR_CHAR_UUID)) if reply[0] == 0xd: logging.info( "[Unpaired device] Connected (Auth OK with default password)." ) session_key = make_session_key(defaultmeshname, P_DEFAULTPASSWORD, session_random, reply[1:9]) else: if reply[0] == 0xe: logging.info( "[Unpaired device] Auth error : check name and password or make sure device is unpaired." ) else: logging.info( '[Unpaired device] Error while trying to auth..') return False logging.info('Step 1 - Mesh Name : ' + new_mesh_name.encode()) message = encrypt(session_key, new_mesh_name.encode()) message.insert(0, 0x4) conn.writeCharacteristic(PAIR_CHAR_UUID, "".join("%02x" % b for b in message)) logging.info('Step 2 - Mesh Password : '******'Step 3 - LongtermKey : ' + new_mesh_long_term_key.encode()) message = encrypt(session_key, new_mesh_long_term_key.encode()) message.insert(0, 0x6) conn.writeCharacteristic(PAIR_CHAR_UUID, "".join("%02x" % b for b in message)) time.sleep(2) logging.info('Step 4 - Get Confirmation') reply = bytearray(conn.readCharacteristic(PAIR_CHAR_UUID)) if reply[0] == 0x7: self.mesh_name = new_mesh_name.encode() self.mesh_password = new_mesh_password.encode() logging.info("Mesh network settings accepted.") else: logging.info("Mesh network settings change failed : %s", repr(reply)) time.sleep(2) if not is_a_remote and self.auth(conn): logging.info('Step 5 - Set a default group') self.setGroupId(conn, P_DEFAULTGROUP, delete=False) time.sleep(1) value = '0407ed3c' # green data = value.decode("hex") self.sendAction(conn, C_COLOR, data) conn.disconnect() return True
def action(self, message): #logging.debug('Doing Awox action') result = {} ret = True mac = message['device']['id'] result['id'] = mac globals.PENDING_ACTION = True localname = '' if 'localname' in message['device']: localname = message['device']['localname'] # Make it works directly with devices paired by remote control (for testing) if localname.startswith("R-"): self.mesh_name = localname self.mesh_password = P_DEFAULTPASSWORD handle = '' value = '0' cmd = '' if 'handle' in message['command']: handle = message['command']['handle'] if 'value' in message['command']: value = message['command']['value'] if '$' in value: # manage injection of cmd/group in value (ex : gp$value or cmd$gp$value) s = value.split('$') if len(s) == 2: # only group message['command']['gp'] = s[0] value = s[1] elif len(s) == 3: # command and group message['command']['cmd'] = s[0] message['command']['gp'] = s[1] value = s[2] else: logging.info('Incorrect parameter (' + message['command']['value'] + '). Format: [[cmd$]gp$]value') if 'cmd' in message['command']: cmd = message['command']['cmd'] if 'gp' in message['command']: self.mesh_id = int(message['command']['gp']) + 32768 if 'target' in message['command']: self.mesh_id = int(message['command']['target']) if cmd != '': logging.debug('Running action ' + cmd) # case of new pairing will work only if unpaired if cmd == 'setNewPairing' or cmd == 'firstInit': self.mesh_name = P_JEEDOM_MESHNAME self.mesh_password = P_JEEDOM_MESHPASSWORD ret = self.setMeshPairing(mac, localname, self.mesh_name, self.mesh_password, self.mesh_longtermkey) time.sleep(3) message['command']['cmd'] = "status" self.action(message) return if mac in globals.KEEPED_CONNECTION: logging.debug('Already a connection for ' + mac + ' use it') conn = globals.KEEPED_CONNECTION[mac] else: logging.debug('Creating a new connection for ' + mac) conn = Connector(mac) globals.KEEPED_CONNECTION[mac] = conn i = 1 authresult = False while i <= 3: i = i + 1 if not conn.isconnected: try: conn.connect(retry=1) except: pass if conn.isconnected: authresult = self.auth(conn) if authresult: break else: time.sleep(0.5) if not authresult: logging.debug( 'Ending action due to authentication error on device') globals.PENDING_ACTION = False return if cmd == 'power': data = struct.pack('B', int(value)) self.sendAction(conn, C_POWER, data) elif cmd == 'resetMesh': self.resetMesh(conn) elif cmd == 'setMeshId': self.setMeshId(conn, int(value)) elif cmd == 'addMeshGroup': self.setGroupId(conn, int(value), delete=False) elif cmd == 'delMeshGroup': self.setGroupId(conn, int(value), delete=True) elif cmd == 'setWhiteHex': # temperature + brightness (hex) data = value[:2].decode("hex") self.sendAction(conn, C_WHITE_TEMPERATURE, data, False) data = value[-2:].decode("hex") self.sendAction(conn, C_WHITE_BRIGHTNESS, data) elif cmd == 'setWhite': # temperature-brightness (value 0 to 100) data = value.split('-') result['whitetemperature'] = data[0] result['whitebrightness'] = data[1] temp = struct.pack('B', int(int(data[0]) * 127 / 100)) brightness = struct.pack('B', int(int(data[1]) * 127 / 100)) self.sendAction(conn, C_WHITE_TEMPERATURE, temp, False) self.sendAction(conn, C_WHITE_BRIGHTNESS, brightness) elif cmd == 'setWhiteTemperature': # temperature from 1 to 100) result['whitetemperature'] = value data = struct.pack('B', int(int(value) * 127 / 100)) self.sendAction(conn, C_WHITE_TEMPERATURE, data) elif cmd == 'setWhiteBrightness': # brightness (hex) #data = value.decode("hex") result['whitebrightness'] = value data = struct.pack('B', int(int(value) * 127 / 100)) self.sendAction(conn, C_WHITE_BRIGHTNESS, data) elif cmd == 'setColor': # red + green + blue (hex) result['color'] = value value = '04' + value.replace("#", "") data = value.decode("hex") self.sendAction(conn, C_COLOR, data) elif cmd == 'setColorLight': # color(#hex)-brightness(0-100) data = value.split('-') result['color'] = data[0] result['colorbrightness'] = data[1] color = '04' + data[0].replace("#", "") brightness = struct.pack('B', int(int(data[1]) * 64 / 100)) self.sendAction(conn, C_COLOR, color.decode("hex"), False) self.sendAction(conn, C_COLOR_BRIGHTNESS, brightness) elif cmd == 'setColorBrightness': # a value between 0xa and 0x64 result['colorbrightness'] = value data = struct.pack('B', int(int(value) * 64 / 100)) self.sendAction(conn, C_COLOR_BRIGHTNESS, data) elif cmd == 'setSequence': # number between 0 and 6 data = struct.pack('B', int(value)) ret = self.sendAction(conn, C_PRESET, data) elif cmd == 'setSequenceColorDuration': # duration: in milliseconds. data = struct.pack("<I", int(value)) ret = self.sendAction(conn, C_SEQUENCE_COLOR_DURATION, data) elif cmd == 'setSequenceFadeDuration': # duration: in milliseconds. data = struct.pack("<I", int(value)) ret = self.sendAction(conn, C_SEQUENCE_FADE_DURATION, data) elif cmd == 'playScenario': # color/white/power&duration|color/white/power&duration|...|X (number of iteration for last value) # ex: #DF0101-100&5|100-100&7|50-50&10|0&5|1&0|3 self.playScenario(conn, value) elif cmd == 'setLightMode': # does nothing # duration: in milliseconds. data = struct.pack("B", int(value)) ret = self.sendAction(conn, C_LIGHT_MODE, data) elif cmd == 'status': notification = Notification(conn, Awoxmesh, { 'mac': conn.mac, 'session': self.session_key }) notification.subscribe(timer=NOTIF_TIMEOUT, disconnect=False) conn.readCharacteristic(STATUS_CHAR_UUID) else: data = value.decode("hex") handle = int(handle, 16) self.sendAction(conn, handle, data) logging.info('Value ' + value + ' sent to controller') globals.PENDING_ACTION = False # prepare results if ret: if cmd == 'power': result['status'] = int(value) elif cmd == 'setWhite' or cmd == 'setWhiteHex' or cmd == 'setWhiteTemperature' or cmd == 'setWhiteBrightness': result['mode'] = 1 result['modestring'] = "Blanc" result['status'] = 1 elif cmd == 'setColor' or cmd == 'setColorLight' or cmd == 'setColorBrightness': result['mode'] = 3 result['modestring'] = "Couleur" result['status'] = 1 elif cmd == 'setSequence': result['mode'] = 7 result['modestring'] = "Sequence" result['status'] = 1 else: # other command for which we are unsure of the result return logging.debug('Action returned status before notification') else: # request somehow failed return return result
def read(self, mac, connection=''): result = {} chars = [] try: if mac in globals.KEEPED_CONNECTION: logging.debug('Already a connection for ' + mac + ' use it') conn = globals.KEEPED_CONNECTION[mac] else: if connection != '': conn = connection else: logging.debug('Creating a new connection for ' + mac) conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return if (mac in globals.KNOWN_DEVICES): if ('specificconfiguration' in globals.KNOWN_DEVICES[mac] and len(globals.KNOWN_DEVICES[mac] ['specificconfiguration']) > 0): logging.debug('Already known handles ' + str( globals.KNOWN_DEVICES[mac]['specificconfiguration'])) chars = [ globals.KNOWN_DEVICES[mac]['specificconfiguration'] ['colorhandle'], globals.KNOWN_DEVICES[mac] ['specificconfiguration']['effecthandle'] ] if chars == []: logging.debug('Not known handles searching') chars = self.findCharacteristics(mac, conn) globals.JEEDOM_COM.add_changes( 'devices::' + mac, { "id": mac, "specificconfiguration": { "colorhandle": chars[0], "effecthandle": chars[1] } }) char = chars[0] refreshlist = globals.KNOWN_DEVICES[mac]['refreshlist'] logging.debug('Here is the list to refresh ' + str(refreshlist)) if 'color' in refreshlist: try: color = utils.tuple_to_hex( struct.unpack('4B', conn.readCharacteristic(chars[0]))) if color[0:2] != '00': color = 'FFFFFF' else: color = color[2:] result['color'] = '#' + color except Exception as e: logging.debug(str(e)) if 'effect' in refreshlist: try: effect = utils.tuple_to_hex( struct.unpack('8B', conn.readCharacteristic(chars[1]))) mode = effect[8:10] if mode == '04': result['mode'] = 'Bougie' elif mode == '01': result['mode'] = 'Fondu uni' elif mode == '00': result['mode'] = 'Flash uni' elif mode == '02': result['mode'] = 'Flash arc-en-ciel' elif mode == '03': result['mode'] = 'Fondu arc-en-ciel' else: result['mode'] = 'Aucun' speed = 255 - int(effect[12:14], 16) result['speed'] = speed except Exception as e: logging.debug(str(e)) if 'battery' in refreshlist: try: if 'hasbatteryinfo' in refreshlist and refreshlist[ 'hasbatteryinfo'] == 1: battery = struct.unpack( '2B', conn.readCharacteristic(refreshlist['battery'])) else: battery = struct.unpack( '1B', conn.readCharacteristic(refreshlist['battery'])) result['battery'] = battery[0] if 'hasbatteryinfo' in refreshlist and refreshlist[ 'hasbatteryinfo'] == 1: if battery[1]: result['mode'] = result['mode'] + ' (En charge)' else: result['mode'] = result['mode'] + ' (En décharge)' except Exception as e: logging.debug(str(e)) except Exception as e: logging.debug(str(e)) conn.disconnect() return logging.debug(str(result)) conn.disconnect() result['id'] = mac return result
def action(self, message): type = '' mac = message['device']['id'] value = message['command']['value'] chars = [] if 'type' in message['command']: type = message['command']['type'] if mac in globals.KEEPED_CONNECTION: logging.debug('Already a connection for ' + mac + ' use it') conn = globals.KEEPED_CONNECTION[mac] else: logging.debug('Creating a new connection for ' + mac) conn = Connector(mac) conn.connect() if not conn.isconnected: conn.connect() if not conn.isconnected: return if (mac.upper() in globals.KNOWN_DEVICES): if ('specificconfiguration' in globals.KNOWN_DEVICES[mac.upper()] and len(globals.KNOWN_DEVICES[mac.upper()] ['specificconfiguration']) > 0): logging.debug('Already known handles ' + str(globals.KNOWN_DEVICES[mac.upper()] ['specificconfiguration'])) chars = [ globals.KNOWN_DEVICES[mac.upper()]['specificconfiguration'] ['colorhandle'], globals.KNOWN_DEVICES[ mac.upper()]['specificconfiguration']['effecthandle'] ] if chars == []: logging.debug('Not known handles searching') chars = self.findCharacteristics(mac, conn) globals.JEEDOM_COM.add_changes( 'devices::' + mac, { "id": mac, "specificconfiguration": { "colorhandle": chars[0], "effecthandle": chars[1] } }) char = chars[0] if type == 'speed': char = chars[1] init = utils.tuple_to_hex( struct.unpack('8B', conn.readCharacteristic(chars[1]))) speed = 255 - int(value) if speed == 0: speed = 1 value = str(init)[0:12] + hex(speed)[2:].zfill(2) + str( init)[14:16] elif type == 'effect': char = chars[1] init = utils.tuple_to_hex( struct.unpack('8B', conn.readCharacteristic(chars[1]))) initcolor = utils.tuple_to_hex( struct.unpack('4B', conn.readCharacteristic(chars[0]))) value = str(initcolor) + value + '00' + str(init)[12:16] elif type == 'color': char = chars[0] initeffect = utils.tuple_to_hex( struct.unpack('8B', conn.readCharacteristic(chars[1]))) if str(initeffect)[8:10] == '04': valueprep = str(initeffect)[0:8] + 'ff' + '00' + str( initeffect)[12:16] result = conn.writeCharacteristic(chars[1], valueprep) if not result: conn.disconnect() logging.debug( "Failed to write to device probably bad bluetooth connection" ) elif type == 'luminosity': value = utils.getTintedColor(message['command']['secondary'], value) arrayValue = [ int('0x' + value[i:i + 2], 16) for i in range(0, len(value), 2) ] result = conn.writeCharacteristic(char, value) if not result: result = conn.writeCharacteristic(char, value) if not result: logging.debug( "Failed to write to device probably bad bluetooth connection" ) data = {} data = self.read(mac, conn) if len(data) > 2: data['source'] = globals.daemonname if type == 'luminosity': data['luminosity'] = luminosityvalue globals.JEEDOM_COM.add_changes('devices::' + mac, data) conn.disconnect() return