Example #1
0
 def db_3_update(self, resourcePath):
     ''' convert all "rgb" to "hsb" '''
     from com.cloudMedia.theKuroBox.sdk.util.colorUtils import ColorUtils
     
     for idCol, tableName in [("reId", "rule_execution"), ("seId", "scene_execution")]:
     
         toBeUpdateds = deque()
         rows = self.__con.execute('SELECT "' + idCol + '", "kbxMethodParams" ' + \
                                   'FROM "' + tableName + '" ' + \
                                   'WHERE "kbxMethodParams" LIKE ?', ('%"r"%', )).fetchall()
         for row in rows:
             methodRow = dict(row)
             kbxMethodParams = methodRow["kbxMethodParams"]
             for kbxMethodParam in kbxMethodParams:
                 kbxParamCurrentValue = kbxMethodParam["kbxParamCurrentValue"]
                 if isinstance(kbxParamCurrentValue, dict):
                     if not {"r", "g", "b"}.difference(kbxParamCurrentValue):
                         hsbDict = ColorUtils.rgb_to_hsb(kbxParamCurrentValue["r"], 
                                                         kbxParamCurrentValue["g"], 
                                                         kbxParamCurrentValue["b"])
                         kbxMethodParam["kbxParamCurrentValue"] = hsbDict
                         toBeUpdateds.append(methodRow)
         
         for methodRow in toBeUpdateds:
             self.__con.execute('UPDATE "' + tableName + '" SET "kbxMethodParams"=? WHERE "' + idCol + '"=?', 
                                (methodRow["kbxMethodParams"], methodRow[idCol]))
             
         Logger.log_info("Database v3 update: RGB -> HSB (%i entries from %s migrated)" % (len(toBeUpdateds), str(tableName)))    
             
     Logger.log_info("Database v3 update completed")
Example #2
0
    def __broadcast_message__favorited_scene_added(self, sceneId, prevSceneId):
        eventTag = AppConstants.EVENT_FAVORITED_SCENE_ADDED
        eventData = {"sceneId": sceneId, "prevSceneId": prevSceneId}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Favorited scene added/updated: Id", sceneId,
                        "prevId:", prevSceneId)
Example #3
0
 def start(self):
     '''
     Initialize all services required by automation app.
     '''
     MethodController.instance() # Must listen to groups and methods added event before bootstrap.
     
     # Bootstrap
     try:
         bs = BootstrapService()
         Logger.log_info("Bootstrap update kbx method ...")
         bs.update_kbx_method()
         Logger.log_info("Bootstrap update kbx group ...")
         bs.update_kbx_group()
         Logger.log_info("Bootstrap register trigger schedulers ...")
         bs.register_trigger_schedulers()
         Logger.log_info("Bootstrap register timer module schedulers ...")
         bs.register_timer_module_schedulers()
     except Exception as e:
         bs.rollback()
         Logger.log_error("AutomationModuleWrapper.start bootstrap ex:", e)
         traceback.print_exc()
         raise e
     else:
         bs.commit()
         Logger.log_info("Bootstrap process completed!")
     
     self.__apiService = APIService()
     self.__ruleService = RuleService()
     self.__sceneService = SceneService()
     self.__serService = SceneExecutionResultService.instance()
Example #4
0
    def __broadcast_message__scene_update_started(self,
                                                  sceneId,
                                                  sceneName=None):
        eventTag = AppConstants.EVENT_SCENE_UPDATE_STARTED
        eventData = {"sceneId": sceneId, "newSceneName": sceneName}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Scene Start Update:", sceneName)
Example #5
0
    def post_system_connected(self):
        super().post_system_connected()

        Logger.log_info("post_system_connected starts...")

        DebugModule.DEBUG_POST_SYSTEM_CONNECTED.append(time.time())

        self.__automationModule.start()

        Logger.log_info("post_system_connected ends...")
Example #6
0
    def post_system_connected(self):
        super().post_system_connected()
        
        Logger.log_info("post_system_connected starts...")

        DebugModule.DEBUG_POST_SYSTEM_CONNECTED.append(time.time())
        
        self.__automationModule.start()
        
        Logger.log_info("post_system_connected ends...")
Example #7
0
    def __broadcast_message__scene_updated(self, sceneId):
        try:
            scene = self.__sceneController.get_summary(sceneId)
        except Exception as e:
            Logger.log_error("SceneService.__broadcast_message__scene_updated get_summary ex:", e)
            scene = None
            
        eventTag = AppConstants.EVENT_SCENE_UPDATED
        eventData = {"sceneId":sceneId, "newSceneSummary":scene}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Scene Updated:", scene["sceneName"])
Example #8
0
    def __broadcast_message__rule_updated(self, ruleId):
        try:
            rule = self.__ruleController.get_summary(ruleId)
        except Exception as e:
            Logger.log_error("RuleService.__broadcast_message__rule_updated get_summary ex:", e)
            return

        eventTag = AppConstants.EVENT_RULE_UPDATED
        eventData = rule
        
        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Rule Updated:", rule["ruleName"])
Example #9
0
    def __broadcast_message__scene_updated(self, sceneId):
        try:
            scene = self.__sceneController.get_summary(sceneId)
        except Exception as e:
            Logger.log_error(
                "SceneService.__broadcast_message__scene_updated get_summary ex:",
                e)
            scene = None

        eventTag = AppConstants.EVENT_SCENE_UPDATED
        eventData = {"sceneId": sceneId, "newSceneSummary": scene}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Scene Updated:", scene["sceneName"])
Example #10
0
    def __broadcast_message__scene_update_failed(self, sceneId, sceneName=None):
        '''
        sceneName - For debugging purpose.
        '''
        try:
            scene = self.__sceneController.get_summary(sceneId)
        except Exception:
            scene = None
        
        eventTag = AppConstants.EVENT_SCENE_UPDATE_FAILED
        eventData = {"sceneId": sceneId, "oldSceneSummary":scene}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Scene Update Failed:", sceneName)
Example #11
0
    def __broadcast_message__rule_update_failed(self, ruleId, ruleName=None):
        '''
        ruleName - For debugging purpose.
        '''
        try:
            rule = self.__ruleController.get_summary(ruleId)
        except Exception:
            rule = None

        eventTag = AppConstants.EVENT_RULE_UPDATE_FAILED
        eventData = {"ruleId": ruleId, "oldRuleSummary": rule}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Rule Update Failed:", ruleName)
Example #12
0
    def __broadcast_message__rule_updated(self, ruleId):
        try:
            rule = self.__ruleController.get_summary(ruleId)
        except Exception as e:
            Logger.log_error(
                "RuleService.__broadcast_message__rule_updated get_summary ex:",
                e)
            return

        eventTag = AppConstants.EVENT_RULE_UPDATED
        eventData = rule

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Rule Updated:", rule["ruleName"])
Example #13
0
    def __broadcast_message__rule_update_failed(self, ruleId, ruleName=None):
        '''
        ruleName - For debugging purpose.
        '''
        try:
            rule = self.__ruleController.get_summary(ruleId)
        except Exception:
            rule = None
        
        eventTag = AppConstants.EVENT_RULE_UPDATE_FAILED
        eventData = {"ruleId": ruleId, "oldRuleSummary":rule}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Rule Update Failed:", ruleName)
Example #14
0
    def __broadcast_message__scene_update_failed(self,
                                                 sceneId,
                                                 sceneName=None):
        '''
        sceneName - For debugging purpose.
        '''
        try:
            scene = self.__sceneController.get_summary(sceneId)
        except Exception:
            scene = None

        eventTag = AppConstants.EVENT_SCENE_UPDATE_FAILED
        eventData = {"sceneId": sceneId, "oldSceneSummary": scene}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Scene Update Failed:", sceneName)
Example #15
0
    def db_3_update(self, resourcePath):
        ''' convert all "rgb" to "hsb" '''
        from com.cloudMedia.theKuroBox.sdk.util.colorUtils import ColorUtils

        for idCol, tableName in [("reId", "rule_execution"),
                                 ("seId", "scene_execution")]:

            toBeUpdateds = deque()
            rows = self.__con.execute('SELECT "' + idCol + '", "kbxMethodParams" ' + \
                                      'FROM "' + tableName + '" ' + \
                                      'WHERE "kbxMethodParams" LIKE ?', ('%"r"%', )).fetchall()
            for row in rows:
                methodRow = dict(row)
                kbxMethodParams = methodRow["kbxMethodParams"]
                for kbxMethodParam in kbxMethodParams:
                    kbxParamCurrentValue = kbxMethodParam[
                        "kbxParamCurrentValue"]
                    if isinstance(kbxParamCurrentValue, dict):
                        if not {"r", "g", "b"
                                }.difference(kbxParamCurrentValue):
                            hsbDict = ColorUtils.rgb_to_hsb(
                                kbxParamCurrentValue["r"],
                                kbxParamCurrentValue["g"],
                                kbxParamCurrentValue["b"])
                            kbxMethodParam["kbxParamCurrentValue"] = hsbDict
                            toBeUpdateds.append(methodRow)

            for methodRow in toBeUpdateds:
                self.__con.execute(
                    'UPDATE "' + tableName +
                    '" SET "kbxMethodParams"=? WHERE "' + idCol + '"=?',
                    (methodRow["kbxMethodParams"], methodRow[idCol]))

            Logger.log_info(
                "Database v3 update: RGB -> HSB (%i entries from %s migrated)"
                % (len(toBeUpdateds), str(tableName)))

        Logger.log_info("Database v3 update completed")
Example #16
0
 def db_2_update(self, resourcePath):
     self.__execute_script("/".join([resourcePath, "tablestructure.sql"]))
     Logger.log_info("Database v2 update: Table structures built")
     
     Logger.log_info("Database v2 update completed")
Example #17
0
    def db_1_update(self, resourcePath):
        
        Logger.log_info("Database v1 update started")
                
        self.__execute_script("/".join([resourcePath, "tablestructure.sql"]))
        Logger.log_info("Database v1 update: Table structures built")
        
        # #################### Migration codes ####################
        try:
            from automationApp.migration.storage import Storage
            allGroups = Storage.list_all_groups()
            if len(allGroups) > 0: # Probably no rule is set.
                '''
                All Groups: e.g. {25: 'Yeelight Blue II'}
                '''
                for kbxGroupId, kbxGroupLabel in allGroups.items():
                    self.__con.execute('INSERT INTO "kbx_group"("kbxGroupId", "kbxGroupLabel", "kbxGroupStatus") VALUES (?, ?, ?)', 
                                       (kbxGroupId, kbxGroupLabel, -1))
                del(allGroups)
                    
                '''
                All Groups Methods: e.g. {69: 25, 71: 25}
                '''
                allMethodGroups = Storage.list_all_method_groups()
                for kbxMethodId, kbxGroupId in allMethodGroups.items():
                    self.__con.execute('INSERT INTO "kbx_method"("kbxMethodId", "kbxGroupId", "kbxMethodStatus") ' + \
                                       'VALUES (?, ?, ?)',
                                       (kbxMethodId, kbxGroupId, -1))
                    
                '''
                All Rules: e.g. [{
                    'execution': [{'kbxMethodId': 71, 'kbxMethodParams': [{'kbxParamCurrentValue': '4', 'kbxParamName': 'pairedDeviceId'},{'kbxParamCurrentValue': [False], 'kbxParamName': 'on'}]}], 
                    'trigger': {'type': 0, 'value': None}, 
                    'ruleId': '1425284835.0756288', 
                    'enabled': True, 
                    'condition': [{'kbxMethodId': 69, 'kbxMethodParams': [{'kbxParamCurrentValue': '4', 'kbxParamName': 'pairedDeviceId'}, {'kbxParamCurrentValue': [True], 'kbxParamName': 'on'}]}], 
                    'ruleName': 'ReTestet'
                }]
                '''
                allRules = Storage.list_all_rules()
                cursor = self.__con.cursor()
                createdTime = updatedTime = time.time()
                triggerController = TriggerController.instance()
                for sort, rule in enumerate(allRules):
                    trigger = triggerController.parse_to_trigger_dto(rule["trigger"])
                    cursor.execute('INSERT INTO "rule"("ruleName", "ruleProtected", "trigger", "enabled", "statusProcessed", "createdTime", "updatedTime", "sort") ' + \
                                   'VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
                                   (rule["ruleName"], False, json.dumps(trigger), 
                                    rule["enabled"], "updated", createdTime, 
                                    updatedTime, sort))
                    
                    ruleId = cursor.lastrowid
                    for vals in (["execution", "rule_execution", "reRuleId"], ["condition", "rule_condition", "rcRuleId"]):
                        for kbxMethodSort, kbxMethodWithCurrentValue in enumerate(rule[vals[0]]):
                            self.__con.execute('INSERT INTO "' + vals[1] + '"("' + vals[2] + '", "kbxMethodId", "kbxMethodParams", "createdTime", "sort") ' + \
                                               'VALUES (?, ?, ?, ?, ?)',
                                               (ruleId, kbxMethodWithCurrentValue["kbxMethodId"], 
                                                json.dumps(kbxMethodWithCurrentValue["kbxMethodParams"]), 
                                                createdTime, kbxMethodSort))
                cursor.close()
                del(allRules)
                
                self.__con.commit()
                
        except Exception as e:
            self.__con.rollback()
            Logger.log_warning("Database failed to migrate rules from system, ex:", e , "---- rolled back")
            
        else:
            Logger.log_info("Database v1 update: Rules migrated")
            try:
                Storage.delete_all_rules()
                Storage.delete_all_method_groups()
                Storage.delete_all_groups()
            except Exception as e:
                Logger.log_warning("Database failed to remove rules from system after migration, ex:", e)
        # #################### End of migration codes ####################
        
        self.__execute_script("/".join([resourcePath, "triggers.sql"]))
        Logger.log_info("Database v1 update: Triggers built")

        self.__execute_script("/".join([resourcePath, "indexes.sql"]))
        Logger.log_info("Database v1 update: Indexes built")
                
        Logger.log_info("Database v1 update completed")
Example #18
0
    def on_system_connected(self):
        super().on_system_connected()
        
        Logger.log_info("on_system_connected begins...")
        
        DebugModule.DEBUG_ON_SYSTEM_CONNECTED.append(time.time())
        self.__automationModule = AutomationModuleWrapper()
        
        # ID must be retrieved before timer module register groups.
        self.__get_default_group_ids()

        # ===== Register methods =====
        # APIs
        paramSection = KBXString(kbxParamName="section")
        paramLimit = KBXNumber(kbxParamName="limit", kbxParamIsRequired=False, kbxParamMinValue=0, \
                               kbxParamMaxValue=200)
        paramOffset = KBXNumber(kbxParamName="offset", kbxParamIsRequired=False, kbxParamMinValue=0)

        self.register_method(kbxMethodName="list_groups", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_groups,
                             kbxMethodParams=[KBXNumber(kbxParamName="parentId", kbxParamIsRequired=False, kbxParamMinValue=1),
                                              paramSection])
        self.register_method(kbxMethodName="list_methods", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_methods,
                             kbxMethodParams=[KBXNumber(kbxParamName="groupId", kbxParamMinValue=1),
                                              paramSection])
        self.register_method(kbxMethodName="update_kbx_method", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.update_kbx_method,
                             kbxMethodParams=[KBXNumber(kbxParamName="kbxMethodId", kbxParamMinValue=1)])
        self.register_method(kbxMethodName="update_kbx_group", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.update_kbx_group,
                             kbxMethodParams=[KBXNumber(kbxParamName="kbxGroupId", kbxParamMinValue=1)])
        self.register_method(kbxMethodName="list_kbx_methods", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_kbx_methods,
                             kbxMethodParams=[paramLimit,
                                              paramOffset])
        self.register_method(kbxMethodName="list_kbx_groups", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_kbx_groups,
                             kbxMethodParams=[paramLimit,
                                              paramOffset])

        # Rules
        paramRuleId = KBXNumber(kbxParamName="ruleId", kbxParamDecimal=0, kbxParamMinValue=1)

        self.register_method(kbxMethodName="set_rule", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.set_rule)
        self.register_method(kbxMethodName="list_rules", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_rules,
                             kbxMethodParams=[paramLimit,
                                              paramOffset])
        self.register_method(kbxMethodName="get_rule", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.get_rule,
                             kbxMethodParams=[paramRuleId])
        self.register_method(kbxMethodName="delete_rule", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.delete_rule,
                             kbxMethodParams=[paramRuleId])
        self.register_method(kbxMethodName="trigger_rule", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.trigger_rule,
                             kbxMethodParams=[paramRuleId,
                                              KBXBoolean(kbxParamName="checkCondition", kbxParamIsRequired=False)])
        self.register_method(kbxMethodName="enable_rule", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.enable_rule,
                             kbxMethodParams=[paramRuleId,
                                              KBXBoolean(kbxParamName="enabled", kbxParamIsRequired=True)])

        # Scenes
        paramSceneId = KBXNumber(kbxParamName="sceneId", kbxParamDecimal=0, kbxParamMinValue=1)

        self.register_method(kbxMethodName="set_scene", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.set_scene)
        self.register_method(kbxMethodName="execute_scene", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.execute_scene,
                             kbxMethodParams=[paramSceneId,
                                              KBXString(kbxParamName="serUrl", kbxParamIsRequired=False)])
        self.register_method(kbxMethodName="stop_scene", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.stop_scene,
                             kbxMethodParams=[paramSceneId])
        self.register_method(kbxMethodName="delete_scene", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.delete_scene,
                             kbxMethodParams=[paramSceneId])
        self.register_method(kbxMethodName="get_scene", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.get_scene,
                             kbxMethodParams=[paramSceneId])
        self.register_method(kbxMethodName="list_scenes", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_scenes,
                             kbxMethodParams=[paramOffset, paramLimit])
        
        # Scene Execution Results
        paramSerId = KBXString(kbxParamName="serId")
        
        self.register_method(kbxMethodName="get_scene_execution_result", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.get_scene_execution_result,
                             kbxMethodParams=[paramSerId])
        self.register_method(kbxMethodName="retry_scene_execution_result_item", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.retry_scene_execution_result_item,
                             kbxMethodParams=[paramSerId,
                                              KBXNumber(kbxParamName="seriIndex", kbxParamIsRequired=False, kbxParamMinValue=0)])
        self.register_method(kbxMethodName="list_scene_execution_results", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_scene_execution_results,
                             kbxMethodParams=[paramOffset, paramLimit])
        self.register_method(kbxMethodName="delete_scene_execution_result", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.delete_scene_execution_result,
                             kbxMethodParams=[paramSerId])
        
        # Favorited Scenes
        self.register_method(kbxMethodName="set_favorited_scene", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.set_favorited_scene,
                             kbxMethodParams=[paramSceneId,
                                              KBXNumber(kbxParamName="prevSceneId", kbxParamIsRequired=False, kbxParamDecimal=0, kbxParamMinValue=1)])
        self.register_method(kbxMethodName="delete_favorited_scene", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.delete_favorited_scene,
                             kbxMethodParams=[paramSceneId])
        self.register_method(kbxMethodName="list_favorited_scenes", kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_favorited_scenes,
                             kbxMethodParams=[paramLimit,
                                              paramOffset])
        
        Logger.log_info("on_system_connected ends...")
Example #19
0
    def on_start(self):
        Logger.log_info("on_start begins...")
        
        AppInfo.JSON_ENCODER_CLS = AutomationJSONEncoder
        
        Database.instance().initialize()
        
        self.register_module(DebugModule("debug_module", None))
        Logger.log_info("registered module: debug_module")
        
        self.register_module(ControllerModule("controller_module", None))
        Logger.log_info("registered module: debug_module")
        self.register_module(TimerModule("timer_module", None))
        Logger.log_info("registered module: debug_module")

        self.register_module(DeviceManagerModule("device_manager", None))
        Logger.log_info("registered module: debug_module")
        self.register_module(ZWaveModule("zwave_module", None))
        Logger.log_info("registered module: zwave_module")
        
        self.register_module(LocationManagerModule("location_manager", None))
        Logger.log_info("registered module: location_manager")
        
        Logger.log_info("on_start ends...")
Example #20
0
    def __broadcast_message__favorited_scene_deleted(self, sceneId):
        eventTag = AppConstants.EVENT_FAVORITED_SCENE_DELETED
        eventData = {"sceneId": sceneId}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Favorited scene deleted: Id", sceneId)
Example #21
0
    def __broadcast_message__rule_deleted(self, ruleId):
        eventTag = AppConstants.EVENT_RULE_DELETED
        eventData = {"ruleId": ruleId}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Rule Deleted: Id -", ruleId)
Example #22
0
    def __broadcast_message__scene_deleted(self, sceneId):
        eventTag = AppConstants.EVENT_SCENE_DELETED
        eventData = {"sceneId": sceneId}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Scene Deleted: Id -", sceneId)
Example #23
0
 def __execute_scene_implementation(self, sceneId, execution, serObj, language):
     '''
     ** Call execute_scene; DO NOT call this function directly.
     '''
     Logger.log_info("execute scene id:", sceneId)
     
     def execution_func(sceneThreadEvent, kbxMethodId, seri, **kwargs):
         try:
             if kbxMethodId == -291:
                 # Delay Timer
                 delayInSec = kwargs["delayInSec"]
                 sceneThreadEvent.wait(delayInSec)
                 seri["seriError"] = None
             else:
                 # Execute method
                 result = SharedMethod.call(**kwargs)
                 seri["seriError"] = str(result)
                 
             seri["seriStatus"] = "ok"
         
         except Exception as e:
             seri["seriStatus"] = "error"
             seri["seriError"] = str(e)
             Logger.log_debug("Execution failed, method:", kwargs["kbxMethodName"])
         
         finally:
             sceneThreadEvent.set()
             
         
     try:
         # Record for debugging purpose
         serStartTime = time.time()
         
         #===================================================================
         # Prepare to execute execution methods
         #===================================================================
         sceneExecLock = self.__sceneExecLocks.get(sceneId)
         sceneThreadEvent = sceneExecLock.get_thread_event()
         seris = deque()
         
         methodExecTime = int(time.time())
         isLoopCompleted = True
         for row in execution:
             kbxMethodId = row["kbxMethodId"]
             kbxMethodName = row["kbxMethodName"]
             kbxGroupId = row["kbxGroupId"]
             kbxMethodStatus = row["kbxMethodStatus"]
             methodParamsWithCurrentValues = row["kbxMethodParams"]
             seri = {"kbxMethodId":kbxMethodId,
                     "kbxGroupId":kbxGroupId,
                     "kbxMethodName":kbxMethodName,
                     "kbxMethodParams":methodParamsWithCurrentValues}
             seris.append(seri)
             # Check is stop
             if sceneExecLock.is_stop():
                 if not isLoopCompleted:
                     serEndTime = time.time()
                     isLoopCompleted = False
                     # === Execution interrupted ===
                 continue
             
             # Check is method not removed
             elif kbxMethodStatus not in (SharedMethod.METHOD_STATUS_ACTIVE, SharedMethod.METHOD_STATUS_INACTIVE):
                 seri["seriStatus"] = "error"
                 seri["seriError"] = "method is removed"
                 continue
 
             kwargs = {methodParam[AppConstants.ARG_NAME]: methodParam[AppConstants.ARG_CURRENT_VALUE]
                       for methodParam in methodParamsWithCurrentValues}
 
             if AppInfo.REQUEST_KEY_LANGUAGE not in kwargs:
                 kwargs[AppInfo.REQUEST_KEY_LANGUAGE] = AppInfo.DEFAULT_API_LANGUAGE
             
             kwargs["kbxMethodName"] = kbxMethodName
             kwargs["kbxGroupId"] = kbxGroupId
             kwargs["kbxModuleName"] = row["kbxModuleName"]
             kwargs["kbxMethodAppId"] = row["kbxMethodAppId"]
             kwargs[AppConstants.KEY_ACTION_TIMESTAMP] = methodExecTime
             
             #===========================================================
             # Execute method
             #===========================================================
             sceneThreadEvent.clear()
             
             execThread = threading.Thread(target=execution_func, args=[sceneThreadEvent, row["kbxMethodId"], seri], kwargs=kwargs)
             execThread.daemon = False
             execThread.start()
             
             sceneThreadEvent.wait() # Event will be set by "stop_scene" or SharedMethod.call returns.
             
             # Check is stop
             if sceneExecLock.is_stop():
                 if not isLoopCompleted:
                     serEndTime = time.time()
                     isLoopCompleted = False
                     # === Execution interrupted ===
                 continue
             
         if isLoopCompleted:
             # Record for debugging purpose
             serEndTime = time.time()
             # === Execution completed ===
         
     except Exception as e:
         # This is unexpected error. Execution will not be recorded by Scene Execution Result.
         Logger.log_error("SceneService.__execute_scene_implementation ex:", e)
         # === Execution completed with errors ===
         
     else:
         if serObj is not None:
             # Log to sceneExecutionResultService
             self.__sceneExecutionResultThreadPool.submit(self.__add_scene_execution_result,
                                                          serUrl=serObj["serUrl"], 
                                                          serStartTime=serStartTime, 
                                                          serEndTime=serEndTime, 
                                                          sceneName=serObj["sceneName"], 
                                                          sceneProtected=serObj["sceneProtected"],
                                                          sceneId=sceneId, 
                                                          execution=seris, 
                                                          language=language)
         
     finally:
         del(self.__sceneExecLocks[sceneId])  # Delete exec lock
         sceneExecLock.release()
Example #24
0
    def db_1_update(self, resourcePath):

        Logger.log_info("Database v1 update started")

        self.__execute_script("/".join([resourcePath, "tablestructure.sql"]))
        Logger.log_info("Database v1 update: Table structures built")

        # #################### Migration codes ####################
        try:
            from automationApp.migration.storage import Storage
            allGroups = Storage.list_all_groups()
            if len(allGroups) > 0:  # Probably no rule is set.
                '''
                All Groups: e.g. {25: 'Yeelight Blue II'}
                '''
                for kbxGroupId, kbxGroupLabel in allGroups.items():
                    self.__con.execute(
                        'INSERT INTO "kbx_group"("kbxGroupId", "kbxGroupLabel", "kbxGroupStatus") VALUES (?, ?, ?)',
                        (kbxGroupId, kbxGroupLabel, -1))
                del (allGroups)
                '''
                All Groups Methods: e.g. {69: 25, 71: 25}
                '''
                allMethodGroups = Storage.list_all_method_groups()
                for kbxMethodId, kbxGroupId in allMethodGroups.items():
                    self.__con.execute('INSERT INTO "kbx_method"("kbxMethodId", "kbxGroupId", "kbxMethodStatus") ' + \
                                       'VALUES (?, ?, ?)',
                                       (kbxMethodId, kbxGroupId, -1))
                '''
                All Rules: e.g. [{
                    'execution': [{'kbxMethodId': 71, 'kbxMethodParams': [{'kbxParamCurrentValue': '4', 'kbxParamName': 'pairedDeviceId'},{'kbxParamCurrentValue': [False], 'kbxParamName': 'on'}]}], 
                    'trigger': {'type': 0, 'value': None}, 
                    'ruleId': '1425284835.0756288', 
                    'enabled': True, 
                    'condition': [{'kbxMethodId': 69, 'kbxMethodParams': [{'kbxParamCurrentValue': '4', 'kbxParamName': 'pairedDeviceId'}, {'kbxParamCurrentValue': [True], 'kbxParamName': 'on'}]}], 
                    'ruleName': 'ReTestet'
                }]
                '''
                allRules = Storage.list_all_rules()
                cursor = self.__con.cursor()
                createdTime = updatedTime = time.time()
                triggerController = TriggerController.instance()
                for sort, rule in enumerate(allRules):
                    trigger = triggerController.parse_to_trigger_dto(
                        rule["trigger"])
                    cursor.execute('INSERT INTO "rule"("ruleName", "ruleProtected", "trigger", "enabled", "statusProcessed", "createdTime", "updatedTime", "sort") ' + \
                                   'VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
                                   (rule["ruleName"], False, json.dumps(trigger),
                                    rule["enabled"], "updated", createdTime,
                                    updatedTime, sort))

                    ruleId = cursor.lastrowid
                    for vals in (["execution", "rule_execution", "reRuleId"],
                                 ["condition", "rule_condition", "rcRuleId"]):
                        for kbxMethodSort, kbxMethodWithCurrentValue in enumerate(
                                rule[vals[0]]):
                            self.__con.execute('INSERT INTO "' + vals[1] + '"("' + vals[2] + '", "kbxMethodId", "kbxMethodParams", "createdTime", "sort") ' + \
                                               'VALUES (?, ?, ?, ?, ?)',
                                               (ruleId, kbxMethodWithCurrentValue["kbxMethodId"],
                                                json.dumps(kbxMethodWithCurrentValue["kbxMethodParams"]),
                                                createdTime, kbxMethodSort))
                cursor.close()
                del (allRules)

                self.__con.commit()

        except Exception as e:
            self.__con.rollback()
            Logger.log_warning(
                "Database failed to migrate rules from system, ex:", e,
                "---- rolled back")

        else:
            Logger.log_info("Database v1 update: Rules migrated")
            try:
                Storage.delete_all_rules()
                Storage.delete_all_method_groups()
                Storage.delete_all_groups()
            except Exception as e:
                Logger.log_warning(
                    "Database failed to remove rules from system after migration, ex:",
                    e)
        # #################### End of migration codes ####################

        self.__execute_script("/".join([resourcePath, "triggers.sql"]))
        Logger.log_info("Database v1 update: Triggers built")

        self.__execute_script("/".join([resourcePath, "indexes.sql"]))
        Logger.log_info("Database v1 update: Indexes built")

        Logger.log_info("Database v1 update completed")
Example #25
0
    def __broadcast_message__rule_update_started(self, ruleId, ruleName=None):
        eventTag = AppConstants.EVENT_RULE_UPDATE_STARTED
        eventData = {"ruleId": ruleId, "newRuleName": ruleName}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Rule Start Update:", ruleName)
Example #26
0
    def __execute_scene_implementation(self, sceneId, execution, serObj,
                                       language):
        '''
        ** Call execute_scene; DO NOT call this function directly.
        '''
        Logger.log_info("execute scene id:", sceneId)

        def execution_func(sceneThreadEvent, kbxMethodId, seri, **kwargs):
            try:
                if kbxMethodId == -291:
                    # Delay Timer
                    delayInSec = kwargs["delayInSec"]
                    sceneThreadEvent.wait(delayInSec)
                    seri["seriError"] = None
                else:
                    # Execute method
                    result = SharedMethod.call(**kwargs)
                    seri["seriError"] = str(result)

                seri["seriStatus"] = "ok"

            except Exception as e:
                seri["seriStatus"] = "error"
                seri["seriError"] = str(e)
                Logger.log_debug("Execution failed, method:",
                                 kwargs["kbxMethodName"])

            finally:
                sceneThreadEvent.set()

        try:
            # Record for debugging purpose
            serStartTime = time.time()

            #===================================================================
            # Prepare to execute execution methods
            #===================================================================
            sceneExecLock = self.__sceneExecLocks.get(sceneId)
            sceneThreadEvent = sceneExecLock.get_thread_event()
            seris = deque()

            methodExecTime = int(time.time())
            isLoopCompleted = True
            for row in execution:
                kbxMethodId = row["kbxMethodId"]
                kbxMethodName = row["kbxMethodName"]
                kbxGroupId = row["kbxGroupId"]
                kbxMethodStatus = row["kbxMethodStatus"]
                methodParamsWithCurrentValues = row["kbxMethodParams"]
                seri = {
                    "kbxMethodId": kbxMethodId,
                    "kbxGroupId": kbxGroupId,
                    "kbxMethodName": kbxMethodName,
                    "kbxMethodParams": methodParamsWithCurrentValues
                }
                seris.append(seri)
                # Check is stop
                if sceneExecLock.is_stop():
                    if not isLoopCompleted:
                        serEndTime = time.time()
                        isLoopCompleted = False
                        # === Execution interrupted ===
                    continue

                # Check is method not removed
                elif kbxMethodStatus not in (
                        SharedMethod.METHOD_STATUS_ACTIVE,
                        SharedMethod.METHOD_STATUS_INACTIVE):
                    seri["seriStatus"] = "error"
                    seri["seriError"] = "method is removed"
                    continue

                kwargs = {
                    methodParam[AppConstants.ARG_NAME]:
                    methodParam[AppConstants.ARG_CURRENT_VALUE]
                    for methodParam in methodParamsWithCurrentValues
                }

                if AppInfo.REQUEST_KEY_LANGUAGE not in kwargs:
                    kwargs[AppInfo.
                           REQUEST_KEY_LANGUAGE] = AppInfo.DEFAULT_API_LANGUAGE

                kwargs["kbxMethodName"] = kbxMethodName
                kwargs["kbxGroupId"] = kbxGroupId
                kwargs["kbxModuleName"] = row["kbxModuleName"]
                kwargs["kbxMethodAppId"] = row["kbxMethodAppId"]
                kwargs[AppConstants.KEY_ACTION_TIMESTAMP] = methodExecTime

                #===========================================================
                # Execute method
                #===========================================================
                sceneThreadEvent.clear()

                execThread = threading.Thread(
                    target=execution_func,
                    args=[sceneThreadEvent, row["kbxMethodId"], seri],
                    kwargs=kwargs)
                execThread.daemon = False
                execThread.start()

                sceneThreadEvent.wait(
                )  # Event will be set by "stop_scene" or SharedMethod.call returns.

                # Check is stop
                if sceneExecLock.is_stop():
                    if not isLoopCompleted:
                        serEndTime = time.time()
                        isLoopCompleted = False
                        # === Execution interrupted ===
                    continue

            if isLoopCompleted:
                # Record for debugging purpose
                serEndTime = time.time()
                # === Execution completed ===

        except Exception as e:
            # This is unexpected error. Execution will not be recorded by Scene Execution Result.
            Logger.log_error("SceneService.__execute_scene_implementation ex:",
                             e)
            # === Execution completed with errors ===

        else:
            if serObj is not None:
                # Log to sceneExecutionResultService
                self.__sceneExecutionResultThreadPool.submit(
                    self.__add_scene_execution_result,
                    serUrl=serObj["serUrl"],
                    serStartTime=serStartTime,
                    serEndTime=serEndTime,
                    sceneName=serObj["sceneName"],
                    sceneProtected=serObj["sceneProtected"],
                    sceneId=sceneId,
                    execution=seris,
                    language=language)

        finally:
            del (self.__sceneExecLocks[sceneId])  # Delete exec lock
            sceneExecLock.release()
Example #27
0
 def __broadcast_message__favorited_scene_added(self, sceneId, prevSceneId):
     eventTag = AppConstants.EVENT_FAVORITED_SCENE_ADDED
     eventData = {"sceneId":sceneId, "prevSceneId":prevSceneId}
     
     self.__broadcast_message(eventTag, eventData)
     Logger.log_info("Favorited scene added/updated: Id", sceneId, "prevId:", prevSceneId)
Example #28
0
 def __broadcast_message__rule_update_started(self, ruleId, ruleName=None):
     eventTag = AppConstants.EVENT_RULE_UPDATE_STARTED
     eventData = {"ruleId":ruleId, "newRuleName":ruleName}
     
     self.__broadcast_message(eventTag, eventData)
     Logger.log_info("Rule Start Update:", ruleName)
Example #29
0
    def on_start(self):
        Logger.log_info("on_start begins...")

        AppInfo.JSON_ENCODER_CLS = AutomationJSONEncoder

        Database.instance().initialize()

        self.register_module(DebugModule("debug_module", None))
        Logger.log_info("registered module: debug_module")

        self.register_module(ControllerModule("controller_module", None))
        Logger.log_info("registered module: debug_module")
        self.register_module(TimerModule("timer_module", None))
        Logger.log_info("registered module: debug_module")

        self.register_module(DeviceManagerModule("device_manager", None))
        Logger.log_info("registered module: debug_module")
        self.register_module(ZWaveModule("zwave_module", None))
        Logger.log_info("registered module: zwave_module")

        self.register_module(LocationManagerModule("location_manager", None))
        Logger.log_info("registered module: location_manager")

        Logger.log_info("on_start ends...")
Example #30
0
    def on_system_connected(self):
        super().on_system_connected()

        Logger.log_info("on_system_connected begins...")

        DebugModule.DEBUG_ON_SYSTEM_CONNECTED.append(time.time())
        self.__automationModule = AutomationModuleWrapper()

        # ID must be retrieved before timer module register groups.
        self.__get_default_group_ids()

        # ===== Register methods =====
        # APIs
        paramSection = KBXString(kbxParamName="section")
        paramLimit = KBXNumber(kbxParamName="limit", kbxParamIsRequired=False, kbxParamMinValue=0, \
                               kbxParamMaxValue=200)
        paramOffset = KBXNumber(kbxParamName="offset",
                                kbxParamIsRequired=False,
                                kbxParamMinValue=0)

        self.register_method(kbxMethodName="list_groups",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_groups,
                             kbxMethodParams=[
                                 KBXNumber(kbxParamName="parentId",
                                           kbxParamIsRequired=False,
                                           kbxParamMinValue=1), paramSection
                             ])
        self.register_method(
            kbxMethodName="list_methods",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.list_methods,
            kbxMethodParams=[
                KBXNumber(kbxParamName="groupId", kbxParamMinValue=1),
                paramSection
            ])
        self.register_method(
            kbxMethodName="update_kbx_method",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.update_kbx_method,
            kbxMethodParams=[
                KBXNumber(kbxParamName="kbxMethodId", kbxParamMinValue=1)
            ])
        self.register_method(
            kbxMethodName="update_kbx_group",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.update_kbx_group,
            kbxMethodParams=[
                KBXNumber(kbxParamName="kbxGroupId", kbxParamMinValue=1)
            ])
        self.register_method(
            kbxMethodName="list_kbx_methods",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.list_kbx_methods,
            kbxMethodParams=[paramLimit, paramOffset])
        self.register_method(
            kbxMethodName="list_kbx_groups",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.list_kbx_groups,
            kbxMethodParams=[paramLimit, paramOffset])

        # Rules
        paramRuleId = KBXNumber(kbxParamName="ruleId",
                                kbxParamDecimal=0,
                                kbxParamMinValue=1)

        self.register_method(kbxMethodName="set_rule",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.set_rule)
        self.register_method(kbxMethodName="list_rules",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_rules,
                             kbxMethodParams=[paramLimit, paramOffset])
        self.register_method(kbxMethodName="get_rule",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.get_rule,
                             kbxMethodParams=[paramRuleId])
        self.register_method(kbxMethodName="delete_rule",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.delete_rule,
                             kbxMethodParams=[paramRuleId])
        self.register_method(
            kbxMethodName="trigger_rule",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.trigger_rule,
            kbxMethodParams=[
                paramRuleId,
                KBXBoolean(kbxParamName="checkCondition",
                           kbxParamIsRequired=False)
            ])
        self.register_method(kbxMethodName="enable_rule",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.enable_rule,
                             kbxMethodParams=[
                                 paramRuleId,
                                 KBXBoolean(kbxParamName="enabled",
                                            kbxParamIsRequired=True)
                             ])

        # Scenes
        paramSceneId = KBXNumber(kbxParamName="sceneId",
                                 kbxParamDecimal=0,
                                 kbxParamMinValue=1)

        self.register_method(kbxMethodName="set_scene",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.set_scene)
        self.register_method(
            kbxMethodName="execute_scene",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.execute_scene,
            kbxMethodParams=[
                paramSceneId,
                KBXString(kbxParamName="serUrl", kbxParamIsRequired=False)
            ])
        self.register_method(kbxMethodName="stop_scene",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.stop_scene,
                             kbxMethodParams=[paramSceneId])
        self.register_method(
            kbxMethodName="delete_scene",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.delete_scene,
            kbxMethodParams=[paramSceneId])
        self.register_method(kbxMethodName="get_scene",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.get_scene,
                             kbxMethodParams=[paramSceneId])
        self.register_method(kbxMethodName="list_scenes",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.list_scenes,
                             kbxMethodParams=[paramOffset, paramLimit])

        # Scene Execution Results
        paramSerId = KBXString(kbxParamName="serId")

        self.register_method(
            kbxMethodName="get_scene_execution_result",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.get_scene_execution_result,
            kbxMethodParams=[paramSerId])
        self.register_method(kbxMethodName="retry_scene_execution_result_item",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.
                             retry_scene_execution_result_item,
                             kbxMethodParams=[
                                 paramSerId,
                                 KBXNumber(kbxParamName="seriIndex",
                                           kbxParamIsRequired=False,
                                           kbxParamMinValue=0)
                             ])
        self.register_method(
            kbxMethodName="list_scene_execution_results",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.list_scene_execution_results,
            kbxMethodParams=[paramOffset, paramLimit])
        self.register_method(kbxMethodName="delete_scene_execution_result",
                             kbxMethodIsPrivate=True,
                             kbxMethodFunc=self.__automationModule.
                             delete_scene_execution_result,
                             kbxMethodParams=[paramSerId])

        # Favorited Scenes
        self.register_method(
            kbxMethodName="set_favorited_scene",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.set_favorited_scene,
            kbxMethodParams=[
                paramSceneId,
                KBXNumber(kbxParamName="prevSceneId",
                          kbxParamIsRequired=False,
                          kbxParamDecimal=0,
                          kbxParamMinValue=1)
            ])
        self.register_method(
            kbxMethodName="delete_favorited_scene",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.delete_favorited_scene,
            kbxMethodParams=[paramSceneId])
        self.register_method(
            kbxMethodName="list_favorited_scenes",
            kbxMethodIsPrivate=True,
            kbxMethodFunc=self.__automationModule.list_favorited_scenes,
            kbxMethodParams=[paramLimit, paramOffset])

        Logger.log_info("on_system_connected ends...")
Example #31
0
 def __broadcast_message__favorited_scene_deleted(self, sceneId):
     eventTag = AppConstants.EVENT_FAVORITED_SCENE_DELETED
     eventData = {"sceneId":sceneId}
     
     self.__broadcast_message(eventTag, eventData)
     Logger.log_info("Favorited scene deleted: Id", sceneId)
Example #32
0
    def __trigger_rule_implementation(self, ruleId, checkCondition=False, eventTag=None, eventData=None, eventMethodId=None):
        '''
        Triggers a rule by given ruleId.
        '''
        Logger.log_info("trigger rule id:", ruleId)
        
        # Check if rule is "updated" AND enabled.
        statusProcessed, enabled = self.__ruleController.get_status_processed_and_enabled(ruleId)
        if statusProcessed != AppConstants.RULE_STATUS_UPDATED or enabled != True:
            return
        
        self.__ruleExecInfos.setdefault(ruleId, RuleExecInfo())
        
        ruleExecInfo = self.__ruleExecInfos.get(ruleId)
        ruleExecInfo.increase_trigger_count()
        triggerCountInThisSession = ruleExecInfo.get_trigger_count()
        
        with ruleExecInfo.get_rlock():
            #=======================================================================
            # Check conditions
            #=======================================================================
            if checkCondition is True:
                # Check if we should proceed (stop if there is another pending request on the same ruleId).
                if triggerCountInThisSession != ruleExecInfo.get_trigger_count():
                    return
                
                methodListToCheck = deque()
                result = self.__ruleController.list_conditions(ruleId)
                methodCheckingTime = int(time.time())
                for row in result:
                    if row["kbxMethodStatus"] not in (SharedMethod.METHOD_STATUS_ACTIVE, SharedMethod.METHOD_STATUS_INACTIVE):
                        return
                    else:
                        methodArgs = row["kbxMethodParams"]
    
                        kwargs = {methodArg[AppConstants.ARG_NAME]:methodArg[AppConstants.ARG_CURRENT_VALUE] for methodArg in methodArgs}
                        
                        if eventTag is not None and eventMethodId == row["kbxMethodId"]:
                            kwargs[AppConstants.KEY_CONDITION_EVENT_TAG] = eventTag
                            kwargs[AppConstants.KEY_CONDITION_EVENT_DATA] = eventData
                            
                        if AppInfo.REQUEST_KEY_LANGUAGE not in kwargs:
                            kwargs[AppInfo.REQUEST_KEY_LANGUAGE] = AppInfo.DEFAULT_API_LANGUAGE
                            
                        kwargs["kbxMethodName"] = row["kbxMethodName"]
                        kwargs["kbxModuleName"] = row["kbxModuleName"]
                        kwargs["kbxGroupId"] = row["kbxGroupId"]
                        kwargs["kbxMethodAppId"] = row["kbxMethodAppId"]
                        
                        # Update ruleId if it is required by the method
                        if "ruleId" in kwargs:
                            kwargs["ruleId"] = str(ruleId)
                        
                        callId = hash(str(kwargs)) # Generate condition checking ID
                        kwargs[AppConstants.KEY_CONDITION_TIMESTAMP] = methodCheckingTime # So that timestamp will not caused the generated id to be different
                        methodListToCheck.append({"callId":callId,
                                                  "callFn":SharedMethod.call,
                                                  "callKwargs":kwargs})
                    
                #===============================================================
                # Submit all conditions for checking
                #===============================================================
                methodListToCheckLen = len(methodListToCheck)
                if methodListToCheckLen > 0:
                    ruleExecResult = RuleExecResult(methodListToCheckLen)
                    
                    for methodItem in methodListToCheck:
                        self.__condCallGroup.submit(callbackFn=self.__on_method_call_complete, ruleExecResult=ruleExecResult, **methodItem)
                    
                    result = ruleExecResult.wait(40.0)
                    
                    if result is False or ruleExecResult.get_result() is False:
                        return # Failed at condition checking.
            
                # Clear cache
                del(methodListToCheck)
                del(methodCheckingTime)
                del(methodListToCheckLen)
                
                # Check if we should proceed (stop if there is another pending request on the same ruleId).
                if triggerCountInThisSession != ruleExecInfo.get_trigger_count():
                    return

            #=======================================================================
            # Execute executions
            #=======================================================================
            methodListToExec = deque()
            result = self.__ruleController.list_executions(ruleId)
            methodExecTime = int(time.time())
            for row in result:
                if row["kbxMethodStatus"] not in (SharedMethod.METHOD_STATUS_ACTIVE, SharedMethod.METHOD_STATUS_INACTIVE):
                    continue
                else:
                    methodArgs = row["kbxMethodParams"]
                    kwargs = {methodArg[AppConstants.ARG_NAME]:methodArg[AppConstants.ARG_CURRENT_VALUE] for methodArg in methodArgs}
                    if AppInfo.REQUEST_KEY_LANGUAGE not in kwargs:
                        kwargs[AppInfo.REQUEST_KEY_LANGUAGE] = AppInfo.DEFAULT_API_LANGUAGE
                    
                    kwargs["kbxMethodName"] = row["kbxMethodName"]
                    kwargs["kbxModuleName"] = row["kbxModuleName"]
                    kwargs["kbxGroupId"] = row["kbxGroupId"]
                    kwargs["kbxMethodAppId"] = row["kbxMethodAppId"]
                    
                    # Update ruleId if it is required by the method
                    if "ruleId" in kwargs:
                        kwargs["ruleId"] = str(ruleId)
                    
                    callId = hash(str(kwargs)) # Generate execution id
                    kwargs[AppConstants.KEY_ACTION_TIMESTAMP] = methodExecTime
                    methodListToExec.append({"callId":callId,
                                             "callFn":SharedMethod.call,
                                             "callKwargs":kwargs})

            #===============================================================
            # Submit all methods for executions
            #===============================================================
            methodListToExecLen = len(methodListToExec)
            if methodListToExecLen > 0:
                ruleExecResult = RuleExecResult(methodListToExecLen)
                
                for methodItem in methodListToExec:
                    self.__execCallGroup.submit(callbackFn=self.__on_method_call_complete, ruleExecResult=ruleExecResult, **methodItem)
                
                result = ruleExecResult.wait(30.0)
                
                return
Example #33
0
    def __broadcast_message__scene_deleted(self, sceneId):
        eventTag = AppConstants.EVENT_SCENE_DELETED
        eventData = {"sceneId": sceneId}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Scene Deleted: Id -", sceneId)
Example #34
0
    def db_2_update(self, resourcePath):
        self.__execute_script("/".join([resourcePath, "tablestructure.sql"]))
        Logger.log_info("Database v2 update: Table structures built")

        Logger.log_info("Database v2 update completed")
Example #35
0
    def __broadcast_message__rule_deleted(self, ruleId):
        eventTag = AppConstants.EVENT_RULE_DELETED
        eventData = {"ruleId": ruleId}

        self.__broadcast_message(eventTag, eventData)
        Logger.log_info("Rule Deleted: Id -", ruleId)
Example #36
0
    def __trigger_rule_implementation(self,
                                      ruleId,
                                      checkCondition=False,
                                      eventTag=None,
                                      eventData=None,
                                      eventMethodId=None):
        '''
        Triggers a rule by given ruleId.
        '''
        Logger.log_info("trigger rule id:", ruleId)

        # Check if rule is "updated" AND enabled.
        statusProcessed, enabled = self.__ruleController.get_status_processed_and_enabled(
            ruleId)
        if statusProcessed != AppConstants.RULE_STATUS_UPDATED or enabled != True:
            return

        self.__ruleExecInfos.setdefault(ruleId, RuleExecInfo())

        ruleExecInfo = self.__ruleExecInfos.get(ruleId)
        ruleExecInfo.increase_trigger_count()
        triggerCountInThisSession = ruleExecInfo.get_trigger_count()

        with ruleExecInfo.get_rlock():
            #=======================================================================
            # Check conditions
            #=======================================================================
            if checkCondition is True:
                # Check if we should proceed (stop if there is another pending request on the same ruleId).
                if triggerCountInThisSession != ruleExecInfo.get_trigger_count(
                ):
                    return

                methodListToCheck = deque()
                result = self.__ruleController.list_conditions(ruleId)
                methodCheckingTime = int(time.time())
                for row in result:
                    if row["kbxMethodStatus"] not in (
                            SharedMethod.METHOD_STATUS_ACTIVE,
                            SharedMethod.METHOD_STATUS_INACTIVE):
                        return
                    else:
                        methodArgs = row["kbxMethodParams"]

                        kwargs = {
                            methodArg[AppConstants.ARG_NAME]:
                            methodArg[AppConstants.ARG_CURRENT_VALUE]
                            for methodArg in methodArgs
                        }

                        if eventTag is not None and eventMethodId == row[
                                "kbxMethodId"]:
                            kwargs[AppConstants.
                                   KEY_CONDITION_EVENT_TAG] = eventTag
                            kwargs[AppConstants.
                                   KEY_CONDITION_EVENT_DATA] = eventData

                        if AppInfo.REQUEST_KEY_LANGUAGE not in kwargs:
                            kwargs[
                                AppInfo.
                                REQUEST_KEY_LANGUAGE] = AppInfo.DEFAULT_API_LANGUAGE

                        kwargs["kbxMethodName"] = row["kbxMethodName"]
                        kwargs["kbxModuleName"] = row["kbxModuleName"]
                        kwargs["kbxGroupId"] = row["kbxGroupId"]
                        kwargs["kbxMethodAppId"] = row["kbxMethodAppId"]

                        # Update ruleId if it is required by the method
                        if "ruleId" in kwargs:
                            kwargs["ruleId"] = str(ruleId)

                        callId = hash(
                            str(kwargs))  # Generate condition checking ID
                        kwargs[
                            AppConstants.
                            KEY_CONDITION_TIMESTAMP] = methodCheckingTime  # So that timestamp will not caused the generated id to be different
                        methodListToCheck.append({
                            "callId": callId,
                            "callFn": SharedMethod.call,
                            "callKwargs": kwargs
                        })

                #===============================================================
                # Submit all conditions for checking
                #===============================================================
                methodListToCheckLen = len(methodListToCheck)
                if methodListToCheckLen > 0:
                    ruleExecResult = RuleExecResult(methodListToCheckLen)

                    for methodItem in methodListToCheck:
                        self.__condCallGroup.submit(
                            callbackFn=self.__on_method_call_complete,
                            ruleExecResult=ruleExecResult,
                            **methodItem)

                    result = ruleExecResult.wait(40.0)

                    if result is False or ruleExecResult.get_result() is False:
                        return  # Failed at condition checking.

                # Clear cache
                del (methodListToCheck)
                del (methodCheckingTime)
                del (methodListToCheckLen)

                # Check if we should proceed (stop if there is another pending request on the same ruleId).
                if triggerCountInThisSession != ruleExecInfo.get_trigger_count(
                ):
                    return

            #=======================================================================
            # Execute executions
            #=======================================================================
            methodListToExec = deque()
            result = self.__ruleController.list_executions(ruleId)
            methodExecTime = int(time.time())
            for row in result:
                if row["kbxMethodStatus"] not in (
                        SharedMethod.METHOD_STATUS_ACTIVE,
                        SharedMethod.METHOD_STATUS_INACTIVE):
                    continue
                else:
                    methodArgs = row["kbxMethodParams"]
                    kwargs = {
                        methodArg[AppConstants.ARG_NAME]:
                        methodArg[AppConstants.ARG_CURRENT_VALUE]
                        for methodArg in methodArgs
                    }
                    if AppInfo.REQUEST_KEY_LANGUAGE not in kwargs:
                        kwargs[
                            AppInfo.
                            REQUEST_KEY_LANGUAGE] = AppInfo.DEFAULT_API_LANGUAGE

                    kwargs["kbxMethodName"] = row["kbxMethodName"]
                    kwargs["kbxModuleName"] = row["kbxModuleName"]
                    kwargs["kbxGroupId"] = row["kbxGroupId"]
                    kwargs["kbxMethodAppId"] = row["kbxMethodAppId"]

                    # Update ruleId if it is required by the method
                    if "ruleId" in kwargs:
                        kwargs["ruleId"] = str(ruleId)

                    callId = hash(str(kwargs))  # Generate execution id
                    kwargs[AppConstants.KEY_ACTION_TIMESTAMP] = methodExecTime
                    methodListToExec.append({
                        "callId": callId,
                        "callFn": SharedMethod.call,
                        "callKwargs": kwargs
                    })

            #===============================================================
            # Submit all methods for executions
            #===============================================================
            methodListToExecLen = len(methodListToExec)
            if methodListToExecLen > 0:
                ruleExecResult = RuleExecResult(methodListToExecLen)

                for methodItem in methodListToExec:
                    self.__execCallGroup.submit(
                        callbackFn=self.__on_method_call_complete,
                        ruleExecResult=ruleExecResult,
                        **methodItem)

                result = ruleExecResult.wait(30.0)

                return
Example #37
0
 def __broadcast_message__scene_update_started(self, sceneId, sceneName=None):
     eventTag = AppConstants.EVENT_SCENE_UPDATE_STARTED
     eventData = {"sceneId": sceneId, "newSceneName":sceneName}
 
     self.__broadcast_message(eventTag, eventData)
     Logger.log_info("Scene Start Update:", sceneName)