def __init__(self, host: str, port: int, hotwordName: str):
     super().__init__()
     self._logger = Logger(prepend='[HotwordDownloadThread]')
     self._host = host
     self._port = int(port)
     self._hotwordName = hotwordName
     self.setDaemon(True)
    def onStop(self):
        mqttManager = self._managers.pop(
            'MqttManager', None)  # Mqtt goes down last with bug reporter
        bugReportManager = self._managers.pop(
            'BugReportManager', None)  # bug reporter goes down as last

        skillManager = self._managers.pop(
            'SkillManager',
            None)  # Skill manager goes down first, to tell the skills
        if skillManager:
            try:
                skillManager.onStop()
            except Exception as e:
                Logger().logError(f'Error stopping SkillManager: {e}')

        for managerName, manager in self._managers.items():
            try:
                if manager.isActive:
                    manager.onStop()
            except Exception as e:
                Logger().logError(
                    f'Error while shutting down manager **{managerName}**: {e}'
                )

        if mqttManager:
            try:
                mqttManager.onStop()
            except Exception as e:
                Logger().logError(f'Error stopping MqttManager: {e}')

        if bugReportManager:
            try:
                bugReportManager.onStop()
            except Exception as e:
                Logger().logError(f'Error stopping BugReportManager: {e}')
Exemple #3
0
    def __init__(self, restartHandler: callable):
        Singleton.__init__(self, self.NAME)
        self._logger = Logger(prepend='[Project Alice]')
        self._logger.logInfo('Starting Alice main unit')
        self._booted = False
        self._isUpdating = False
        self._shuttingDown = False
        self._restart = False
        self._restartHandler = restartHandler

        if not self.checkDependencies():
            self._restart = True
            self._restartHandler()
        else:
            with Stopwatch() as stopWatch:
                self._superManager = SuperManager(self)

                self._superManager.initManagers()
                self._superManager.onStart()

                if self._superManager.configManager.getAliceConfigByName(
                        'useHLC'):
                    self._superManager.commons.runRootSystemCommand(
                        ['systemctl', 'start', 'hermesledcontrol'])

                self._superManager.onBooted()

            self._logger.logInfo(f'Started in {stopWatch} seconds')
            self._booted = True
    def __init__(self, host: str, port: int, zipPath: str):
        super().__init__()
        self._logger = Logger()

        self.setDaemon(True)

        self._host = host
        self._port = port
        self._zipPath = Path(zipPath)
    def __init__(self, host: str, port: int, zipPath: str):
        super().__init__()
        self._logger = Logger(prepend='[HotwordUploadThread]')

        self.setDaemon(True)

        self._host = host
        self._port = port
        self._zipPath = Path(zipPath)
Exemple #6
0
class State:

    name: str
    currentState: StateType = StateType.BORN
    logger: Logger = Logger(prepend='[State]')
    callbacks: list = field(default_factory=list)

    def subscribe(self, callback: Callable):
        self.callbacks.append(callback)

    def unsubscribe(self, callback: Callable):
        self.callbacks.remove(callback)

    def setState(self, newState: StateType):
        oldState = self.currentState
        self.currentState = newState
        for callback in self.callbacks:
            try:
                callback(oldState, newState)
            except:
                self.logger.logWarning(
                    f'Failed callback for state {self.name}')

    def __repr__(self) -> str:
        return f'State "{self.name}" Current state "{self.currentState.value}"'
Exemple #7
0
	def __init__(self, name):
		super().__init__()

		if self.INSTANCE:
			Logger().logFatal(f'Trying to instanciate {name} but instance already exists')
			raise KeyboardInterrupt
		else:
			self.INSTANCE = self
 def onStop(self):
     managerName = constants.UNKNOWN_MANAGER
     try:
         for managerName, manager in self._managers.items():
             manager.onStop()
     except Exception as e:
         Logger().logError(
             f'Error while shutting down manager "{managerName}": {e}')
Exemple #9
0
    def onStop(self):
        managerName = constants.UNKNOWN_MANAGER
        try:
            mqttManager = self._managers.pop('MqttManager')

            for managerName, manager in self._managers.items():
                manager.onStop()

            managerName = mqttManager.name
            mqttManager.onStop()
        except KeyError as e:
            Logger().logWarning(
                f'Manager **{managerName}** was not running: {e}')
        except Exception as e:
            Logger().logError(
                f'Error while shutting down manager **{managerName}**: {e}')
            traceback.print_exc()
 def __init__(self,
              message: str = None,
              status: int = None,
              context: list = None):
     self._logger = Logger()
     self._message = message
     self._status = status
     self._context = context
     super().__init__(message)
Exemple #11
0
    def restartManager(self, manager: str):
        if not manager in self._managers:
            Logger().logWarning(
                f'Was asking to restart manager **{manager}** but it doesn\'t exist'
            )
            return

        self._managers[manager].onStop()
        self._managers[manager].onStart()
        self._managers[manager].onBooted()
Exemple #12
0
 def exceptionDecorator(*args, **kwargs):
     try:
         return func(*args, **kwargs)
     except exceptions as e:
         Logger(depth=6).logWarning(msg=e, printStack=printStack)
         return _exceptHandler(*args,
                               text=text,
                               exceptHandler=exceptHandler,
                               returnText=returnText,
                               **kwargs)
Exemple #13
0
    def __init__(self, restartHandler: callable):
        Singleton.__init__(self, self.NAME)
        self._logger = Logger()
        self._logger.logInfo('Starting up Project Alice')
        self._booted = False
        with Stopwatch() as stopWatch:
            self._restart = False
            self._restartHandler = restartHandler
            self._superManager = SuperManager(self)

            self._superManager.initManagers()
            self._superManager.onStart()

            if self._superManager.configManager.getAliceConfigByName('useHLC'):
                self._superManager.commons.runRootSystemCommand(
                    ['systemctl', 'start', 'hermesledcontrol'])

            self._superManager.onBooted()
        self._logger.logInfo(f'- Started Project Alice in {stopWatch} seconds')
        self._booted = True
Exemple #14
0
    def onBooted(self):
        self.mqttManager.playSound(soundFilename='boot')

        manager = None
        try:
            for manager in self._managers.values():
                if manager:
                    manager.onBooted()
        except Exception as e:
            Logger().logError(
                f'Error while sending onBooted to manager **{manager.name}**: {e}'
            )
Exemple #15
0
    def onStop(self):
        managerName = constants.UNKNOWN_MANAGER
        try:
            mqttManager = self._managers.pop('MqttManager')

            for managerName, manager in self._managers.items():
                manager.onStop()

            managerName = mqttManager.name
            mqttManager.onStop()
        except Exception as e:
            Logger().logError(
                f'Error while shutting down manager **{managerName}**: {e}')
		def settingDecorator(*args, **kwargs):
			if not settingName:
				Logger().logWarning(msg='Cannot use IfSetting decorator without settingName')
				return None

			configManager = SuperManager.getInstance().configManager
			value = configManager.getSkillConfigByName(skillName, settingName) if skillName else configManager.getAliceConfigByName(settingName)

			if value is None:
				return None

			if (not inverted and value == settingValue) or \
				(inverted and value != settingValue):
				return func(*args, **kwargs)
Exemple #17
0
    def onBooted(self):
        manager = None
        try:
            for manager in self._managers.values():
                if manager:
                    manager.onBooted()
        except Exception as e:
            Logger().logError(
                f'Error while sending onBooted to manager **{manager.name}**: {e}'
            )

        deviceList = self.deviceManager.getDevicesWithAbilities(
            [DeviceAbility.IS_SATELITTE, DeviceAbility.IS_CORE])
        self.mqttManager.playSound(soundFilename='boot', deviceUid=deviceList)
Exemple #18
0
class ProjectAlice(Singleton):
    NAME = 'ProjectAlice'

    def __init__(self, restartHandler: callable):
        Singleton.__init__(self, self.NAME)
        self._logger = Logger(prepend='[Project Alice]')
        self._logger.logInfo('Starting Alice main unit')
        self._booted = False
        self._isUpdating = False
        self._shuttingDown = False
        self._restart = False
        self._restartHandler = restartHandler

        if not self.checkDependencies():
            self._restart = True
            self._restartHandler()
        else:
            with Stopwatch() as stopWatch:
                self._superManager = SuperManager(self)

                self._superManager.initManagers()
                self._superManager.onStart()

                if self._superManager.configManager.getAliceConfigByName(
                        'useHLC'):
                    self._superManager.commons.runRootSystemCommand(
                        ['systemctl', 'start', 'hermesledcontrol'])

                self._superManager.onBooted()

            self._logger.logInfo(f'Started in {stopWatch} seconds')
            self._booted = True

    def checkDependencies(self) -> bool:
        """
		Compares .hash files against requirements.txt and sysrequirement.txt. Updates dependencies if necessary
		:return: boolean False if the check failed, new deps were installed (reboot maybe? :) )
		"""
        HASH_SUFFIX = '.hash'
        TXT_SUFFIX = '.txt'

        path = Path('requirements')
        savedHash = path.with_suffix(HASH_SUFFIX)
        reqHash = hashlib.blake2b(
            path.with_suffix(TXT_SUFFIX).read_bytes()).hexdigest()

        if not savedHash.exists() or savedHash.read_text() != reqHash:
            self._logger.logInfo(
                'Pip dependencies added or removed, updating virtual environment'
            )
            subprocess.run([
                './venv/bin/pip', 'install', '-r',
                str(path.with_suffix(TXT_SUFFIX))
            ])
            savedHash.write_text(reqHash)
            return False

        path = Path('sysrequirements')
        savedHash = path.with_suffix(HASH_SUFFIX)
        reqHash = hashlib.blake2b(
            path.with_suffix(TXT_SUFFIX).read_bytes()).hexdigest()

        if not savedHash.exists() or savedHash.read_text() != reqHash:
            self._logger.logInfo(
                'System dependencies added or removed, updating system')
            reqs = [
                line.rstrip('\n')
                for line in open(path.with_suffix(TXT_SUFFIX))
            ]
            subprocess.run([
                'sudo', 'apt-get', 'install', '-y', '--allow-unauthenticated'
            ] + reqs)
            savedHash.write_text(reqHash)
            return False

        path = Path('pipuninstalls')
        savedHash = path.with_suffix(HASH_SUFFIX)
        reqHash = hashlib.blake2b(
            path.with_suffix(TXT_SUFFIX).read_bytes()).hexdigest()

        if not savedHash.exists() or savedHash.read_text() != reqHash:
            self._logger.logInfo(
                'Pip conflicting dependencies added, updating virtual environment'
            )
            subprocess.run([
                './venv/bin/pip', 'uninstall', '-y', '-r',
                str(path.with_suffix(TXT_SUFFIX))
            ])
            savedHash.write_text(reqHash)
            return False

        return True

    @property
    def name(self) -> str:  # NOSONAR
        return self.NAME

    @property
    def isBooted(self) -> bool:
        return self._booted

    @property
    def restart(self) -> bool:
        return self._restart

    @restart.setter
    def restart(self, value: bool):
        self._restart = value

    def doRestart(self):
        self._restart = True
        self.onStop()

    def onStop(self, withReboot: bool = False):
        self._logger.logInfo('Shutting down')
        self._shuttingDown = True
        self._superManager.onStop()
        if self._superManager.configManager.getAliceConfigByName('useHLC'):
            self._superManager.commons.runRootSystemCommand(
                ['systemctl', 'stop', 'hermesledcontrol'])

        self._booted = False
        self.INSTANCE = None

        if withReboot:
            subprocess.run(['sudo', 'shutdown', '-r', 'now'])
        else:
            self._restartHandler()

    def wipeAll(self):
        # Set as restarting so skills don't install / update
        self._restart = True

        self._superManager.skillManager.wipeSkills()
        self._superManager.databaseManager.clearDB()
        self._superManager.assistantManager.clearAssistant()
        self._superManager.dialogTemplateManager.clearCache(False)
        self._superManager.nluManager.clearCache()

    def updateProjectAlice(self):
        self._logger.logInfo('Checking for core updates')
        STATE = 'projectalice.core.updating'
        state = self._superManager.stateManager.getState(STATE)
        if not state:
            self._superManager.stateManager.register(
                STATE, initialState=StateType.RUNNING)
        elif state.currentState == StateType.RUNNING:
            self._logger.logInfo('Update cancelled, already running')
            return

        self._superManager.stateManager.setState(STATE,
                                                 newState=StateType.RUNNING)

        self._isUpdating = True
        req = requests.get(
            url=f'{constants.GITHUB_API_URL}/ProjectAlice/branches',
            auth=SuperManager.getInstance().configManager.githubAuth)
        if req.status_code != 200:
            self._logger.logWarning('Failed checking for updates')
            self._superManager.stateManager.setState(STATE,
                                                     newState=StateType.ERROR)
            return

        userUpdatePref = SuperManager.getInstance(
        ).configManager.getAliceConfigByName('aliceUpdateChannel')

        if userUpdatePref == 'master':
            candidate = 'master'
        else:
            candidate = Version.fromString(constants.VERSION)
            for branch in req.json():
                if 'dependabot' in branch['name']:
                    continue
                repoVersion = Version.fromString(branch['name'])
                if not repoVersion.isVersionNumber:
                    continue

                releaseType = repoVersion.releaseType
                if userUpdatePref == 'rc' and releaseType in {
                        'b', 'a'
                } or userUpdatePref == 'beta' and releaseType == 'a':
                    continue

                if repoVersion > candidate:
                    candidate = repoVersion

        self._logger.logInfo(f'Checking on "{str(candidate)}" update channel')
        commons = SuperManager.getInstance().commons

        currentHash = subprocess.check_output(
            ['git', 'rev-parse', '--short HEAD'])

        commons.runSystemCommand(['git', '-C', commons.rootDir(), 'stash'])
        commons.runSystemCommand(
            ['git', '-C', commons.rootDir(), 'clean', '-df'])
        commons.runSystemCommand(
            ['git', '-C',
             commons.rootDir(), 'checkout',
             str(candidate)])
        commons.runSystemCommand(['git', '-C', commons.rootDir(), 'pull'])
        commons.runSystemCommand(
            ['git', '-C', commons.rootDir(), 'submodule', 'init'])
        commons.runSystemCommand(
            ['git', '-C',
             commons.rootDir(), 'submodule', 'update'])
        commons.runSystemCommand([
            'git', '-C',
            commons.rootDir(), 'submodule', 'foreach', 'git', 'checkout',
            f'builds_{str(candidate)}'
        ])
        commons.runSystemCommand([
            'git', '-C',
            commons.rootDir(), 'submodule', 'foreach', 'git', 'pull'
        ])

        newHash = subprocess.check_output(['git', 'rev-parse', '--short HEAD'])

        # Remove install tickets
        [
            file.unlink() for file in Path(
                commons.rootDir(), 'system/skillInstallTickets').glob('*')
            if file.is_file()
        ]

        self._superManager.stateManager.setState(STATE,
                                                 newState=StateType.FINISHED)

        if currentHash != newHash:
            self._logger.logWarning(
                'New Alice version installed, need to restart...')

            self._superManager.webUINotificationManager.newNotification(
                typ=UINotificationType.INFO, notification='aliceUpdated')
            self.doRestart()

        self._logger.logInfo('Update checks completed.')
        self._isUpdating = False

    @property
    def updating(self) -> bool:
        return self._isUpdating

    @property
    def shuttingDown(self) -> bool:
        return self._shuttingDown
Exemple #19
0
    def onStart(self):
        try:
            commons = self._managers.pop('CommonsManager')
            commons.onStart()

            configManager = self._managers.pop('ConfigManager')
            configManager.onStart()

            languageManager = self._managers.pop('LanguageManager')
            languageManager.onStart()

            locationManager = self._managers.pop('LocationManager')
            locationManager.onStart()

            deviceManager = self._managers.pop('DeviceManager')
            deviceManager.onStart()

            audioServer = self._managers.pop('AudioManager')
            audioServer.onStart()

            internetManager = self._managers.pop('InternetManager')
            internetManager.onStart()

            databaseManager = self._managers.pop('DatabaseManager')
            databaseManager.onStart()

            userManager = self._managers.pop('UserManager')
            userManager.onStart()

            mqttManager = self._managers.pop('MqttManager')
            mqttManager.onStart()

            talkManager = self._managers.pop('TalkManager')
            skillManager = self._managers.pop('SkillManager')
            assistantManager = self._managers.pop('AssistantManager')
            dialogTemplateManager = self._managers.pop('DialogTemplateManager')
            nluManager = self._managers.pop('NluManager')
            nodeRedManager = self._managers.pop('NodeRedManager')

            for manager in self._managers.values():
                if manager:
                    manager.onStart()

            talkManager.onStart()
            nluManager.onStart()
            skillManager.onStart()
            dialogTemplateManager.onStart()
            assistantManager.onStart()
            nodeRedManager.onStart()

            self._managers[configManager.name] = configManager
            self._managers[audioServer.name] = audioServer
            self._managers[languageManager.name] = languageManager
            self._managers[locationManager.name] = locationManager
            self._managers[deviceManager.name] = deviceManager
            self._managers[talkManager.name] = talkManager
            self._managers[databaseManager.name] = databaseManager
            self._managers[userManager.name] = userManager
            self._managers[mqttManager.name] = mqttManager
            self._managers[skillManager.name] = skillManager
            self._managers[dialogTemplateManager.name] = dialogTemplateManager
            self._managers[assistantManager.name] = assistantManager
            self._managers[nluManager.name] = nluManager
            self._managers[internetManager.name] = internetManager
            self._managers[nodeRedManager.name] = nodeRedManager
        except Exception as e:
            import traceback

            traceback.print_exc()
            Logger().logFatal(f'Error while starting managers: {e}')
Exemple #20
0
class ProjectAliceObject:
    def __init__(self, logDepth: int = 3, *args, **kwargs):
        self._depth = logDepth
        self._logger = Logger(logDepth)

    def __repr__(self):
        return json.dumps(self.__dict__)

    def __str__(self):
        return json.dumps(self.__dict__)

    def broadcast(self,
                  method: str,
                  exceptions: list = None,
                  manager=None,
                  propagateToSkills: bool = False,
                  **kwargs):
        if not exceptions:
            exceptions = list()

        if isinstance(exceptions, str):
            exceptions = [exceptions]

        if not exceptions and not manager:
            # Prevent infinite loop of broadcaster being broadcasted to re broadcasting
            self.logWarning(
                'Cannot broadcast to itself, the calling method has to be put in exceptions'
            )
            return

        if 'ProjectAlice' not in exceptions:
            exceptions.append('ProjectAlice')

        if not method.startswith('on'):
            method = f'on{method[0].capitalize() + method[1:]}'

        deadManagers = list()
        for name, man in SM.SuperManager.getInstance().managers.items():
            if not man:
                deadManagers.append(name)
                continue

            if (manager
                    and man.name != manager.name) or man.name in exceptions:
                continue

            try:
                func = getattr(man, method, None)
                if func:
                    func(**kwargs)

            except TypeError as e:
                self.logWarning(
                    f'- Failed to broadcast event {method} to {man.name}: {e}')

        if propagateToSkills:
            self.SkillManager.skillBroadcast(method=method, **kwargs)

        for name in deadManagers:
            del SM.SuperManager.getInstance().managers[name]

    def logInfo(self, msg: str):
        self._logger.doLog(function='info', msg=msg, printStack=False)

    def logError(self, msg: str):
        self._logger.doLog(function='error', msg=msg)

    def logDebug(self, msg: str):
        self._logger.doLog(function='debug', msg=msg, printStack=False)

    def logFatal(self, msg: str):
        self._logger.doLog(function='fatal', msg=msg)
        try:
            self.ProjectAlice.onStop()
        except:
            exit()

    def logWarning(self, msg: str, printStack: bool = False):
        self._logger.doLog(function='warning', msg=msg, printStack=printStack)

    def logCritical(self, msg: str):
        self._logger.doLog(function='critical', msg=msg)

    def onStart(self):
        pass

    def onStop(self):
        pass

    def onBooted(self):
        pass

    def onSkillInstalled(self, skill: str):
        pass

    def onSkillUpdated(self, skill: str):
        pass

    def onInternetConnected(self):
        pass

    def onInternetLost(self):
        pass

    def onHotword(self, siteId: str, user: str = constants.UNKNOWN_USER):
        pass

    def onHotwordToggleOn(self, siteId: str):
        pass

    def onSessionStarted(self, session):
        pass

    def onStartListening(self, session):
        pass

    def onStopListening(self, session):
        pass

    def onCaptured(self, session):
        pass

    def onNluQuery(self, session):
        pass

    def onIntentParsed(self, session):
        pass

    def onUserCancel(self, session):
        pass

    def onSessionTimeout(self, session):
        pass

    def onIntentNotRecognized(self, session):
        pass

    def onSessionError(self, session):
        pass

    def onSessionEnded(self, session):
        pass

    def onSay(self, session):
        pass

    def onSayFinished(self, session):
        pass

    def onSessionQueued(self, session):
        pass

    def onMessage(self, session) -> bool:
        """ Do not consume the intent by default """
        return False

    def onSleep(self):
        pass

    def onWakeup(self):
        pass

    def onGoingBed(self):
        pass

    def onLeavingHome(self):
        pass

    def onReturningHome(self):
        pass

    def onEating(self):
        pass

    def onWatchingTV(self):
        pass

    def onCooking(self):
        pass

    def onMakeup(self):
        pass

    def onContextSensitiveDelete(self, sessionId: str):
        pass

    def onContextSensitiveEdit(self, sessionId: str):
        pass

    def onFullMinute(self):
        pass

    def onFiveMinute(self):
        pass

    def onQuarterHour(self):
        pass

    def onFullHour(self):
        pass

    def onWakeword(self, siteId: str, user: str = constants.UNKNOWN_USER):
        pass

    def onMotionDetected(self):
        pass

    def onMotionStopped(self):
        pass

    def onButtonPressed(self):
        pass

    def onButtonReleased(self):
        pass

    def onDeviceConnecting(self):
        pass

    def onDeviceDisconnecting(self):
        pass

    def onUVIndexAlert(self, *args, **kwargs):
        pass

    def onRaining(self, *args, **kwargs):
        pass

    def onTooMuchRain(self, *args, **kwargs):
        pass

    def onWindy(self, *args, **kwargs):
        pass

    def onFreezing(self, *args, **kwargs):
        pass

    def onTemperatureHighAlert(self, *args, **kwargs):
        pass

    def onTemperatureLowAlert(self, *args, **kwargs):
        pass

    def onCO2Alert(self, *args, **kwargs):
        pass

    def onHumidityHighAlert(self, *args, **kwargs):
        pass

    def onHumidityLowAlert(self, *args, **kwargs):
        pass

    def onNoiseAlert(self, *args, **kwargs):
        pass

    def onPressureHighAlert(self, *args, **kwargs):
        pass

    def onPressureLowAlert(self, *args, **kwargs):
        pass

    def onBroadcastingForNewDeviceStart(self, session):
        pass

    def onBroadcastingForNewDeviceStop(self):
        pass

    def onAuthenticated(self, session):
        pass

    def onAuthenticationFailed(self, session):
        pass

    def onAudioFrame(self, **kwargs):
        pass

    def onSnipsAssistantInstalled(self, **kwargs):
        pass

    def onSnipsAssistantFailedTraining(self, **kwargs):
        pass

    def onSkillInstallFailed(self, skill: str):
        pass

    def onNluTrained(self, **kwargs):
        pass

    def onPartialTextCaptured(self, session, text: str, likelihood: float,
                              seconds: float):
        pass

    @property
    def ProjectAlice(self):
        return SM.SuperManager.getInstance().projectAlice

    @property
    def ConfigManager(self):
        return SM.SuperManager.getInstance().configManager

    @property
    def SkillManager(self):
        return SM.SuperManager.getInstance().skillManager

    @property
    def DeviceManager(self):
        return SM.SuperManager.getInstance().deviceManager

    @property
    def DialogSessionManager(self):
        return SM.SuperManager.getInstance().dialogSessionManager

    @property
    def MultiIntentManager(self):
        return SM.SuperManager.getInstance().multiIntentManager

    @property
    def ProtectedIntentManager(self):
        return SM.SuperManager.getInstance().protectedIntentManager

    @property
    def MqttManager(self):
        return SM.SuperManager.getInstance().mqttManager

    @property
    def SnipsServicesManager(self):
        return SM.SuperManager.getInstance().snipsServicesManager

    @property
    def UserManager(self):
        return SM.SuperManager.getInstance().userManager

    @property
    def DatabaseManager(self):
        return SM.SuperManager.getInstance().databaseManager

    @property
    def InternetManager(self):
        return SM.SuperManager.getInstance().internetManager

    @property
    def TelemetryManager(self):
        return SM.SuperManager.getInstance().telemetryManager

    @property
    def ThreadManager(self):
        return SM.SuperManager.getInstance().threadManager

    @property
    def TimeManager(self):
        return SM.SuperManager.getInstance().timeManager

    @property
    def ASRManager(self):
        return SM.SuperManager.getInstance().asrManager

    @property
    def LanguageManager(self):
        return SM.SuperManager.getInstance().languageManager

    @property
    def TalkManager(self):
        return SM.SuperManager.getInstance().talkManager

    @property
    def TTSManager(self):
        return SM.SuperManager.getInstance().ttsManager

    @property
    def WakewordManager(self):
        return SM.SuperManager.getInstance().wakewordManager

    @property
    def WebInterfaceManager(self):
        return SM.SuperManager.getInstance().webInterfaceManager

    @property
    def Commons(self):
        return SM.SuperManager.getInstance().commonsManager

    @property
    def SnipsWatchManager(self):
        return SM.SuperManager.getInstance().snipsWatchManager

    @property
    def SkillStoreManager(self):
        return SM.SuperManager.getInstance().skillStoreManager

    @property
    def NluManager(self):
        return SM.SuperManager.getInstance().nluManager

    @property
    def DialogTemplateManager(self):
        return SM.SuperManager.getInstance().dialogTemplateManager

    @property
    def SnipsAssistantManager(self):
        return SM.SuperManager.getInstance().snipsAssistantManager
class HotwordDownloadThread(Thread):
    def __init__(self, host: str, port: int, hotwordName: str):
        super().__init__()
        self._logger = Logger(prepend='[HotwordDownloadThread]')
        self._host = host
        self._port = int(port)
        self._hotwordName = hotwordName
        self.setDaemon(True)

    def run(self):
        sock = None
        try:
            self._logger.logInfo('Cleaning up')

            rootPath = Path(SuperManager.getInstance().commons.rootDir(),
                            'hotwords')
            hotwordPath = rootPath / f'{self._hotwordName}'
            zipPath = hotwordPath.with_suffix('.zip')

            if zipPath.exists():
                zipPath.unlink()

            if hotwordPath.exists():
                shutil.rmtree(hotwordPath, ignore_errors=True)

            self._logger.logInfo(
                f'Connecting to **{self._host}_{self._port}**')
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((self._host, self._port))

            self._logger.logInfo(
                f'Receiving hotword package: **{self._hotwordName}**')
            sock.settimeout(2)
            try:
                with zipPath.open('wb') as f:
                    while True:
                        data = sock.recv(1024)

                        if not data:
                            break

                        f.write(data)
            except socket.timeout:
                sock.settimeout(None)

        except Exception as e:
            self._logger.logError(f'Error downloading hotword: {e}')
            if sock:
                sock.send(b'-1')
                sock.close()
            return

        try:
            self._logger.logInfo('New hotword received, unpacking...')
            shutil.unpack_archive(filename=zipPath, extract_dir=hotwordPath)

            conf = SuperManager.getInstance(
            ).configManager.getSnipsConfiguration(parent='snips-hotword',
                                                  key='model',
                                                  createIfNotExist=True)
            if not isinstance(conf, list):
                conf = list()

            addSnips = True
            regex = re.compile(f'.*/{hotwordPath}=[0-9.]+$')
            copy = conf.copy()
            for i, hotword in enumerate(copy):
                if hotword.find('/snips_hotword='):
                    addSnips = False
                elif regex.match(hotword):
                    conf.pop(i)

            if addSnips:
                conf.append(str(rootPath / 'snips_hotword=0.53'))

            conf.append(f'{hotwordPath}=0.52')
            SuperManager.getInstance().configManager.updateSnipsConfiguration(
                parent='snips-hotword',
                key='model',
                value=conf,
                createIfNotExist=True)
            subprocess.run(['sudo', 'systemctl', 'restart', 'snips-satellite'])

            sock.send(b'0')
            self._logger.logInfo(
                f'Sucessfully installed new hotword **{self._hotwordName}**')
        except Exception as e:
            self._logger.logError(
                f'Error while unpacking and installing hotword: {e}')
            sock.send(b'-2')
        finally:
            sock.close()
            os.remove(zipPath)
 def __init__(self, *args, **kwargs):
     self._logger = Logger(*args, **kwargs)
class ProjectAliceObject:
    def __init__(self, *args, **kwargs):
        self._logger = Logger(*args, **kwargs)

    def __repr__(self) -> str:
        ret = copy(self.__dict__)
        ret.pop('_logger')
        return json.dumps(ret)

    def __str__(self) -> str:
        return self.__repr__()

    def broadcast(self,
                  method: str,
                  exceptions: list = None,
                  manager=None,
                  **kwargs):
        if not exceptions:
            exceptions = list()

        if isinstance(exceptions, str):
            exceptions = [exceptions]

        if not exceptions and not manager:
            # Prevent infinite loop of broadcaster being broadcasted to re broadcasting
            self.logWarning(
                'Cannot broadcast to itself, the calling method has to be put in exceptions'
            )
            return

        if 'ProjectAlice' not in exceptions:
            exceptions.append('ProjectAlice')

        if not method.startswith('on'):
            method = f'on{method[0].capitalize() + method[1:]}'

        deadManagers = list()
        for name, man in SM.SuperManager.getInstance().managers.items():
            if not man:
                deadManagers.append(name)
                continue

            if (manager
                    and man.name != manager.name) or man.name in exceptions:
                continue

            try:
                func = getattr(man, method, None)
                if func:
                    func(**kwargs)

            except TypeError as e:
                self.logWarning(
                    f'- Failed to broadcast event {method} to {man.name}: {e}')

        for name in deadManagers:
            del SM.SuperManager.getInstance().managers[name]

    def logInfo(self, msg: str):
        self._logger.doLog(function='info',
                           msg=self.decorateLogs(msg),
                           printStack=False)

    def logError(self, msg: str):
        self._logger.doLog(function='error', msg=self.decorateLogs(msg))

    def logDebug(self, msg: str):
        self._logger.doLog(function='debug',
                           msg=self.decorateLogs(msg),
                           printStack=False)

    def logFatal(self, msg: str):
        self._logger.doLog(function='fatal', msg=self.decorateLogs(msg))
        try:
            self.ProjectAlice.onStop()
            exit()
        except:
            exit()

    def logWarning(self, msg: str, printStack: bool = False):
        self._logger.doLog(function='warning',
                           msg=self.decorateLogs(msg),
                           printStack=printStack)

    def logCritical(self, msg: str):
        self._logger.doLog(function='critical', msg=self.decorateLogs(msg))

    def decorateLogs(self, text: str) -> str:
        return f'[{self.__class__.__name__}] {text}'

    def onStart(self):
        pass

    def onStop(self):
        pass

    def onBooted(self):
        pass

    def onFullMinute(self):
        pass

    def onFiveMinute(self):
        pass

    def onQuarterHour(self):
        pass

    def onFullHour(self):
        pass

    @property
    def ProjectAlice(self):
        return SM.SuperManager.getInstance().projectAlice

    @property
    def ConfigManager(self):
        return SM.SuperManager.getInstance().configManager

    @property
    def MqttManager(self):
        return SM.SuperManager.getInstance().mqttManager

    @property
    def DatabaseManager(self):
        return SM.SuperManager.getInstance().databaseManager

    @property
    def ThreadManager(self):
        return SM.SuperManager.getInstance().threadManager

    @property
    def TimeManager(self):
        return SM.SuperManager.getInstance().timeManager

    @property
    def HotwordManager(self):
        return SM.SuperManager.getInstance().hotwordManager

    @property
    def Commons(self):
        return SM.SuperManager.getInstance().commonsManager

    @property
    def NetworkManager(self):
        return SM.SuperManager.getInstance().networkManager
Exemple #24
0
class ProjectAliceObject(object):
    DEPENDENCIES = {'internal': {}, 'external': {}, 'system': [], 'pip': []}

    def __init__(self, *args, **kwargs):
        self._logger = Logger(*args, **kwargs)

    def __repr__(self) -> str:
        ret = copy(self.__dict__)
        ret.pop('_logger')
        return json.dumps(ret)

    def __str__(self) -> str:
        return self.__repr__()

    def broadcast(self,
                  method: str,
                  exceptions: list = None,
                  manager=None,
                  propagateToSkills: bool = False,
                  **kwargs):  # NOSONAR
        if not exceptions:
            exceptions = list()

        if isinstance(exceptions, str):
            exceptions = [exceptions]

        if not exceptions and not manager:
            # Prevent infinite loop of broadcaster being broadcasted to re broadcasting
            self.logWarning(
                'Cannot broadcast to itself, the calling method has to be put in exceptions'
            )
            return

        if 'ProjectAlice' not in exceptions:
            exceptions.append('ProjectAlice')

        if 'DialogManager' not in exceptions:
            exceptions.append('DialogManager')

        if not method.startswith('on'):
            method = f'on{method[0].capitalize() + method[1:]}'

        # Give absolute priority to DialogManager
        try:
            func = getattr(
                SM.SuperManager.getInstance().getManager('DialogManager'),
                method, None)
            if func:
                func(**kwargs)

        except TypeError as e:
            self.logWarning(
                f'Failed to broadcast event **{method}** to **DialogManager**: {e}'
            )

        deadManagers = list()
        for name, man in SM.SuperManager.getInstance().managers.copy().items():
            if not man:
                deadManagers.append(name)
                continue

            if (manager
                    and man.name != manager.name) or man.name in exceptions:
                continue

            try:
                func = getattr(man, method, None)
                if func:
                    func(**kwargs)

            except TypeError as e:
                self.logWarning(
                    f'Failed to broadcast event **{method}** to **{man.name}**: {e}'
                )

        if propagateToSkills:
            self.SkillManager.skillBroadcast(method=method, **kwargs)

        for name in deadManagers:
            del SM.SuperManager.getInstance().managers[name]

        if method == 'onAudioFrame':
            return

        # Now send the event over mqtt
        payload = dict()
        for item, value in kwargs.items():
            try:
                payload[item] = json.dumps(value)
            except:
                # Cannot serialize that attribute, do nothing
                pass

        self.MqttManager.publish(topic=f'projectalice/events/{method}',
                                 payload=payload)

    def checkDependencies(self) -> bool:
        self.logInfo('Checking dependencies')

        for dep in {
                **self.DEPENDENCIES.get('internal', dict()),
                **self.DEPENDENCIES.get('external', dict())
        }:
            result = self.Commons.runRootSystemCommand(
                ['dpkg-query', '-l', dep])
            if result.returncode:
                self.logWarning(f'Found missing dependency: {dep}')
                return False

        for dep in self.DEPENDENCIES['pip']:
            match = re.match(r'^([a-zA-Z0-9-_]*)(?:([=><]{0,2})([\d.]*)$)',
                             dep)
            if not match:
                continue

            packageName, operator, version = match.groups()
            if not packageName:
                self.logWarning('Wrongly declared PIP requirement')
                continue

            try:
                installedVersion = packageVersion(packageName)
            except PackageNotFoundError:
                self.logWarning(f'Found missing dependencies: {packageName}')
                return False

            if not installedVersion or not operator or not version:
                continue

            version = Version.fromString(version)
            installedVersion = Version.fromString(installedVersion)

            if (operator == '==' and version != installedVersion) or \
              (operator == '>=' and installedVersion < version) or \
              (operator == '>' and (installedVersion < version or installedVersion == version)) or \
              (operator == '<' and (installedVersion > version or installedVersion == version)):

                self.logWarning(
                    f'Dependency "{packageName}" is not conform with version requirements'
                )
                return False

        for dep in self.DEPENDENCIES['system']:
            result = self.Commons.runRootSystemCommand(
                ['dpkg-query', '-l', dep])
            if result.returncode:
                self.logWarning(f'Found missing dependency: {dep}')
                return False

        return True

    def installDependencies(self) -> bool:
        self.logInfo('Installing dependencies')

        try:
            for dep, link in self.DEPENDENCIES.get('internal', dict()).items():
                self.logInfo(f'Installing "{dep}"')
                result = self.Commons.runRootSystemCommand(
                    ['apt-get', 'install', '-y', f'./{link}'])
                if result.returncode:
                    raise Exception(result.stderr)

                self.logInfo(f'Installed!')

            for dep, link in self.DEPENDENCIES.get('external', dict()).items():
                self.logInfo(f'Downloading "{dep}"')
                if not self.Commons.downloadFile(link, link.rsplit('/')[-1]):
                    return False

                self.logInfo(f'Installing "{dep}"')
                result = self.Commons.runRootSystemCommand(
                    ['apt-get', 'install', '-y', f'./{link.rsplit("/")[-1]}'])
                if result.returncode:
                    raise Exception(result.stderr)

                Path(link.rsplit('/')[-1]).unlink()

                self.logInfo(f'Installed!')

            for dep in self.DEPENDENCIES['system']:
                self.logInfo(f'Installing "{dep}"')
                result = self.Commons.runRootSystemCommand(
                    ['apt-get', 'install', '-y', dep])
                if result.returncode:
                    raise Exception(result.stderr)

                self.logInfo(f'Installed!')

            for dep in self.DEPENDENCIES['pip']:
                self.logInfo(f'Installing "{dep}"')
                result = self.Commons.runSystemCommand(
                    ['./venv/bin/pip', 'install', dep])
                if result.returncode:
                    raise Exception(result.stderr)

                self.logInfo(f'Installed!')

            return True
        except Exception as e:
            self.logError(f'Installing dependencies failed: {e}')
            return False

    def logInfo(self, msg: str, plural: Union[list, str] = None):
        self._logger.doLog(function='info',
                           msg=self.decorateLogs(msg),
                           printStack=False,
                           plural=plural)

    def logError(self, msg: str, plural: Union[list, str] = None):
        self._logger.doLog(function='error',
                           msg=self.decorateLogs(msg),
                           plural=plural)

    def logDebug(self, msg: str, plural: Union[list, str] = None):
        self._logger.doLog(function='debug',
                           msg=self.decorateLogs(msg),
                           printStack=False,
                           plural=plural)

    def logFatal(self, msg: str, plural: Union[list, str] = None):
        self._logger.doLog(function='fatal',
                           msg=self.decorateLogs(msg),
                           plural=plural)
        try:
            self.ProjectAlice.onStop()
        except:
            exit()

    def logWarning(self,
                   msg: str,
                   printStack: bool = False,
                   plural: Union[list, str] = None):
        self._logger.doLog(function='warning',
                           msg=self.decorateLogs(msg),
                           printStack=printStack,
                           plural=plural)

    def logCritical(self, msg: str, plural: Union[list, str] = None):
        self._logger.doLog(function='critical',
                           msg=self.decorateLogs(msg),
                           plural=plural)

    def decorateLogs(self, text: str) -> str:
        return f'[{self.__class__.__name__}] {text}'

    def onStart(self):
        pass  # Super object function is overridden only if needed

    def onStop(self, **kwargs):
        pass  # Super object function is overridden only if needed

    def onBooted(self):
        pass  # Super object function is overridden only if needed

    def onSkillInstalled(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onSkillDeleted(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onSkillUpdated(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onSkillUpdating(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onSkillStarted(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onSkillStopped(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onSkillActivated(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onSkillDeactivated(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onInternetConnected(self):
        pass  # Super object function is overridden only if needed

    def onInternetLost(self):
        pass  # Super object function is overridden only if needed

    def onHotword(self, deviceUid: str, user: str = constants.UNKNOWN_USER):
        pass  # Super object function is overridden only if needed

    def onHotwordToggleOn(self, deviceUid: str, session):
        pass  # Super object function is overridden only if needed

    def onHotwordToggleOff(self, deviceUid: str, session):
        pass  # Super object function is overridden only if needed

    def onSessionStarted(self, session):
        pass  # Super object function is overridden only if needed

    def onContinueSession(self, session):
        pass  # Super object function is overridden only if needed

    def onAsrToggleOn(self, deviceUid: str):
        pass  # Super object function is overridden only if needed

    def onAsrToggleOff(self, deviceUid: str):
        pass  # Super object function is overridden only if needed

    def onStartListening(self, session):
        pass  # Super object function is overridden only if needed

    def onStopListening(self, session):
        pass  # Super object function is overridden only if needed

    def onCaptured(self, session):
        pass  # Super object function is overridden only if needed

    def onNluQuery(self, session):
        pass  # Super object function is overridden only if needed

    def onIntentParsed(self, session):
        pass  # Super object function is overridden only if needed

    def onIntent(self, session):
        pass  # Super object function is overridden only if needed

    def onConfigureIntent(self, intents: list):
        pass  # Super object function is overridden only if needed

    def onUserCancel(self, session):
        pass  # Super object function is overridden only if needed

    def onSessionTimeout(self, session):
        pass  # Super object function is overridden only if needed

    def onIntentNotRecognized(self, session):
        pass  # Super object function is overridden only if needed

    def onNluIntentNotRecognized(self, session):
        pass  # Super object function is overridden only if needed

    def onNluError(self, session):
        pass  # Super object function is overridden only if needed

    def onSessionError(self, session):
        pass  # Super object function is overridden only if needed

    def onStartSession(self, deviceUid: str, payload: dict):
        pass  # Super object function is overridden only if needed

    def onSessionEnded(self, session):
        pass  # Super object function is overridden only if needed

    def onSay(self, session):
        pass  # Super object function is overridden only if needed

    def onSayFinished(self, session, uid: str = None):
        pass  # Super object function is overridden only if needed

    def onSessionQueued(self, session):
        pass  # Super object function is overridden only if needed

    def onMessage(self, session) -> bool:  # NOSONAR
        """ Do not consume the intent by default """
        return False

    def onSleep(self):
        pass  # Super object function is overridden only if needed

    def onWakeup(self):
        pass  # Super object function is overridden only if needed

    def onGoingBed(self):
        pass  # Super object function is overridden only if needed

    def onLeavingHome(self):
        pass  # Super object function is overridden only if needed

    def onReturningHome(self):
        pass  # Super object function is overridden only if needed

    def onEating(self):
        pass  # Super object function is overridden only if needed

    def onWatchingTV(self):
        pass  # Super object function is overridden only if needed

    def onCooking(self):
        pass  # Super object function is overridden only if needed

    def onMakeup(self):
        pass  # Super object function is overridden only if needed

    def onContextSensitiveDelete(self, session):
        pass  # Super object function is overridden only if needed

    def onContextSensitiveEdit(self, session):
        pass  # Super object function is overridden only if needed

    def onFullMinute(self):
        pass  # Super object function is overridden only if needed

    def onFiveMinute(self):
        pass  # Super object function is overridden only if needed

    def onQuarterHour(self):
        pass  # Super object function is overridden only if needed

    def onFullHour(self):
        pass  # Super object function is overridden only if needed

    def onWakeword(self, deviceUid: str, user: str = constants.UNKNOWN_USER):
        pass  # Super object function is overridden only if needed

    def onMotionDetected(self):
        pass  # Super object function is overridden only if needed

    def onMotionStopped(self):
        pass  # Super object function is overridden only if needed

    def onButtonPressed(self):
        pass  # Super object function is overridden only if needed

    def onButtonReleased(self):
        pass  # Super object function is overridden only if needed

    def onDeviceDiscovered(self, device, uid: str):
        pass  # Super object function is overridden only if needed

    def onDeviceAdded(self, device, uid: str):
        pass  # Super object function is overridden only if needed

    def onDeviceRemoved(self, device, uid: str):
        pass  # Super object function is overridden only if needed

    def onDeviceConnecting(self):
        pass  # Super object function is overridden only if needed

    def onDeviceDisconnecting(self):
        pass  # Super object function is overridden only if needed

    def onUVIndexAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onRaining(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onTooMuchRain(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onWindy(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onFreezing(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onTemperatureHighAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onTemperatureLowAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onCOTwoAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onHumidityHighAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onHumidityLowAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onNoiseAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onPressureHighAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onGasAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onPressureLowAlert(self, *args, **kwargs):
        pass  # Super object function is overridden only if needed

    def onBroadcastingForNewDeviceStart(self):
        pass  # Super object function is overridden only if needed

    def onBroadcastingForNewDeviceStop(self, *args):
        pass  # Super object function is overridden only if needed

    def onAuthenticated(self, session):
        pass  # Super object function is overridden only if needed

    def onAuthenticationFailed(self, session):
        pass  # Super object function is overridden only if needed

    def onAudioFrame(self, **kwargs):
        pass  # Super object function is overridden only if needed

    def onAssistantInstalled(self, **kwargs):
        pass  # Super object function is overridden only if needed

    def onAssistantFailedTraining(self, **kwargs):
        pass  # Super object function is overridden only if needed

    def onSkillInstallFailed(self, skill: str):
        pass  # Super object function is overridden only if needed

    def onNluTrained(self, **kwargs):
        pass  # Super object function is overridden only if needed

    def onVadUp(self, **kwargs):
        pass  # Super object function is overridden only if needed

    def onVadDown(self, **kwargs):
        pass  # Super object function is overridden only if needed

    def onPlayBytes(self,
                    payload: bytearray,
                    deviceUid: str,
                    sessionId: str = None):
        pass  # Super object function is overridden only if needed

    def onPlayBytesFinished(self, deviceUid: str, sessionId: str = None):
        pass  # Super object function is overridden only if needed

    def onToggleFeedbackOn(self, deviceUid: str):
        pass  # Super object function is overridden only if needed

    def onToggleFeedbackOff(self, deviceUid: str):
        pass  # Super object function is overridden only if needed

    def onPartialTextCaptured(self, session, text: str, likelihood: float,
                              seconds: float):
        pass  # Super object function is overridden only if needed

    def onEndSession(self, session, reason: str = 'nominal'):
        pass  # Super object function is overridden only if needed

    def onDeviceHeartbeat(self, uid: str, deviceUid: str = None):
        pass  # Super object function is overridden only if needed

    def onDeviceStatus(self, session):
        pass  # Super object function is overridden only if needed

    @property
    def ProjectAlice(self) -> ProjectAlice:  # NOSONAR
        return SM.SuperManager.getInstance().projectAlice

    @property
    def ConfigManager(self) -> ConfigManager:  # NOSONAR
        return SM.SuperManager.getInstance().configManager

    @property
    def SkillManager(self) -> SkillManager:  # NOSONAR
        return SM.SuperManager.getInstance().skillManager

    @property
    def DeviceManager(self) -> DeviceManager:  # NOSONAR
        return SM.SuperManager.getInstance().deviceManager

    @property
    def MultiIntentManager(self) -> MultiIntentManager:  # NOSONAR
        return SM.SuperManager.getInstance().multiIntentManager

    @property
    def MqttManager(self) -> MqttManager:  # NOSONAR
        return SM.SuperManager.getInstance().mqttManager

    @property
    def UserManager(self) -> UserManager:  # NOSONAR
        return SM.SuperManager.getInstance().userManager

    @property
    def DatabaseManager(self) -> DatabaseManager:  # NOSONAR
        return SM.SuperManager.getInstance().databaseManager

    @property
    def InternetManager(self) -> InternetManager:  # NOSONAR
        return SM.SuperManager.getInstance().internetManager

    @property
    def TelemetryManager(self) -> TelemetryManager:  # NOSONAR
        return SM.SuperManager.getInstance().telemetryManager

    @property
    def ThreadManager(self) -> ThreadManager:  # NOSONAR
        return SM.SuperManager.getInstance().threadManager

    @property
    def TimeManager(self) -> TimeManager:  # NOSONAR
        return SM.SuperManager.getInstance().timeManager

    @property
    def ASRManager(self) -> ASRManager:  # NOSONAR
        return SM.SuperManager.getInstance().asrManager

    @property
    def LanguageManager(self) -> LanguageManager:  # NOSONAR
        return SM.SuperManager.getInstance().languageManager

    @property
    def TalkManager(self) -> TalkManager:  # NOSONAR
        return SM.SuperManager.getInstance().talkManager

    @property
    def TTSManager(self) -> TTSManager:  # NOSONAR
        return SM.SuperManager.getInstance().ttsManager

    @property
    def WakewordRecorder(self) -> WakewordRecorder:  # NOSONAR
        return SM.SuperManager.getInstance().wakewordRecorder

    @property
    def ApiManager(self) -> ApiManager:  # NOSONAR
        return SM.SuperManager.getInstance().apiManager

    @property
    def Commons(self) -> CommonsManager:  # NOSONAR
        return SM.SuperManager.getInstance().commonsManager

    @property
    def SkillStoreManager(self) -> SkillStoreManager:  # NOSONAR
        return SM.SuperManager.getInstance().skillStoreManager

    @property
    def NluManager(self) -> NluManager:  # NOSONAR
        return SM.SuperManager.getInstance().nluManager

    @property
    def DialogTemplateManager(self) -> DialogTemplateManager:  # NOSONAR
        return SM.SuperManager.getInstance().dialogTemplateManager

    @property
    def AssistantManager(self) -> AssistantManager:  # NOSONAR
        return SM.SuperManager.getInstance().assistantManager

    @property
    def AliceWatchManager(self) -> AliceWatchManager:  # NOSONAR
        return SM.SuperManager.getInstance().aliceWatchManager

    @property
    def AudioServer(self) -> AudioManager:  # NOSONAR
        return SM.SuperManager.getInstance().audioManager

    @property
    def DialogManager(self) -> DialogManager:  # NOSONAR
        return SM.SuperManager.getInstance().dialogManager

    @property
    def LocationManager(self) -> LocationManager:  # NOSONAR
        return SM.SuperManager.getInstance().locationManager

    @property
    def WakewordManager(self) -> WakewordManager:  # NOSONAR
        return SM.SuperManager.getInstance().wakewordManager

    @property
    def NodeRedManager(self) -> NodeRedManager:  # NOSONAR
        return SM.SuperManager.getInstance().nodeRedManager

    @property
    def WidgetManager(self) -> WidgetManager:  # NOSONAR
        return SM.SuperManager.getInstance().widgetManager

    @property
    def StateManager(self) -> StateManager:  # NOSONAR
        return SM.SuperManager.getInstance().stateManager

    @property
    def WebUIManager(self) -> WebUIManager:  # NOSONAR
        return SM.SuperManager.getInstance().webUiManager

    @property
    def SubprocessManager(self) -> SubprocessManager:  # NOSONAR
        return SM.SuperManager.getInstance().subprocessManager

    @property
    def WebUINotificationManager(self) -> WebUINotificationManager:  # NOSONAR
        return SM.SuperManager.getInstance().webUINotificationManager

    @property
    def BugReportManager(self) -> BugReportManager:  # NOSONAR
        return SM.SuperManager.getInstance().bugReportManager
Exemple #25
0
class ProjectAlice(Singleton):
    NAME = 'ProjectAlice'

    def __init__(self, restartHandler: callable):
        Singleton.__init__(self, self.NAME)
        self._logger = Logger()
        self._logger.logInfo('Starting up Project Alice')
        self._booted = False
        with Stopwatch() as stopWatch:
            self._restart = False
            self._restartHandler = restartHandler
            self._superManager = SuperManager(self)

            self._superManager.initManagers()
            self._superManager.onStart()

            if self._superManager.configManager.getAliceConfigByName('useHLC'):
                self._superManager.commons.runRootSystemCommand(
                    ['systemctl', 'start', 'hermesledcontrol'])

            self._superManager.onBooted()
        self._logger.logInfo(f'- Started Project Alice in {stopWatch} seconds')
        self._booted = True

    @property
    def name(self) -> str:
        return self.NAME

    @property
    def isBooted(self) -> bool:
        return self._booted

    @property
    def restart(self) -> bool:
        return self._restart

    @restart.setter
    def restart(self, value: bool):
        self._restart = value

    def doRestart(self):
        self._restart = True
        self.onStop()

    def onStop(self):
        self._logger.logInfo('Shutting down Project Alice')
        self._superManager.onStop()
        if self._superManager.configManager.getAliceConfigByName('useHLC'):
            self._superManager.commons.runRootSystemCommand(
                ['systemctl', 'stop', 'hermesledcontrol'])

        self.INSTANCE = None
        self._restartHandler()

    def wipeAll(self):
        # Set as restarting so skills don't install / update
        self._restart = True

        self._superManager.skillManager.wipeSkills()
        self._superManager.databaseManager.clearDB()
        self._superManager.dialogTemplateManager.clearCache(False)
        self._superManager.nluManager.clearCache()
        self._superManager.snipsAssistantManager.clearData()

    def updateProjectAlice(self):
        self._logger.logInfo('Checking Project Alice updates')
        req = requests.get(
            url=f'{constants.GITHUB_API_URL}/ProjectAlice/branches',
            auth=SuperManager.getInstance().configManager.getGithubAuth())
        if req.status_code != 200:
            self._logger.logWarning('Failed checking for updates')
            return

        userUpdatePref = SuperManager.getInstance(
        ).configManager.getAliceConfigByName('aliceUpdateChannel')

        if userUpdatePref == 'master':
            candidate = 'master'
        else:
            candidate = Version.fromString(constants.VERSION)
            for branch in req.json():
                repoVersion = Version.fromString(branch['name'])
                if not repoVersion.isVersionNumber:
                    continue

                releaseType = repoVersion.releaseType
                if userUpdatePref == 'rc' and releaseType in {
                        'b', 'a'
                } or userUpdatePref == 'beta' and releaseType == 'a':
                    continue

                if repoVersion > candidate:
                    candidate = repoVersion

        self._logger.logInfo(f'Checking on "{str(candidate)}" update channel')
        commons = SuperManager.getInstance().commons
        commons.runSystemCommand(['git', '-C', commons.rootDir(), 'stash'])
        commons.runSystemCommand(
            ['git', '-C', commons.rootDir(), 'clean', '-df'])
        commons.runSystemCommand(
            ['git', '-C',
             commons.rootDir(), 'checkout',
             str(candidate)])
        commons.runSystemCommand(['git', '-C', commons.rootDir(), 'pull'])

        # Remove install tickets
        [
            file.unlink() for file in Path(
                commons.rootDir(), 'system/skillInstallTickets').glob('*')
            if file.is_file()
        ]
class WakewordUploadThread(Thread):
    def __init__(self, host: str, port: int, zipPath: str):
        super().__init__()
        self._logger = Logger()

        self.setDaemon(True)

        self._host = host
        self._port = port
        self._zipPath = Path(zipPath)

    def run(self):
        try:
            wakewordName = self._zipPath.stem

            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
                sock.bind((self._host, self._port))
                self._logger.logInfo('Waiting for a device to connect')
                sock.listen()

                conn, addr = sock.accept()
                self._logger.logInfo(f'New device connected: {addr}')

                with self._zipPath.open(mode='rb') as f:
                    data = f.read(1024)
                    while data:
                        conn.send(data)
                        data = f.read(1024)

                self._logger.logInfo(f'Waiting on a feedback from {addr[0]}')
                conn.settimeout(20)
                try:
                    while True:
                        answer = conn.recv(1024).decode()
                        if not answer:
                            self._logger.logInfo(
                                'The device closed the connection before confirming...'
                            )
                            break

                        if answer == '0':
                            self._logger.logInfo(
                                f'Wakeword "{wakewordName}" upload to {addr[0]} success'
                            )
                            break
                        elif answer == '-1':
                            self._logger.logWarning(
                                'The device failed downloading the hotword')
                            break
                        elif answer == '-2':
                            self._logger.logWarning(
                                'The device failed installing the hotword')
                            break
                except timeout:
                    self._logger.logWarning(
                        'The device did not confirm the operation as successfull in time. The hotword installation might have failed'
                    )
        except Exception as e:
            self._logger.logInfo(f'Error uploading wakeword: {e}')
Exemple #27
0
class Light:
    state: dict
    swupdate: dict
    type: str
    name: str
    modelid: str
    manufacturername: str
    productname: str
    capabilities: dict
    config: dict
    uniqueid: str
    swversion: str
    swconfigid: str = ''
    productid: str = ''
    id: int = 0
    bridge: Optional[Bridge] = None
    myScenes: list = field(default_factory=list)
    logger: Optional[Logger] = None

    def init(self, lightId: int, bridgeInstance: Bridge):
        self.id = lightId
        self.bridge = bridgeInstance
        self.name = self.name.lower()
        self.logger = Logger(prepend='[Phue Light]')

    def __str__(self) -> str:
        return f'Light id {self.id} named "{self.name}" of type {self.type}.'

    def on(self):  #NOSONAR
        self.request(url=f'/{self.id}/state', method='PUT', data={'on': True})

    def off(self):
        self.request(url=f'/{self.id}/state', method='PUT', data={'on': False})

    @property
    def isOn(self) -> bool:
        return self.state['on']

    @property
    def isOff(self) -> bool:
        return not self.state['on']

    def alert(self, state: str = 'lselect'):
        self.request(url=f'/{self.id}/state',
                     method='PUT',
                     data={'alert': state})

    def effect(self, effect: str = 'colorloop'):
        self.request(url=f'/{self.id}/state',
                     method='PUT',
                     data={'effect': effect})

    def configure(self, data: dict, sendToBridge: bool = True):
        for key, value in data.items():
            if not key in self.state:
                continue

            self.state[key] = value

        if sendToBridge:
            self.request(url=f'/{self.id}/state', method='PUT', data=data)

    @property
    def brightness(self) -> int:
        return self.state['bri']

    @brightness.setter
    def brightness(self, value: int):
        if value == 0:
            self.off()
            self.state['bri'] = 0
            return

        value = sorted((1, value, 254))[1]

        self.state['bri'] = value
        self.request(url=f'/{self.id}/state',
                     method='PUT',
                     data={'bri': value})

    @property
    def saturation(self) -> int:
        return self.state['sat']

    @saturation.setter
    def saturation(self, value: int):
        value = sorted((1, value, 254))[1]

        self.state['sat'] = value
        self.request(url=f'/{self.id}/state',
                     method='PUT',
                     data={'sat': value})

    @property
    def hue(self) -> int:
        return self.state['hue']

    @hue.setter
    def hue(self, value: int):
        value = sorted((0, value, 65535))[1]

        self.state['hue'] = value
        self.request(url=f'/{self.id}/state',
                     method='PUT',
                     data={'hue': value})

    @property
    def xy(self) -> list:  #NOSONAR
        return self.state['xy']

    @xy.setter
    def xy(self, value: list):  #NOSONAR
        x = sorted((0, value[0], 1))[1]  #NOSONAR
        y = sorted((0, value[1], 1))[1]  #NOSONAR

        self.state['xy'] = [x, y]
        self.request(url=f'/{self.id}/state', method='PUT', data={'xy': value})

    @property
    def mired(self) -> int:
        return self.state['ct']

    @mired.setter
    def mired(self, value: int):
        self.state['ct'] = value
        self.request(url=f'/{self.id}/state', method='PUT', data={'ct': value})

    @property
    def colormode(self) -> str:
        return self.state.get('colormode', None)

    @colormode.setter
    def colormode(self, mode: str):
        if 'colormode' not in self.state:
            self.logger.logWarning(
                f'Light {self.name} with id {self.id} does not support colormode changing'
            )
            return

        if mode not in ('hs', 'xy', 'ct'):
            mode = 'ct'
            self.logger.logWarning(
                'Invalid color mode specified. Allowed value are "hs", "ct", "xy"'
            )

        self.state['colormode'] = mode
        self.request(url=f'/{self.id}/state',
                     method='PUT',
                     data={'colormode': mode})

    @property
    def reachable(self) -> bool:
        return self.state['reachable']

    def delete(self):
        self.request(url=f'/{self.id}', method='DELETE')

    def request(self, url: str, data: dict = None, method: str = 'GET'):
        if not self.reachable or not self.bridge:
            raise LightNotReachable

        self.bridge.sendAuthRequest(
            url=f'/lights{"/" if not url.startswith("/") else ""}{url}',
            method=method,
            data=data)
Exemple #28
0
 def __init__(self, logDepth: int = 3, *args, **kwargs):
     self._depth = logDepth
     self._logger = Logger(logDepth)
Exemple #29
0
 def init(self, lightId: int, bridgeInstance: Bridge):
     self.id = lightId
     self.bridge = bridgeInstance
     self.name = self.name.lower()
     self.logger = Logger(prepend='[Phue Light]')
class ProjectAlice(Singleton):
	NAME = 'ProjectAlice'


	def __init__(self, restartHandler: callable):
		Singleton.__init__(self, self.NAME)
		self._logger = Logger(prepend='[Project Alice]')
		self._logger.logInfo('Starting Alice satellite unit')
		self._booted = False
		with Stopwatch() as stopWatch:
			self._restart = False
			self._restartHandler = restartHandler
			self._superManager = SuperManager(self)

			self._superManager.initManagers()
			self._superManager.onStart()

			if self._superManager.configManager.getAliceConfigByName('useHLC'):
				self._superManager.commons.runRootSystemCommand(['systemctl', 'start', 'hermesledcontrol'])

			self._superManager.onBooted()

		self._logger.logInfo(f'Started in {stopWatch} seconds')
		self._booted = True


	@property
	def name(self) -> str:
		return self.NAME


	@property
	def isBooted(self) -> bool:
		return self._booted


	@property
	def restart(self) -> bool:
		return self._restart


	@restart.setter
	def restart(self, value: bool):
		self._restart = value


	def doRestart(self):
		self._restart = True
		self.onStop()


	def onStop(self):
		self._logger.logInfo('Shutting down')
		self._superManager.onStop()
		if self._superManager.configManager.getAliceConfigByName('useHLC'):
			self._superManager.commons.runRootSystemCommand(['systemctl', 'stop', 'hermesledcontrol'])

		self.INSTANCE = None
		self._restartHandler()


	def updateProjectAlice(self):
		self._logger.logInfo('Checking for satellite updates')
		req = requests.get(url=f'{constants.GITHUB_API_URL}/ProjectAliceSatellite/branches', auth=SuperManager.getInstance().configManager.getGithubAuth())
		if req.status_code != 200:
			self._logger.logWarning('Failed checking for updates')
			return

		userUpdatePref = SuperManager.getInstance().configManager.getAliceConfigByName('aliceUpdateChannel')

		if userUpdatePref == 'master':
			candidate = 'master'
		else:
			candidate = Version.fromString(constants.VERSION)
			for branch in req.json():
				repoVersion = Version.fromString(branch['name'])
				if not repoVersion.isVersionNumber:
					continue

				releaseType = repoVersion.releaseType
				if userUpdatePref == 'rc' and releaseType in {'b', 'a'} or userUpdatePref == 'beta' and releaseType == 'a':
					continue

				if repoVersion > candidate:
					candidate = repoVersion

		self._logger.logInfo(f'Checking on "{str(candidate)}" update channel')
		commons = SuperManager.getInstance().commons
		commons.runSystemCommand(['git', '-C', commons.rootDir(), 'stash'])
		commons.runSystemCommand(['git', '-C', commons.rootDir(), 'clean', '-df'])
		commons.runSystemCommand(['git', '-C', commons.rootDir(), 'checkout', str(candidate)])
		commons.runSystemCommand(['git', '-C', commons.rootDir(), 'pull'])