示例#1
0
    def __init__(self, mainClass):
        self._logger = logging.getLogger('SnipsLedControl')
        self._logger.info('Initializing leds controller')

        self._mainClass = mainClass  # type: SnipsLedControl

        if self.INSTANCE is None:
            self.INSTANCE = self
        else:
            self._logger.fatal(
                'Trying to instanciate LedsController but instance already exists'
            )
            self._mainClass.onStop()

        self._params = self._mainClass.params
        self._hardware = self._mainClass.hardware
        self._interface = None
        self._running = False
        self._active = True if self._params.defaultState == 'on' else False

        if self._params.pattern == 'google':
            self._pattern = GoogleHomeLedPattern(self)
        elif self._params.pattern == 'alexa':
            self._pattern = AlexaLedPattern(self)
        else:
            self._pattern = CustomLedPattern(self)

        if not self.initHardware():
            self._logger.fatal("Couldn't start hardware")
            self._mainClass.onStop()
            return

        self._queue = Queue.Queue()
        self._thread = threading.Thread(target=self._run)
        self._thread.daemon = True
示例#2
0
	def __init__(self, mainClass):
		self._logger = logging.getLogger('SnipsLedControl')
		self._logger.info('Initializing leds controller')

		self._mainClass = mainClass # type: SnipsLedControl

		if self.INSTANCE is None:
			self.INSTANCE = self
		else:
			self._logger.fatal('Trying to instanciate LedsController but instance already exists')
			self._mainClass.onStop()

		self._params 			= self._mainClass.params
		self._hardware 			= self._mainClass.hardware
		self._interface 		= None
		self._running 			= False
		self._defaultBrightness = self._params.defaultBrightness

		self._active = threading.Event()
		if self._params.defaultState == 'on':
			self._active.set()
		else:
			self._active.clear()


		if self._params.pattern == 'google':
			self._pattern = GoogleHomeLedPattern(self)
		elif self._params.pattern == 'alexa':
			self._pattern = AlexaLedPattern(self)
		elif self._params.pattern == 'kiboost':
			self._pattern = KiboostLedPattern(self)
		else:
			self._pattern = CustomLedPattern(self)


		if not self.initHardware():
			self._logger.fatal("Couldn't start hardware")
			self._mainClass.onStop()
			return


		self._buttonsThread = None
		if 'extras' in self._hardware and 'buttons' in self.hardware['extras']:
			import RPi.GPIO
			RPi.GPIO.setmode(RPi.GPIO.BCM)
			for button in self._hardware['extras']['buttons']:
				RPi.GPIO.setup(int(self._hardware['extras']['buttons'][button]['bcm_gpio']), RPi.GPIO.IN)

			self._buttonsThread = threading.Thread(target=self._runButtons)
			self._buttonsThread.setDaemon(True)


		self._queue = Queue.Queue()
		self._animationThread = threading.Thread(target=self._runAnimation)
		self._animationThread.setDaemon(True)
示例#3
0
class LedsController:
    INSTANCE = None

    def __init__(self, mainClass):
        self._logger = logging.getLogger('HermesLedControl')
        self._logger.info('Initializing leds controller')

        self._mainClass = mainClass  # type: HermesLedControl

        if self.INSTANCE is None:
            self.INSTANCE = self
        else:
            self._logger.fatal(
                'Trying to instanciate LedsController but instance already exists'
            )
            self._mainClass.onStop()

        self._params = self._mainClass.params
        self._hardware = self._mainClass.hardware
        self._interface = None
        self._running = False
        self._defaultBrightness = self._params.defaultBrightness
        self._stickyAnimation = None
        self._runningRequestId = None

        if not self._params.enableDoA and 'doa' in self._hardware:
            self._hardware['doa'] = False

        self._active = threading.Event()
        if self._params.defaultState == 'on':
            self._active.set()
        else:
            self._active.clear()

        if not self.initHardware():
            self._logger.fatal("Couldn't start hardware")
            self._mainClass.onStop()
            return

        if self._params.pattern == 'google':
            self._pattern = GoogleHomeLedPattern(self)
        elif self._params.pattern == 'alexa':
            self._pattern = AlexaLedPattern(self)
        elif self._params.pattern == 'kiboost':
            self._pattern = KiboostLedPattern(self)
        elif self._params.pattern == 'projectalice':
            self._pattern = ProjectAlicePattern(self)
        elif self._params.pattern == 'pgas':
            self._pattern = PgasPattern(self)
        else:
            self._pattern = CustomLedPattern(self)

        self._buttonsThread = None
        if 'extras' in self._hardware and 'buttons' in self.hardware['extras']:
            import RPi.GPIO
            RPi.GPIO.setmode(RPi.GPIO.BCM)
            for button in self._hardware['extras']['buttons']:
                RPi.GPIO.setup(
                    int(self._hardware['extras']['buttons'][button]
                        ['bcm_gpio']), RPi.GPIO.IN)

            self._buttonsThread = threading.Thread(target=self._runButtons)
            self._buttonsThread.setDaemon(True)

        self._timeout = 0
        if self._params.timeout and self._params.timeout > 0:
            self._timeout = self._params.timeout

        self._queue = Queue.Queue()
        self._animationThread = threading.Thread(target=self._runAnimation)
        self._animationThread.setDaemon(True)

    @property
    def stickyAnimation(self):
        return self._stickyAnimation

    @stickyAnimation.setter
    def stickyAnimation(self, value):
        self._stickyAnimation = value

    @property
    def active(self):
        return self._active.isSet()

    @property
    def hardware(self):
        return self._hardware

    @property
    def defaultBrightness(self):
        return self._defaultBrightness

    @property
    def interface(self):
        return self._interface

    @property
    def pattern(self):
        return self._pattern

    def initHardware(self):
        try:
            if self._hardware['interface'] == Interfaces.APA102:
                from interfaces.apa102 import APA102
                self._interface = APA102(hardware=self._hardware,
                                         endFrame=self._hardware['endFrame'])

            elif self._hardware['interface'] == Interfaces.NEOPIXELS:
                from interfaces.neopixels import Neopixels
                self._interface = Neopixels(
                    numLeds=self._hardware['numberOfLeds'],
                    stripType=self._hardware['type'],
                    pin=self._hardware['gpioPin'])

            elif self._hardware[
                    'interface'] == Interfaces.RESPEAKER_MIC_ARRAY_V2:
                from interfaces.respeakerMicArrayV2 import RespeakerMicArrayV2
                self._interface = RespeakerMicArrayV2(
                    hardware=self._hardware,
                    vid=self._hardware['vid'],
                    pid=self._hardware['pid'])

            elif self._hardware[
                    'interface'] == Interfaces.RESPEAKER_MIC_ARRAY_V1:
                from interfaces.respeakerMicArrayV1 import RespeakerMicArrayV1
                self._interface = RespeakerMicArrayV1(
                    hardware=self._hardware,
                    vid=self._hardware['vid'],
                    pid=self._hardware['pid'])

            elif self._hardware['interface'] == Interfaces.MATRIX_VOICE:
                from interfaces.matrixvoice import MatrixVoice
                self._interface = MatrixVoice(
                    numLeds=self._hardware['numberOfLeds'])

            elif self._hardware['interface'] == Interfaces.PURE_GPIO:
                from interfaces.pureGPIO import PureGPIO
                self._interface = PureGPIO(
                    numLeds=self._hardware['numberOfLeds'],
                    pinout=self._hardware['gpios'],
                    activeHigh=self._hardware['activeHigh'])

            if self._interface is None:
                return False
            else:
                return True
        except InterfaceInitError as e:
            self._logger.error('{}'.format(e))
            return False

    def setVolume(self, volume):
        """
		Some hardware such as respeaker mic array have onboard volume control that can be set
		:type volume: int
		:return:
		"""
        if 'extras' in self._hardware and 'volume' in self._hardware['extras']:
            try:
                minVol = self._hardware['extras']['volume']['min']
                maxVol = self._hardware['extras']['volume']['max']
                volume = max(min(volume, maxVol), minVol)
                if self._interface is not None:
                    self._interface.setVolume(volume)
            except:
                self._logger.error(
                    'Missing or wrong configuration for volume setting')
        else:
            self._logger.warning(
                'Tried to set volume on an unsupported device')

    def setVadLed(self, state):
        """
		Some hardware such as respeaker mic array have onboard vad led
		:type state: int (0-1)
		:return:
		"""
        if 'extras' in self._hardware and 'vadLed' in self._hardware['extras']:
            try:
                if self._interface is not None:
                    self._interface.setVadLed(state)
            except:
                self._logger.error('Missing or wrong vad led setting')
        else:
            self._logger.warning(
                'Tried to set vad led on an unsupported device')

    def putStickyPattern(self,
                         pattern,
                         patternMethod=None,
                         sticky: bool = False,
                         flush: bool = False,
                         duration: int = 0,
                         **kwargs):
        if sticky:
            self._stickyAnimation = {
                "func": pattern,
                "args": kwargs,
                "duration": duration
            }

        if patternMethod is None:
            self._put(pattern, flush=flush, duration=duration, **kwargs)
        else:
            try:
                func = getattr(self._pattern, patternMethod)
                self._put(func, flush=flush, duration=duration, **kwargs)
            except AttributeError:
                self._logger.error(
                    "Can't find {} method in pattern".format(patternMethod))
                self._put(pattern, flush=flush, duration=duration, **kwargs)

    def wakeup(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.wakeup, self._params.wakeupPattern,
                              sticky)

    def listen(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.listen, self._params.listenPattern,
                              sticky)

    def think(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.think, self._params.thinkPattern,
                              sticky)

    def speak(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.speak, self._params.speakPattern,
                              sticky)

    def idle(self):
        if self._stickyAnimation:
            self._put(self._stickyAnimation['func'],
                      flush=False,
                      duration=self._stickyAnimation['duration'],
                      noTimeout=True,
                      **self._stickyAnimation['args'])
        else:
            if self._params.idlePattern is None:
                self._put(self._pattern.idle, noTimeout=True)
            else:
                try:
                    func = getattr(self._pattern, self._params.idlePattern)
                    self._put(func, noTimeout=True)
                except AttributeError:
                    self._logger.error(
                        "Can't find {} method in pattern".format(
                            self._params.idlePattern))
                    self._put(self._pattern.idle, noTimeout=True)

    def onError(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.onError, self._params.errorPattern,
                              sticky)

    def onSuccess(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.onSuccess,
                              self._params.successPattern, sticky)

    def updating(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.updating,
                              self._params.updatingPattern, sticky)

    def call(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.call, self._params.callPattern,
                              sticky)

    def setupMode(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.setupMode,
                              self._params.setupModePattern, sticky)

    def conError(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.conError,
                              self._params.conErrorPattern, sticky)

    def message(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.message,
                              self._params.messagePattern, sticky)

    def dnd(self, sticky: bool = False):
        self.putStickyPattern(self._pattern.dnd, self._params.dndPattern,
                              sticky)

    def off(self):
        if self._params.offPattern is None:
            self._put(self._pattern.off, True)
        else:
            try:
                func = getattr(self._pattern, self._params.offPattern)
                self._put(func, True)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.offPattern))
                self._put(self._pattern.off, True)

    def start(self):
        if self._params.startPattern is None:
            self._put(self._pattern.onStart, True)
        else:
            try:
                func = getattr(self._pattern, self._params.startPattern)
                self._put(func, True)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.startPattern))
                self._put(self._pattern.onStart, True)

    def stop(self):
        if self._params.startPattern is None:
            self._put(self._pattern.onStop, True)
        else:
            try:
                func = getattr(self._pattern, self._params.stopPattern)
                self._put(func, True)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.stopPattern))
                self._put(self._pattern.onStart, True)

    def toggleStateOff(self):
        if self.active:
            threading.Timer(interval=0.5, function=self._clear).start()
        self.off()

    def _clear(self):
        self._active.clear()

    def toggleStateOn(self):
        if not self.active:
            threading.Timer(interval=0.5,
                            function=self._pattern.onStart).start()
        self._active.set()

    def toggleState(self):
        if self.active:
            self.toggleStateOff()
        else:
            self.toggleStateOn()

    def _put(self,
             func,
             flush=False,
             duration: int = 0,
             noTimeout: bool = False,
             **kwargs):
        self._pattern.animation.clear()

        if not self.active:
            return

        if flush:
            self._queue.empty()

        requestId = str(uuid.uuid4())
        self._logger.debug(f'New animation {func} has id {requestId}')

        if not noTimeout and self._timeout and (not duration
                                                or duration > self._timeout):
            self._logger.debug(
                f'Timeout is setting duration from {duration} to {self._timeout}'
            )
            duration = self._timeout

        if duration:
            threading.Timer(interval=int(duration),
                            function=self.scheduledEndAnimation,
                            args=[requestId]).start()

        self._queue.put({
            "func": func,
            "args": kwargs,
            "duration": duration,
            "requestId": requestId
        })

    def _runAnimation(self):
        while self._running:
            self._pattern.animation.clear()
            funcRecipe = self._queue.get()
            self._runningRequestId = funcRecipe["requestId"]
            funcRecipe['func'](**funcRecipe['args'])

    def scheduledEndAnimation(self, requestId):
        if self._runningRequestId == requestId:
            self._logger.debug(
                f'Request {requestId} animation ended or timed out')
            self.idle()

    def setLed(self, ledNum, red, green, blue, brightness=-1):
        if ledNum < 0 or ledNum > self._interface.numLeds:
            self._logger.warning(
                "Tried to access a led number that doesn't exist: {} / {}".
                format(ledNum, self._interface.numLeds))
            return

        if brightness == -1:
            brightness = self.defaultBrightness
        self._interface.setPixel(ledNum, red, green, blue, brightness)

    def setLedRGB(self, ledNum, color, brightness=-1):
        if len(color) > 3:
            brightness = color[3]
        elif brightness == -1:
            brightness = self.defaultBrightness

        self.setLed(ledNum, color[0], color[1], color[2], brightness)

    def clearLeds(self):
        if self._interface is not None:
            self._interface.clearStrip()

    @DeprecationWarning
    def showData(self, data):
        """Will soon be removed in favor or more understandable and per led setting"""
        for i in range(self._hardware['numberOfLeds']):
            self.setLed(i, int(data[4 * i + 1]), int(data[4 * i + 2]),
                        int(data[4 * i + 3]))
        self.show()

    def show(self):
        self._interface.show()

    def doa(self):
        if self._params.enableDoA and self._hardware.get('doa'):
            angle = self._interface.doa()
            if angle > 0:
                return int(
                    round(angle / (360 / self._hardware['numberOfLeds'])))

        return 0

    def _runButtons(self):
        while self._running:
            try:
                for button in self._hardware['extras']['buttons']:
                    state = GPIO.input(self._hardware['extras']['buttons']
                                       [button]['bcm_gpio'])
                    if not state:
                        try:
                            func = getattr(
                                self._pattern, self._hardware['extras']
                                ['buttons'][button]['function'])
                            func()
                        except AttributeError:
                            self._logger.error(
                                "Function {} couldn't be found in pattern")
                time.sleep(0.25)
            except:
                import RPi.GPIO as GPIO

    def onStart(self):
        if self._interface is None:
            self._logger.error('Interface error')
            return

        self._running = True
        self._interface.onStart()

        self._animationThread.start()
        if self._buttonsThread is not None:
            self._buttonsThread.start()

        threading.Timer(interval=0.5, function=self._pattern.onStart).start()

    def onStop(self):
        self._pattern.animation.clear()
        self._pattern.onStop()

        self._running = False
        self._interface.onStop()

        if self._animationThread is not None and self._animationThread.is_alive(
        ):
            self._animationThread.join(timeout=2)
        if self._buttonsThread is not None and self._buttonsThread.is_alive():
            self._buttonsThread.join(timeout=2)
class LedsController:
	INSTANCE = None

	def __init__(self, mainClass):
		self._logger = logging.getLogger('SnipsLedControl')
		self._logger.info('Initializing leds controller')

		self._mainClass = mainClass # type: SnipsLedControl

		if self.INSTANCE is None:
			self.INSTANCE = self
		else:
			self._logger.fatal('Trying to instanciate LedsController but instance already exists')
			self._mainClass.onStop()

		self._params 			= self._mainClass.params
		self._hardware 			= self._mainClass.hardware
		self._interface 		= None
		self._running 			= False
		self._defaultBrightness = self._params.defaultBrightness

		self._active = threading.Event()
		if self._params.defaultState == 'on':
			self._active.set()
		else:
			self._active.clear()


		if self._params.pattern == 'google':
			self._pattern = GoogleHomeLedPattern(self)
		elif self._params.pattern == 'alexa':
			self._pattern = AlexaLedPattern(self)
		else:
			self._pattern = CustomLedPattern(self)

		if not self.initHardware():
			self._logger.fatal("Couldn't start hardware")
			self._mainClass.onStop()
			return


		self._buttonsThread = None
		if 'extras' in self._hardware and 'buttons' in self.hardware['extras']:
			import RPi.GPIO
			RPi.GPIO.setmode(RPi.GPIO.BCM)
			for button in self._hardware['extras']['buttons']:
				RPi.GPIO.setup(int(self._hardware['extras']['buttons'][button]['bcm_gpio']), RPi.GPIO.IN)

			self._buttonsThread = threading.Thread(target=self._runButtons)
			self._buttonsThread.setDaemon(True)


		self._queue = Queue.Queue()
		self._animationThread = threading.Thread(target=self._runAnimation)
		self._animationThread.setDaemon(True)


	@property
	def active(self):
		return self._active.isSet()


	@property
	def hardware(self):
		return self._hardware


	@property
	def defaultBrightness(self):
		return self._defaultBrightness


	def initHardware(self):
		try:
			if self._hardware['interface'] == Interfaces.APA102:
				from interfaces.apa102 import APA102
				self._interface = APA102(numLed=self._hardware['numberOfLeds'])

			elif self._hardware['interface'] == Interfaces.NEOPIXELS:
				from interfaces.neopixels import Neopixels
				self._interface = Neopixels(numLeds=self._hardware['numberOfLeds'], stripType=self._hardware['type'], pin=self._hardware['gpioPin'])

			elif self._hardware['interface'] == Interfaces.RESPEAKER_MIC_ARRAY_V2:
				from interfaces.respeakerMicArrayV2 import RespeakerMicArrayV2
				self._interface = RespeakerMicArrayV2(numLeds=self._hardware['numberOfLeds'], vid=self._hardware['vid'], pid=self._hardware['pid'])

			elif self._hardware['interface'] == Interfaces.MATRIX_VOICE:
				from interfaces.matrixvoice import MatrixVoice
				self._interface = MatrixVoice(numLeds=self._hardware['numberOfLeds'], matrixIp=self._hardware['matrixIp'], everloopPort=self._hardware['everloopPort'])

			if self._interface is None:
				return False
			else:
				return True
		except InterfaceInitError as e:
			self._logger.error('{}'.format(e))
			return False


	def wakeup(self):
		if self._params.wakeupPattern is None:
			self._put(self._pattern.wakeup)
		else:
			try:
				func = getattr(self._pattern, self._params.wakeupPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.wakeupPattern))
				self._put(self._pattern.wakeup)


	def listen(self):
		if self._params.listenPattern is None:
			self._put(self._pattern.listen)
		else:
			try:
				func = getattr(self._pattern, self._params.listenPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.listenPattern))
				self._put(self._pattern.listen)


	def think(self):
		if self._params.thinkPattern is None:
			self._put(self._pattern.think)
		else:
			try:
				func = getattr(self._pattern, self._params.thinkPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.thinkPattern))
				self._put(self._pattern.think)


	def speak(self):
		if self._params.speakPattern is None:
			self._put(self._pattern.speak)
		else:
			try:
				func = getattr(self._pattern, self._params.speakPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.speakPattern))
				self._put(self._pattern.speak)


	def idle(self):
		if self._params.idlePattern is None:
			self._put(self._pattern.idle)
		else:
			try:
				func = getattr(self._pattern, self._params.idlePattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.idlePattern))
				self._put(self._pattern.idle)


	def onError(self):
		if self._params.errorPattern is None:
			self._put(self._pattern.onError)
		else:
			try:
				funct = getattr(self._pattern, self._params.errorPattern)
				self._put(funct)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.errorPattern))
				self._put(self._pattern.onError)


	def onSuccess(self):
		if self._params.successPattern is None:
			self._put(self._pattern.onSuccess)
		else:
			try:
				func = getattr(self._pattern, self._params.successPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.successPattern))
				self._put(self._pattern.onSuccess)


	def updating(self):
		if self._params.updatingPattern is None:
			self._put(self._pattern.updating())
		else:
			try:
				func = getattr(self._pattern, self._params.updatingPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.updatingPattern))
				self._put(self._pattern.updating())


	def call(self):
		if self._params.updatingPattern is None:
			self._put(self._pattern.call())
		else:
			try:
				func = getattr(self._pattern, self._params.callPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.callPattern))
				self._put(self._pattern.call())


	def setupMode(self):
		if self._params.updatingPattern is None:
			self._put(self._pattern.setupMode())
		else:
			try:
				func = getattr(self._pattern, self._params.setupModePattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.setupModePattern))
				self._put(self._pattern.setupMode())


	def conError(self):
		if self._params.updatingPattern is None:
			self._put(self._pattern.conError())
		else:
			try:
				func = getattr(self._pattern, self._params.conErrorPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.conErrorPattern))
				self._put(self._pattern.conError())


	def message(self):
		if self._params.updatingPattern is None:
			self._put(self._pattern.message())
		else:
			try:
				func = getattr(self._pattern, self._params.messagePattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.messagePattern))
				self._put(self._pattern.message())


	def dnd(self):
		if self._params.updatingPattern is None:
			self._put(self._pattern.dnd())
		else:
			try:
				func = getattr(self._pattern, self._params.dndPattern)
				self._put(func)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.dndPattern))
				self._put(self._pattern.dnd())


	def off(self):
		if self._params.offPattern is None:
			self._put(self._pattern.off, True)
		else:
			try:
				func = getattr(self._pattern, self._params.offPattern)
				self._put(func, True)
			except AttributeError:
				self._logger.error("Can't find {} method in pattern".format(self._params.offPattern))
				self._put(self._pattern.off, True)


	def toggleStateOff(self):
		if self.active:
			threading.Timer(interval=0.5, function=self._clear).start()
		self.off()


	def _clear(self):
		self._active.clear()


	def toggleStateOn(self):
		if not self.active:
			threading.Timer(interval=0.5, function=self._pattern.onStart).start()
		self._active.set()


	def toggleState(self):
		if self.active:
			self.toggleStateOff()
		else:
			self.toggleStateOn()


	def _put(self, func, flush=False):
		self._pattern.animation.clear()

		if not self.active:
			return

		if flush:
			self._queue.empty()

		self._queue.put(func)


	def _runAnimation(self):
		while self._running:
			self._pattern.animation.clear()
			func = self._queue.get()
			func()


	def setLed(self, ledNum, red, green, blue, brightness=-1):
		if brightness == -1:
			brightness = self.defaultBrightness
		self._interface.setPixel(ledNum, red, green, blue, brightness)


	def setLedRGB(self, ledNum, color, brightness=-1):
		if brightness == -1:
			brightness = self.defaultBrightness

		if len(color) > 3:
			brightness = color[3]

		self.setLed(ledNum, color[0], color[1], color[2], brightness)


	def clearLeds(self):
		self._interface.clearStrip()


	@DeprecationWarning
	def showData(self, data):
		"""Will soon be removed in favor or more understandable and per led setting"""
		for i in range(self._hardware['numberOfLeds']):
			self.setLed(i, int(data[4 * i + 1]), int(data[4 * i + 2]), int(data[4 * i + 3]))
		self.show()


	def show(self):
		self._interface.show()


	def _runButtons(self):
		while self._running:
			try:
				for button in self._hardware['extras']['buttons']:
					state = GPIO.input(self._hardware['extras']['buttons'][button]['bcm_gpio'])
					if not state:
						try:
							func = getattr(self._pattern, self._hardware['extras']['buttons'][button]['function'])
							func()
						except AttributeError:
							self._logger.error("Function {} couldn't be found in pattern")
				time.sleep(0.25)
			except:
				import RPi.GPIO as GPIO


	def onStart(self):
		if self._interface is None:
			return

		self._running = True
		self._interface.onStart()

		self._animationThread.start()
		if self._buttonsThread is not None:
			self._buttonsThread.start()

		threading.Timer(interval=0.5, function=self._pattern.onStart).start()


	def onStop(self):
		self._pattern.animation.clear()
		self._pattern.onStop()

		self._running = False
		self._interface.onStop()

		self._animationThread.join(timeout=2)
		if self._buttonsThread is not None:
			self._buttonsThread.join(timeout=2)
示例#5
0
    def __init__(self, mainClass):
        self._logger = logging.getLogger('HermesLedControl')
        self._logger.info('Initializing leds controller')

        self._mainClass = mainClass  # type: HermesLedControl

        if self.INSTANCE is None:
            self.INSTANCE = self
        else:
            self._logger.fatal(
                'Trying to instanciate LedsController but instance already exists'
            )
            self._mainClass.onStop()

        self._params = self._mainClass.params
        self._hardware = self._mainClass.hardware
        self._interface = None
        self._running = False
        self._defaultBrightness = self._params.defaultBrightness
        self._stickyAnimation = None
        self._runningRequestId = None

        if not self._params.enableDoA and 'doa' in self._hardware:
            self._hardware['doa'] = False

        self._active = threading.Event()
        if self._params.defaultState == 'on':
            self._active.set()
        else:
            self._active.clear()

        if not self.initHardware():
            self._logger.fatal("Couldn't start hardware")
            self._mainClass.onStop()
            return

        if self._params.pattern == 'google':
            from ledPatterns.GoogleLedPattern import GoogleHomeLedPattern
            self._pattern = GoogleHomeLedPattern(self)
        elif self._params.pattern == 'alexa':
            from ledPatterns.AlexaLedPattern import AlexaLedPattern
            self._pattern = AlexaLedPattern(self)
        elif self._params.pattern == 'kiboost':
            from ledPatterns.KiboostLedPattern import KiboostLedPattern
            self._pattern = KiboostLedPattern(self)
        elif self._params.pattern == 'projectalice':
            from ledPatterns.ProjectAlicePattern import ProjectAlicePattern
            self._pattern = ProjectAlicePattern(self)
        elif self._params.pattern == 'pgas':
            from ledPatterns.PgasPattern import PgasPattern
            self._pattern = PgasPattern(self)
        elif self._params.pattern == 'fake-name':
            from ledPatterns.FakeNamePattern import FakeNamePattern
            self._pattern = FakeNamePattern(self)
        else:
            from ledPatterns.CustomLedPattern import CustomLedPattern
            self._pattern = CustomLedPattern(self)

        self._buttonsThread = None
        if 'extras' in self._hardware and 'buttons' in self.hardware['extras']:
            import RPi.GPIO

            RPi.GPIO.setmode(RPi.GPIO.BCM)
            for button in self._hardware['extras']['buttons']:
                RPi.GPIO.setup(
                    int(self._hardware['extras']['buttons'][button]
                        ['bcm_gpio']), RPi.GPIO.IN)

            self._buttonsThread = threading.Thread(target=self._runButtons)
            self._buttonsThread.setDaemon(True)

        self._timeout = 0
        if self._params.timeout and self._params.timeout > 0:
            self._timeout = self._params.timeout

        self._queue = Queue.Queue()
        self._animationThread = threading.Thread(target=self._runAnimation)
        self._animationThread.setDaemon(True)
示例#6
0
class LedsController:
    INSTANCE = None

    def __init__(self, mainClass):
        self._logger = logging.getLogger('SnipsLedControl')
        self._logger.info('Initializing leds controller')

        self._mainClass = mainClass  # type: SnipsLedControl

        if self.INSTANCE is None:
            self.INSTANCE = self
        else:
            self._logger.fatal(
                'Trying to instanciate LedsController but instance already exists'
            )
            self._mainClass.onStop()

        self._params = self._mainClass.params
        self._hardware = self._mainClass.hardware
        self._interface = None
        self._running = False
        self._active = True if self._params.defaultState == 'on' else False

        if self._params.pattern == 'google':
            self._pattern = GoogleHomeLedPattern(self)
        elif self._params.pattern == 'alexa':
            self._pattern = AlexaLedPattern(self)
        else:
            self._pattern = CustomLedPattern(self)

        if not self.initHardware():
            self._logger.fatal("Couldn't start hardware")
            self._mainClass.onStop()
            return

        self._queue = Queue.Queue()
        self._thread = threading.Thread(target=self._run)
        self._thread.daemon = True

    @property
    def active(self):
        return self._active

    @property
    def hardware(self):
        return self._hardware

    def initHardware(self):
        if self._hardware['interface'] == Interfaces.APA102:
            from interfaces.apa102 import APA102
            self._interface = APA102(numLed=self._hardware['numberOfLeds'])

        elif self._hardware['interface'] == Interfaces.NEOPIXELS:
            from interfaces.neopixels import Neopixels
            self._interface = Neopixels(numLeds=self._hardware['numberOfLeds'],
                                        pin=self._hardware['gpioPin'])

        elif self._hardware['interface'] == Interfaces.RESPEAKER_MIC_ARRAY_V2:
            from interfaces.respeakerMicArrayV2 import RespeakerMicArrayV2
            self._interface = RespeakerMicArrayV2(
                numLeds=self._hardware['numberOfLeds'],
                vid=self._hardware['vid'],
                pid=self._hardware['pid'])

        elif self._hardware['interface'] == Interfaces.MATRIX_VOICE:
            from interfaces.matrixvoice import MatrixVoice
            self._interface = MatrixVoice(
                numLeds=self._hardware['numberOfLeds'],
                matrixIp=self._hardware['matrixIp'],
                everloopPort=self._hardware['everloopPort'])

        if self._interface is None:
            return False
        else:
            return True

    def wakeup(self):
        if self._params.wakeupPattern is None:
            self.put(self._pattern.wakeup)
        else:
            try:
                func = getattr(self._pattern, self._params.wakeupPattern)
                self.put(func)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.wakeupPattern))

    def listen(self):
        if self._params.listenPattern is None:
            self.put(self._pattern.listen)
        else:
            try:
                func = getattr(self._pattern, self._params.listenPattern)
                self.put(func)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.listenPattern))

    def think(self):
        if self._params.thinkPattern is None:
            self.put(self._pattern.think)
        else:
            try:
                func = getattr(self._pattern, self._params.thinkPattern)
                self.put(func)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.thinkPattern))

    def speak(self):
        if self._params.speakPattern is None:
            self.put(self._pattern.speak)
        else:
            try:
                func = getattr(self._pattern, self._params.speakPattern)
                self.put(func)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.speakPattern))

    def idle(self):
        if self._params.idlePattern is None:
            self.put(self._pattern.idle)
        else:
            try:
                func = getattr(self._pattern, self._params.idlePattern)
                self.put(func)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.idlePattern))

    def onError(self):
        if self._params.errorPattern is None:
            self.put(self._pattern.onError)
        else:
            try:
                funct = getattr(self._pattern, self._params.errorPattern)
                self.put(funct)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.errorPattern))

    def onSuccess(self):
        if self._params.successPattern is None:
            self.put(self._pattern.onSuccess)
        else:
            try:
                func = getattr(self._pattern, self._params.successPattern)
                self.put(func)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.successPattern))

    def off(self):
        if self._params.offPattern is None:
            self.put(self._pattern.off)
        else:
            try:
                func = getattr(self._pattern, self._params.offPattern)
                self.put(func)
            except AttributeError:
                self._logger.error("Can't find {} method in pattern".format(
                    self._params.offPattern))

    def toggleStateOff(self):
        self._active = False
        self.off()

    def toggleStateOn(self):
        self._active = True

    def toggleState(self):
        if self._active:
            self._active = False
            self.off()
        else:
            self._active = True

    def put(self, func):
        self._pattern.animation.clear()

        if not self._active:
            return

        self._queue.put(func)

    def _run(self):
        while self._running:
            self._pattern.animation.clear()
            func = self._queue.get()
            func()

    def setLed(self, ledNum, red, green, blue, brightness=100):
        self._interface.setPixel(ledNum, red, green, blue, brightness)

    def setLedRGB(self, ledNum, color, brightness=100):
        self._interface.setPixelRgb(ledNum, color, brightness)

    def clearLeds(self):
        self._interface.clearStrip()

    @DeprecationWarning
    def showData(self, data):
        """Will soon be removed in favor or more understandable and per led setting"""
        for i in range(self._hardware['numberOfLeds']):
            self.setLed(i, int(data[4 * i + 1]), int(data[4 * i + 2]),
                        int(data[4 * i + 3]))
        self.show()

    def show(self):
        self._interface.show()

    def onStart(self):
        if self._interface is None:
            return

        self._running = True
        self._interface.onStart()
        self._pattern.onStart()
        self._thread.start()

    def onStop(self):
        self._pattern.animation.clear()
        self._pattern.onStop()

        self._running = False
        self._interface.onStop()

        self._thread.join(timeout=2)