Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
 def _initConf(self, identifier: str, deviceBrand: str, deviceType: str):
     self._tasmotaConfigs = TasmotaConfigs(deviceType, identifier)
     self._confArray = self._tasmotaConfigs.getConfigs(
         deviceBrand, self.DeviceManager.broadcastRoom)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
	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
Ejemplo n.º 5
0
    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