class Tasmota(AliceSkill): """ Author: Psychokiller1888 Description: This skill allows you to not only connect tasmota esp devices, but listen to them """ def __init__(self): self._initializingSkill = False self._confArray = [] self._tasmotaConfigs = None super().__init__() @MqttHandler('projectalice/devices/tasmota/feedback/hello/+') def connectingHandler(self, session: DialogSession): identifier = session.intentName.split('/')[-1] if self.DeviceManager.getDeviceByUID(identifier): # This device is known self.logInfo(f'A device just connected in {session.siteId}') self.DeviceManager.deviceConnecting(uid=identifier) else: # We did not ask Alice to add a new device if not self.DeviceManager.broadcastFlag.isSet(): self.logWarning( 'A device is trying to connect to Alice but is unknown') @MqttHandler('projectalice/devices/tasmota/feedback/+') def feedbackHandler(self, session: DialogSession): siteId = session.siteId payload = session.payload feedback = payload.get('feedback') if not feedback: return deviceType = payload['deviceType'] if deviceType == 'switch': if feedback > 0: self.SkillManager.skillBroadcast('onButtonPressed', siteId=siteId) else: self.SkillManager.skillBroadcast('onButtonReleased', siteId=siteId) elif deviceType == 'pir': if feedback > 0: self.SkillManager.skillBroadcast('onMotionDetected', siteId=siteId) else: self.SkillManager.skillBroadcast('onMotionStopped', siteId=siteId) def _initConf(self, identifier: str, deviceBrand: str, deviceType: str): self._tasmotaConfigs = TasmotaConfigs(deviceType, identifier) self._confArray = self._tasmotaConfigs.getConfigs( deviceBrand, self.DeviceManager.broadcastRoom)
def _initConf(self, identifier: str, deviceBrand: str, deviceType: str): self._tasmotaConfigs = TasmotaConfigs(deviceType, identifier) self._confArray = self._tasmotaConfigs.getConfigs( deviceBrand, self.DeviceManager.broadcastRoom)
class Tasmota(Module): """ Author: Psychokiller1888 Description: This module allows you to not only connect tasmota esp devices, but listen to them """ _CONNECTING = 'projectalice/devices/tasmota/feedback/hello/+' _FEEDBACK = 'projectalice/devices/tasmota/feedback/+' def __init__(self): self._SUPPORTED_INTENTS = [self._FEEDBACK, self._CONNECTING] self._connectingRegex = re.compile( self._CONNECTING.replace('+', '(.*)')) self._feedbackRegex = re.compile(self._FEEDBACK.replace('+', '(.*)')) self._initializingModule = False self._confArray = [] self._tasmotaConfigs = None super().__init__(self._SUPPORTED_INTENTS) def filterIntent(self, intent: str, session: DialogSession) -> bool: if intent.startswith('projectalice/devices/tasmota/'): return True return super().filterIntent(intent=intent, session=session) def onMessage(self, intent: str, session: DialogSession) -> bool: siteId = session.siteId payload = session.payload if self._connectingRegex.match(intent): identifier = self._connectingRegex.match(intent).group(1) if self.DeviceManager.getDeviceByUID(identifier): # This device is known self.logInfo(f'A device just connected in {siteId}') self.DeviceManager.deviceConnecting(uid=identifier) else: # We did not ask Alice to add a new device if not self.DeviceManager.broadcastFlag.isSet(): self.logWarning( 'A device is trying to connect to Alice but is unknown' ) elif self._feedbackRegex.match(intent): if 'feedback' in payload: if payload['deviceType'] == 'switch': if payload['feedback'] > 0: self.ModuleManager.moduleBroadcast('onButtonPressed', args=[siteId]) else: self.ModuleManager.moduleBroadcast('onButtonReleased', args=[siteId]) elif payload['deviceType'] == 'pir': if payload['feedback'] > 0: self.ModuleManager.moduleBroadcast('onMotionDetected', args=[siteId]) else: self.ModuleManager.moduleBroadcast('onMotionStopped', args=[siteId]) return True def _initConf(self, identifier: str, deviceBrand: str, deviceType: str): self._tasmotaConfigs = TasmotaConfigs(deviceType, identifier) self._confArray = self._tasmotaConfigs.getConfigs( deviceBrand, self.DeviceManager.broadcastRoom)
def doFlashTasmota(self, room: str, espType: str, siteId: str): port = self.findUSBPort(timeout=60) if not port: self.MqttManager.say(text=self.TalkManager.randomTalk('noESPFound', skill='AliceCore'), client=siteId) self._broadcastFlag.clear() return self.MqttManager.say(text=self.TalkManager.randomTalk('usbDeviceFound', skill='AliceCore'), client=siteId) try: mac = ESPLoader.detect_chip(port=port, baud=115200).read_mac() mac = ':'.join([f'{x:02x}' for x in mac]) cmd = [ '--port', port, '--baud', '115200', '--after', 'no_reset', 'write_flash', '--flash_mode', 'dout', '0x00000', 'sonoff.bin', '--erase-all' ] esptool.main(cmd) except Exception as e: self.logError(f'Something went wrong flashing esp device: {e}') self.MqttManager.say(text=self.TalkManager.randomTalk('espFailed', skill='AliceCore'), client=siteId) self._broadcastFlag.clear() return self.logInfo('Tasmota flash done') self.MqttManager.say(text=self.TalkManager.randomTalk('espFlashedUnplugReplug', skill='AliceCore'), client=siteId) found = self.findUSBPort(timeout=60) if found: self.MqttManager.say(text=self.TalkManager.randomTalk('espFoundReadyForConf', skill='AliceCore'), client=siteId) time.sleep(10) uid = self._getFreeUID(mac) tasmotaConfigs = TasmotaConfigs(deviceType=espType, uid=uid) confs = tasmotaConfigs.getBacklogConfigs(room) if not confs: self.logError('Something went wrong getting tasmota configuration') self.MqttManager.say(text=self.TalkManager.randomTalk('espFailed', skill='AliceCore'), client=siteId) else: ser = serial.Serial() ser.baudrate = 115200 ser.port = port ser.open() try: for group in confs: cmd = ';'.join(group['cmds']) if len(group['cmds']) > 1: cmd = f'Backlog {cmd}' arr = list() if len(cmd) > 50: while len(cmd) > 50: arr.append(cmd[:50]) cmd = cmd[50:] arr.append(f'{cmd}\r\n') else: arr.append(f'{cmd}\r\n') for piece in arr: ser.write(piece.encode()) self.logInfo('Sent {}'.format(piece.replace('\r\n', ''))) time.sleep(0.5) time.sleep(group['waitAfter']) ser.close() self.logInfo('Tasmota flashing and configuring done') self.MqttManager.say(text=self.TalkManager.randomTalk('espFlashingDone', skill='AliceCore'), client=siteId) self.addNewDevice(espType, room, uid) self._broadcastFlag.clear() except Exception as e: self.logError(f'Something went wrong writting configuration to esp device: {e}') self.MqttManager.say(text=self.TalkManager.randomTalk('espFailed', skill='AliceCore'), client=siteId) self._broadcastFlag.clear() ser.close() else: self.MqttManager.say(text=self.TalkManager.randomTalk('espFailed', skill='AliceCore'), client=siteId) self._broadcastFlag.clear() return
def doFlashTasmota(self, room: str, espType: str, siteId: str): port = self.findUSBPort(timeout=60) if port: self.MqttManager.say(text=self.TalkManager.randomTalk( 'usbDeviceFound', module='AliceCore'), client=siteId) try: mac = ESPLoader.detect_chip(port=port, baud=115200).read_mac() mac = '%s' % (':'.join(map(lambda x: '%02x' % x, mac))) cmd = list() cmd.append('--port') cmd.append(port) cmd.append('--baud') cmd.append('115200') cmd.append('--after') cmd.append('no_reset') cmd.append('write_flash') cmd.append('--flash_mode') cmd.append('dout') cmd.append('0x00000') cmd.append('sonoff.bin') cmd.append('--erase-all') esptool.main(cmd) except Exception as e: self._logger.error( '[{}] Something went wrong flashing esp device: {}'.format( self.name, e)) self.MqttManager.say(text=self.TalkManager.randomTalk( 'espFailed', module='AliceCore'), client=siteId) self._broadcastFlag.clear() return else: self.MqttManager.say(text=self.TalkManager.randomTalk( 'noESPFound', module='AliceCore'), client=siteId) self._broadcastFlag.clear() return self._logger.info('[{}] Tasmota flash done'.format(self.name)) self.MqttManager.say(text=self.TalkManager.randomTalk( 'espFlashedUnplugReplug', module='AliceCore'), client=siteId) found = self.findUSBPort(timeout=60) if found: self.MqttManager.say(text=self.TalkManager.randomTalk( 'espFoundReadyForConf', module='AliceCore'), client=siteId) time.sleep(10) uid = self._getFreeUID(mac) tasmotaConfigs = TasmotaConfigs(deviceType=espType, uid=uid) confs = tasmotaConfigs.getBacklogConfigs(room) if not confs: self._logger.error( '[{}] Something went wrong getting tasmota configuration'. format(self.name)) self.MqttManager.say(text=self.TalkManager.randomTalk( 'espFailed', module='AliceCore'), client=siteId) else: serial = Serial() serial.baudrate = 115200 serial.port = port serial.open() try: for group in confs: cmd = ';'.join(group['cmds']) if len(group['cmds']) > 1: cmd = 'Backlog {}'.format(cmd) arr = list() if len(cmd) > 50: while len(cmd) > 50: arr.append(cmd[:50]) cmd = cmd[50:] arr.append('{}\r\n'.format(cmd)) else: arr.append('{}\r\n'.format(cmd)) for piece in arr: serial.write(piece.encode()) self._logger.info('[{}] Sent {}'.format( self.name, piece.replace('\r\n', ''))) time.sleep(0.5) time.sleep(group['waitAfter']) serial.close() self._logger.info( '[{}] Tasmota flashing and configuring done'.format( self.name)) self.MqttManager.say(text=self.TalkManager.randomTalk( 'espFlashingDone', module='AliceCore'), client=siteId) self.addNewDevice(espType, room, uid) self._broadcastFlag.clear() except Exception as e: self._logger.error( '[{}] Something went wrong writting configuration to esp device: {}' .format(self.name, e)) self.MqttManager.say(text=self.TalkManager.randomTalk( 'espFailed', module='AliceCore'), client=siteId) self._broadcastFlag.clear() serial.close() else: self.MqttManager.say(text=self.TalkManager.randomTalk( 'espFailed', module='AliceCore'), client=siteId) self._broadcastFlag.clear() return