Esempio n. 1
0
def Run(
    trigger
):  # Run through the rules looking to see if we have a match for the trigger
    rules = database.GetRules(
        trigger)  # Get a list of all rules that mention trigger
    log.debug("Running rule: " + trigger)
    delVar = False
    if "==" in trigger:
        sep = trigger.index("==")
        triggerType = trigger[:sep]
        triggerVal = trigger[sep + 2:]
        oldVal = variables.Get(triggerType)
        if oldVal == None:  # Check to see if this variable already exists and leave it alone if so
            variables.Set(triggerType, triggerVal)
            delVar = True
    for line in rules:
        ruleId = line[0]
        rule = ' '.join(
            line[1].split()
        )  # Compact multiple spaces into single ones and make each line into a rule
        ruleList = rule.split(" ")  # Make each rule into a list
        if ruleList[0].lower() == "if":
            doIndex = FindItemInList("do", ruleList)  # Safely look for "do"
            if doIndex != None:
                if ParseCondition(
                        ruleList[1:doIndex], trigger
                ) == True:  # Parse condition from element 1 (ie immediately after "if") to "do"
                    Action(ruleList[doIndex + 1:], ruleId)  # Do action
            # else skip rest of line
        # else assume the line is a comment and skip it
    # end of rules
    if delVar:
        variables.Del(
            triggerType)  # Make sure we don't re-run the same trigger
Esempio n. 2
0
 def do_set(self, line):
     """set name value
     Set named variable to value"""
     if " " in line:
         argList = line.split(" ")
         name = argList[0]
         val = argList[1]
         variables.Set(name, val)
     else:
         variables.Del(line)
Esempio n. 3
0
def SetVarFromAttr(
    devIdx, name, value
):  # See if this attribute has an associated variable for user & rules
    if name == "attr" + zcl.Cluster.PowerConfig + ":" + zcl.Attribute.Batt_Percentage:
        SetTempVal(devIdx, "GetNextBatteryAfter",
                   datetime.now() +
                   timedelta(seconds=86400))  # Ask for battery every day
        #varName = GetUserNameFromDevIdx(devIdx)+"_BatteryPercentage"
        if value != "FF":
            varVal = int(value, 16) / 2  # Arrives in 0.5% increments
            #variables.Set(varName, varVal)
            #SetSynopsis(varName, str(varVal)) # Ready for the synopsis email
            SetStatus(devIdx, "Battery", str(varVal))  # For web page
        else:
            variables.Del(varName)
    if name == "attr" + zcl.Cluster.Temperature + ":" + zcl.Attribute.Celsius:
        #varName = GetUserNameFromDevIdx(devIdx)+"_TemperatureC"
        if value != "FF9C":  # Don't know where this value comes from - should be "FFFF"
            varVal = int(value, 16) / 100  # Arrives in 0.01'C increments
            #variables.Set(varName, varVal)
            SetStatus(devIdx, "Temperature", str(varVal))  # For web page
        else:
            variables.Del(varName)
    if name == "attr" + zcl.Cluster.OnOff + ":" + zcl.Attribute.OnOffState:
        now = datetime.now()
        nowStr = now.strftime("%H:%M")
        varVal = int(value, 16)
        if varVal == 0:
            SetStatus(devIdx, "Other", "Turned Off @ " + nowStr)
        else:
            SetStatus(devIdx, "Other", "Turned On @ " + nowStr)
    if name == "attr" + zcl.Cluster.Basic + "." + zcl.Attribute.Manuf_Name:
        userName = GetUserNameFromDevIdx(devIdx)
        if userName.find("(New)") == 0:
            userName = userName + " " + value
            SetUserNameFromDevIdx(devIdx, userName)
    if name == "attr" + zcl.Cluster.Basic + "." + zcl.Attribute.Model_Name:
        userName = GetUserNameFromDevIdx(devIdx)
        if userName.find("(New)") == 0:
            userName = userName + " " + value
            SetUserNameFromDevIdx(devIdx, userName)
Esempio n. 4
0
def Run(
    trigger
):  # Run through the rules looking to see if we have a match for the trigger
    rulesFile = Path(rulesFilename)
    if rulesFile.is_file():
        with open(rulesFilename) as rules:
            log.log("Running rule: " + trigger)
            if "==" in trigger:
                sep = trigger.index("==")
                triggerType = trigger[:sep]
                triggerVal = trigger[sep + 2:]
                variables.Set(triggerType, triggerVal)
            for line in rules:
                rule = ' '.join(
                    line.split()
                )  # Compact multiple spaces into single ones and make each line into a rule
                ruleList = rule.split(" ")  # Make each rule into a list
                if ruleList[0] == "if":
                    doIndex = FindItemInList("do",
                                             ruleList)  # Safely look for "do"
                    if doIndex != None:
                        if ParseCondition(
                                ruleList[1:doIndex], trigger
                        ) == True:  # Parse condition from element 1 to "do"
                            Action(ruleList[doIndex + 1:])  # Do action
                    # else skip rest of line
                elif ruleList[0] == "do":
                    Action(ruleList[1:])
                # else assume the line is a comment and skip it
            # end of rules
            variables.Del(
                triggerType)  # Make sure we don't re-run the same trigger
    else:
        shell.exec("touch " + rulesFilename)
        shell.exec("chmod 666 " + rulesFilename)
        log.fault("Made new " + rulesFilename + " !")
Esempio n. 5
0
def Action(actList, ruleId):
    log.debug("Action with: " + str(actList))
    action = actList[0].lower()
    if action == "Log".lower():
        log.debug("Rule says Log event for " + ' '.join(actList[1:]))
    elif action == "Play".lower():
        call(["omxplayer", "-o", actList[1], actList[2]])
    elif action == "Event".lower():
        if actList[1].lower() == "TimeOfDay".lower():
            events.IssueEvent(events.ids.TIMEOFDAY, actList[2])
        elif actList[1].lower() == "Alarm".lower():
            events.IssueEvent(events.ids.ALARM, actList[2])
        # Could have other events here...
    elif action == "synopsis":  # Was status
        emailAddress = config.Get("emailAddress")
        log.debug("About to send synopsis to " + emailAddress)
        if emailAddress != None:
            synopsis.BuildPage()  # Create synopsis page on demand
            with open("synopsis.txt", "r") as fh:  # Plain text of email
                emailText = fh.readlines()
            text = ''.join(emailText)
            with open("synopsis.html", "r") as fh:  # HTML of email
                emailHtml = fh.readlines()
            html = ''.join(emailHtml)
            sendmail.email("Vesta Status", text, html)  # See sendmail.py
        else:
            synopsis.problem(
                "NoEmail",
                "No emailAddress entry in config, needed to send synopsis")
    elif action == "email":  # All args are body of the text.  Fixed subject and email address
        emailAddress = config.Get("emailAddress")
        if emailAddress != None:
            emailBody = []
            for item in actList[1:]:
                emailBody.append(item)
            plainText = " ".join(emailBody)
            log.debug("Sending email with '" + plainText + "'")
            result = sendmail.email("Vesta Alert!", plainText, None)
            if result != 0:
                synopsis.problem(
                    "Email", "sendmail.email() failed with code " +
                    str(result) + " when trying to send:" + plainText)
        else:
            synopsis.problem("NoEmail", "No emailAddress entry in config")
    elif action == "override":  # Syntax is "Override <targetDevice> <targetDegC> <durationSecs>"
        devKey = devices.FindDev(actList[1])
        target = actList[2]
        timeSecs = actList[3]
        if devKey != None:
            schedule.Override(devKey, target, timeSecs)
    elif action == "set":  # Set a named variable to a value
        expression = "".join(
            actList[1:]
        )  # First recombine actList[1] onwards, with no spaces.  Now expression should be of the form "<var>=<val>"
        if "--" in expression:
            sep = expression.index("--")
            varName = expression[:sep]
            varVal = variables.Get(varName)
            if isNumber(varVal):
                newVal = str(eval(varVal + "-1"))
                variables.Set(varName, newVal)
                Run(
                    varName + "==" + newVal
                )  # Recurse! to see if any rules need running now that we've set a variable
            else:
                log.fault(varName + " not a number at " + expression)
        elif "++" in expression:
            sep = expression.index("++")
            varName = expression[:sep]
            varVal = variables.Get(varName)
            if isNumber(varVal):
                newVal = str(eval(varVal + "+1"))
                variables.Set(varName, newVal)
                Run(
                    varName + "==" + newVal
                )  # Recurse! to see if any rules need running now that we've set a variable
            else:
                log.fault(varName + " not a number at " + expression)
        elif "=" in expression:
            sep = expression.index("=")
            varName = expression[:sep]
            varVal = expression[sep + 1:]
            variables.Set(varName, varVal)
            Run(
                varName + "==" + varVal
            )  # Recurse! to see if any rules need running now that we've set a variable
        else:
            log.fault("Badly formatted rule at " + expression)
    elif action == "unset":  # Remove a named variable
        variables.Del(actList[1])
    else:  # Must be a command for a device, or group of devices
        if len(actList) >= 2:  # Check that we have a second arg...
            name = actList[1]  # Second arg is name
            if database.IsGroupName(name):  # Check if name is a groupName
                devKeyList = GetGroupDevs(name)
                for devKey in devKeyList:
                    CommandDev(action, devKey, actList,
                               ruleId)  # Command each device in list
            else:
                devKey = database.GetDevKey("userName", name)
                CommandDev(action, devKey, actList,
                           ruleId)  # Command one device