def DateStringFormat (value, oldFormat, newFormat): try: oldDate = datetime.datetime.strptime (value, oldFormat) return oldDate.strftime (newFormat) except Exception as e: eps.printException(e)
def stateToWeatherLCD(dev, state): try: if state in dev.states: value = dev.states[state] else: indigo.server.log( u"Unable to convert long weather condition to short condition because the state %s does not exist in %s" % (state, dev.name), isError=True, ) return "Err" if value == "Partly Cloudy": value = "P.CDY" if value == "Mostly Cloudy": value = "M.CDY" if value == "Clear": value = "CLEA" if value == "Thunderstorm": value = "T.STM" if value == "Overcast": value = "OVER" if value == "Rain": value = "RAIN" if value == "Scattered Clouds": value = "S.CLD" except Exception as e: eps.printException(e) return value
def getConditionDateValues(self, filter="", valuesDict=None, typeId="", targetId=0): ret = ui.getDataList (filter, valuesDict, typeId, targetId) try: option = ("any", "any") ret.insert(0, option) i = 1 # where the line will go x = string.find (filter, 'monthdays') if x > -1: options = ["lastday|last day of the month", "first|first week day", "second|second week day", "third|third week day", "fourth|fourth week day", "last|last week day"] for s in options: data = s.split("|") option = (data[0], data[1]) ret.insert(i, option) i = i + 1 # move the line if filter == "years": options = ["current|this year", "last|last year", "next|next year"] for s in options: data = s.split("|") option = (data[0], data[1]) ret.insert(i, option) i = i + 1 # move the line option = ("-1", "----------------------------------") ret.insert(i, option) except Exception as e: eps.printException(e) return ret
def getDayIteration (self, year, month, iteration, dow): try: days = calendar.monthrange(year, month) maxDays = days[1] dow = int(dow) iteration = iteration.lower() count = 0 dayidx = 0 for i in range (1, maxDays + 1): s = str(year) + "-" + "%02d" % month + "-" + "%02d" % i d = datetime.datetime.strptime (s, "%Y-%m-%d") if int(d.strftime("%w")) == dow: count = count + 1 dayidx = i # the last day that matches our dow if iteration == "first" and count == 1: return d if iteration == "second" and count == 2: return d if iteration == "third" and count == 3: return d if iteration == "fourth" and count == 4: return d # If we haven't yet returned then check if it's the last if iteration == "last" and count > 0: s = str(year) + "-" + "%02d" % month + "-" + "%02d" % dayidx d = datetime.datetime.strptime (s, "%Y-%m-%d") return d except Exception as e: eps.printException(e)
def autoCollapseConditions (self, valuesDict): try: currentBlock = int(valuesDict["currentCondition"]) # Run through all conditions, if any other than the current is checked then update for i in range (1, self.maxConditions + 1): if eps.valueValid (valuesDict, "expandConditions" + str(i)): if valuesDict["expandConditions" + str(i)] and i != currentBlock: currentBlock = i break # Now collapse all but the current block for i in range (1, self.maxConditions + 1): if eps.valueValid (valuesDict, "expandConditions" + str(i)): if i != currentBlock: valuesDict["expandConditions" + str(i)] = False # Hide/show fields for all unexpanded/expanded conditions for i in range (1, self.maxConditions + 1): if eps.valueValid (valuesDict, "expandConditions" + str(i)): valuesDict = self.setUIValueVisibility (valuesDict, i) # also hide options # Save the current block self.debugLog ("Current condition block set to %i" % currentBlock) valuesDict["currentCondition"] = str(currentBlock) except Exception as e: eps.printException(e) return valuesDict
def matchesDevice (self, dev, plugin, action): try: deviceMatch = False if action["devicefilter"] == "": deviceMatch = True elif action["devicefilter"] == plugin["id"]: deviceMatch = True elif action["devicefilter"] == plugin["id"] + "." + dev.deviceTypeId: deviceMatch = True elif action["devicefilter"] != "": devFind = string.find (action["devicefilter"], plugin["id"] + "." + dev.deviceTypeId) if devFind > -1: deviceMatch = True else: devFind = string.find (action["devicefilter"], plugin["id"]) if devFind > -1: devStr = action["devicefilter"][devFind:] # In case there is a comma devAry = devStr.split(",") if devAry[0] == plugin["id"]: deviceMatch = True if devAry[0] == plugin["id"] + "." + dev.deviceTypeId: deviceMatch = True except Exception as e: eps.printException(e) return deviceMatch
def conditionsPass (self, dev): try: isTrue = 0 isFalse = 0 if eps.valueValid (dev.pluginProps, "conditions", True) == False: return False condition = dev.pluginProps["conditions"] self.debugLog ("\tCondition is set to %s, testing condition(s)" % condition) if condition == "none": return True for i in range (0, self.maxConditions + 1): if eps.valueValid (dev.pluginProps, "condition" + str(i), True) == False: continue # no condition for this index if dev.pluginProps["condition" + str(i)] == "disabled": continue # this condition is disabled val = [0,0] # Failsafe if dev.pluginProps["evaluation" + str(i)] == "between" or dev.pluginProps["evaluation" + str(i)] == "notbetween": val = self.conditionBetween (dev, i) if dev.pluginProps["evaluation" + str(i)] == "equal" or dev.pluginProps["evaluation" + str(i)] == "notequal": val = self.conditionEquals (dev, i) if dev.pluginProps["evaluation" + str(i)] == "greater": val = self.conditionGreater (dev, i) if dev.pluginProps["evaluation" + str(i)] == "less": val = self.conditionLess (dev, i) if dev.pluginProps["evaluation" + str(i)] == "contains" or dev.pluginProps["evaluation" + str(i)] == "notcontains": val = self.conditionContain (dev, i) isTrue = isTrue + val[0] isFalse = isFalse + val[1] if condition == "alltrue" and isFalse <> 0: return False if condition == "anytrue" and isTrue == 0: return False if condition == "allfalse" and isTrue <> 0: return False if condition == "anyfalse" and isFalse == 0: return False except Exception as e: eps.printException(e) return False
def hasDefinedAction (self, dev, actionId): try: # This is a future feature, we will be checking if this action ID for this device has been defined return False except Exception as e: eps.printException(e)
def getOptionFields (self, dev, action): retVal = [] cmdList = [] try: if unicode(type(dev)) == "<class 'indigo.DimmerDevice'>": cmdList += devactiondefs.INDIGO_DIMMER if unicode(type(dev)) == "<class 'indigo.RelayDevice'>": cmdList += devactiondefs.INDIGO_RELAY if unicode(type(dev)) == "<class 'indigo.SprinklerDevice'>": cmdList += devactiondefs.INDIGO_SPRINKLER for s in cmdList: cmds = s.split("|") if cmds[0] == action: opts = cmds[2].split(",") for opt in opts: indigo.server.log(opt) x = string.find (opt, "=") if x > -1: o = opt.split("=") indigo.server.log(unicode(o)) retVal.append(o[1]) indigo.server.log(unicode(cmds)) except Exception as e: eps.printException(e) indigo.server.log(unicode(retVal)) return retVal
def conditionBetween (self, dev, index): ret = [] isTrue = 0 isFalse = 0 try: #if dev.pluginProps["condition" + str(index)] == "timeonly" or dev.pluginProps["condition" + str(index)] == "devstatetimeonly" or dev.pluginProps["condition" + str(index)] == "vartimeonly": val = self.conditionsDateBetween (dev, index, True, False) #if dev.pluginProps["condition" + str(index)] == "dateonly" or dev.pluginProps["condition" + str(index)] == "devstatedateonly" or dev.pluginProps["condition" + str(index)] == "vardateonly": val = self.conditionsDateBetween (dev, index, False, True) #if dev.pluginProps["condition" + str(index)] == "datetime" or dev.pluginProps["condition" + str(index)] == "devstatedatetime" or dev.pluginProps["condition" + str(index)] == "vardatetime": val = self.conditionsDateBetween (dev, index, True, True) #if dev.pluginProps["condition" + str(index)] == "dow" or dev.pluginProps["condition" + str(index)] == "devstatedow": val = self.conditionsDow (dev, index) if dev.pluginProps["condition" + str(index)] == "datetime" or dev.pluginProps["condition" + str(index)] == "devstatedatetime" or dev.pluginProps["condition" + str(index)] == "vardatetime": val = self.conditionsDate (dev, index) if dev.pluginProps["condition" + str(index)] == "device": val = [0, 0] # Failsafe devEx = indigo.devices[int(dev.pluginProps["device" + str(index)])] if eps.valueValid (devEx.states, dev.pluginProps["state" + str(index)]): compareString = unicode(devEx.states[dev.pluginProps["state" + str(index)]]) self.debugLog ("\tChecking if device state '%s' value of '%s' is between '%s' and '%s'" % (dev.pluginProps["state" + str(index)], compareString, dev.pluginProps["value" + str(index)], dev.pluginProps["endValue" + str(index)])) if compareString.lower() >= dev.pluginProps["value" + str(index)].lower() and compareString.lower() <= dev.pluginProps["endValue" + str(index)].lower(): val[0] = 1 val[1] = 0 else: val[0] = 0 val[1] = 1 if dev.pluginProps["condition" + str(index)] == "variable": val = [0, 0] # Failsafe var = indigo.variables[int(dev.pluginProps["variable" + str(index)])] compareString = unicode(var.value) self.debugLog ("\tChecking if variable '%s' value of '%s' is between '%s' and '%s'" % (var.name, compareString, dev.pluginProps["value" + str(index)], dev.pluginProps["endValue" + str(index)])) if compareString.lower() >= dev.pluginProps["value" + str(index)].lower() and compareString.lower() <= dev.pluginProps["endValue" + str(index)].lower(): val[0] = 1 val[1] = 0 else: val[0] = 0 val[1] = 1 if dev.pluginProps["evaluation" + str(index)] == "between": isTrue = isTrue + val[0] isFalse = isFalse + val[1] else: # It's the negative version so reverse the values isTrue = isTrue + val[1] isFalse = isFalse + val[0] except Exception as e: eps.printException(e) isTrue = 0 isFalse = 0 ret.append(isTrue) ret.append(isFalse) return ret
def updateChangedLCD(devChild, stateChangedAry): try: for pluginDevId, stateProps in stateChangedAry.iteritems(): for s in stateProps["stateChanges"]: if s in devChild.states: devParent = indigo.devices[int(pluginDevId)] # Make sure the state is valid - 1.13 if eps.valueValid(devChild.states, s) == False: indigo.server.log( "The watched state of '%s' on '%s' for LCD device '%s' is not a valid state and won't be converted" % (s, devChild.name, devParent.name), isError=True, ) return state = getStateDetails(devParent, s) if state is None: return # Added in 1.13 to handle invalid states stateValue = devChild.states[s] # Convert if required if state[3]: stateValue = convertStateValue(devParent, devChild, s, stateValue) parent.debugLog("\t%s changed to %s" % (s, unicode(devChild.states[s]))) if state[0]: # Convert a string to LCD value = lcdlib.stringToLCD(stateValue, state[2], devParent.pluginProps["textspaces"]) parent.debugLog("\t%s LCD readout string value is %s" % (s, value)) lcdlib.stringToGraphics(devParent, state[1], value) else: # Converting from a number to LCD padCharacter = "0" if devParent.pluginProps["spaces"]: padCharacter = " " # If this is a set point on a thermostat (or setmodesetpoint on extended), make sure decimals are zero since we can't set fractional temperatures on a thermostat if devParent.deviceTypeId == "epslcdth" and ( state[1] == "setpointHeat" or state[1] == "setpointCool" or state[1] == "setModeSetPoint" ): parent.debugLog("\t\tForcing integer value for set points") value = lcdlib.numberToLCD(stateValue, state[2], "round", padCharacter) else: value = lcdlib.numberToLCD( stateValue, state[2], devParent.pluginProps["decimals"], padCharacter ) parent.debugLog("\t%s LCD readout value is %s" % (s, value)) lcdlib.stringToGraphics(devParent, state[1], value) except Exception as e: eps.printException(e)
def setStates (dev, stateDisplay, value, number = None, boolean = None, image = indigo.kStateImageSel.None): try: dev.updateStateOnServer("statedisplay", stateDisplay) dev.updateStateOnServer("convertedValue", value) if number is not None: dev.updateStateOnServer("convertedNumber", number) if boolean is not None: dev.updateStateOnServer("convertedBoolean", boolean) dev.updateStateImageOnServer(image) except Exception as e: eps.printException(e)
def getDevStateDateTime (self, dev, devEx, index): d = indigo.server.getTime() try: if eps.valueValid (devEx.states, dev.pluginProps["state" + str(index)]) and eps.valueValid (dev.pluginProps, "dtFormat" + str(index), True): compareString = unicode(devEx.states[dev.pluginProps["state" + str(index)]]) self.debugLog ("\tConverting state '%s' date of '%s' using format '%s'" % (dev.pluginProps["state" + str(index)], compareString, dev.pluginProps["dtFormat" + str(index)])) d = datetime.datetime.strptime (compareString, dev.pluginProps["dtFormat" + str(index)]) except Exception as e: eps.printException(e) return d
def getVarDateTime (self, dev, index): d = indigo.server.getTime() try: if eps.valueValid (dev.pluginProps, "variable" + str(index), True) and eps.valueValid (dev.pluginProps, "dtFormat" + str(index), True): compareString = indigo.variables[int(dev.pluginProps["variable" + str(index)])].value self.debugLog ("\tConverting variable '%s' date of '%s' using format '%s'" % (indigo.variables[int(dev.pluginProps["variable" + str(index)])].name, compareString, dev.pluginProps["dtFormat" + str(index)])) d = datetime.datetime.strptime (compareString, dev.pluginProps["dtFormat" + str(index)]) except Exception as e: eps.printException(e) return d
def collapseAllConditions (self, dev): try: props = dev.pluginProps # See if this is a brand new device and if it is then set defaults if eps.valueValid (dev.pluginProps, "isNewDevice"): if dev.pluginProps["isNewDevice"]: #indigo.server.log("%s added, enabling conditions. You can now re-open the device to use conditions" % dev.name) props["conditions"] = "none" props["isNewDevice"] = False for i in range (1, self.maxConditions + 1): props = self.setUIDefaults (props, "disabled", "onOffState") dev.replacePluginPropsOnServer(props) return # don't do anything else # Set up collapse options if eps.valueValid (dev.pluginProps, "expandConditions1"): if props["expandConditions1"] == False: props["expandConditions1"] = True props["currentCondition"] = "1" props["noneExpanded"] = False # Check for multiple conditions to see if we need the padding if props["conditions"] != "none": for i in range (2, self.maxConditions + 1): if eps.valueValid (dev.pluginProps, "expandConditions" + str(i)): props["multiConditions"] = True # gives us extra padding on multiple conditions break props = self.setUIValueVisibility (props, 1) else: # If we don't have condition 1 then we don't have any return for i in range (2, self.maxConditions + 1): if eps.valueValid (dev.pluginProps, "expandConditions" + str(i)): if dev.pluginProps["expandConditions" + str(i)]: props["expandConditions" + str(i)] = False props = self.setUIDefaults (props, "disabled", "onOffState") if props != dev.pluginProps: self.debugLog ("Collapsing all conditions for %s" % dev.name) dev.replacePluginPropsOnServer(props) except Exception as e: eps.printException(e) return
def addUIConditionMenu (self, popupList): try: if popupList is None: popupList = [] evalList = ["none|No conditions", "alltrue|All items are true", "anytrue|Any items are true", "allfalse|All items are false", "anyfalse|Any items are false"] for s in evalList: eval = s.split("|") option = (eval[0], eval[1]) popupList.append (option) except Exception as e: eps.printException(e) popupList = [] option = ("error", "Error in conditions, see Indigo log") popupList.append (option) return popupList
def addUIEvals (self, popupList): try: if popupList is None: popupList = [] evalList = ["equal|Equal to", "notequal|Not equal to", "greater|Greater than", "less|Less than", "between|Between", "notbetween|Not between", "contains|Containing", "notcontains|Not containing"] for s in evalList: eval = s.split("|") option = (eval[0], eval[1]) popupList.append (option) except Exception as e: eps.printException(e) popupList = [] option = ("error", "Error in evaluations, see Indigo log") popupList.append (option) return popupList
def parsePlist (self, path): try: plist = open(path + "/Contents/Info.plist") nameIdx = 0 name = "" idIdx = 0 id = "" for line in plist: if nameIdx == 1: name = line nameIdx = 0 continue if idIdx == 1: id = line idIdx = 0 continue x = string.find (line, 'CFBundleDisplayName') if x > -1: nameIdx = 1 x = string.find (line, 'CFBundleIdentifier') if x > -1: idIdx = 1 #indigo.server.log (name + "\t" + id) x = string.find (name, "<string>") y = string.find (name, "</string>") name = name[x + 8:y] x = string.find (id, "<string>") y = string.find (id, "</string>") id = id[x + 8:y] return [id, name] except Exception as e: eps.printException(e) return ["Unknown", "Unknown"]
def appendUIConditions (self, popupList, type = "device"): try: type = type.lower() if popupList is None: popupList = [] option = ("disabled", "- CONDITION DISABLED -") popupList.append (option) if type == "device" or type == "all": option = ("device", "Device state") popupList.append (option) if type == "variable" or type == "all": option = ("variable", "Variable value") popupList.append (option) if type == "datetime" or type == "all": option = ("datetime", "Date and time") popupList.append (option) if type == "devstatedate" or type == "all": option = ("devstatedatetime", "Date and time from device state") popupList.append (option) if type == "vardate" or type == "all": option = ("vardatetime", "Date and time from variable") popupList.append (option) except Exception as e: eps.printException(e) popupList = [] option = ("error", "Error in conditions, see Indigo log") popupList.append (option) return popupList
def setUIDefaults (self, valuesDict, defaultCondition = "disabled", defaultState = "onOffState"): try: # Make sure times are defaulted if eps.valueValid (valuesDict, "startTime1", True) == False: self.debugLog ("Setting default values") for i in range (1, self.maxConditions + 1): if eps.valueValid (valuesDict, "condition" + str(i)): valuesDict["condition" + str(i)] = defaultCondition if eps.valueValid (valuesDict, "evaluation" + str(i)): valuesDict["evaluation" + str(i)] = "equal" if eps.valueValid (valuesDict, "state" + str(i)): valuesDict["state" + str(i)] = defaultState if eps.valueValid (valuesDict, "startTime" + str(i)): valuesDict["startTime" + str(i)] = "08:00" if eps.valueValid (valuesDict, "endTime" + str(i)): valuesDict["endTime" + str(i)] = "09:00" if eps.valueValid (valuesDict, "startMonth" + str(i)): valuesDict["startMonth" + str(i)] = "01" if eps.valueValid (valuesDict, "endMonth" + str(i)): valuesDict["endMonth" + str(i)] = "02" if eps.valueValid (valuesDict, "startDay" + str(i)): valuesDict["startDay" + str(i)] = "01" if eps.valueValid (valuesDict, "endDay" + str(i)): valuesDict["endDay" + str(i)] = "15" if eps.valueValid (valuesDict, "startDow" + str(i)): valuesDict["startDow" + str(i)] = "0" if eps.valueValid (valuesDict, "endDow" + str(i)): valuesDict["endDow" + str(i)] = "6" if eps.valueValid (valuesDict, "startYear" + str(i)): valuesDict["startYear" + str(i)] = "any" if eps.valueValid (valuesDict, "endYear" + str(i)): valuesDict["endYear" + str(i)] = "any" valuesDict = self.autoCollapseConditions (valuesDict) valuesDict = self.showPlaceholders (valuesDict) # If everything is collapsed then show the full placeholder if conditions are enabled if valuesDict["currentCondition"] == "0" and valuesDict["conditions"] != "none": self.debugLog("Current block is 0, setting placeholder") valuesDict["noneExpanded"] = True else: valuesDict["noneExpanded"] = False #indigo.server.log("\n" + unicode(valuesDict)) return valuesDict except Exception as e: eps.printException(e) return valuesDict
def temperature (value, convertC = False, precision = 1): try: if convertC: # Convert value to celsius value = float(value) value = (value - 32) / 1.8000 value = round(value, precision) if precision == 0: return int(value) return value else: # Default: convert value to fahrenheit value = float(value) value = (value * 1.8000) + 32 value = round(value, precision) if precision == 0: return int(value) return value except Exception as e: eps.printException(e)
def cachePluginActions (self): try: base = indigo.server.getInstallFolderPath() + "/Plugins" plugins = glob.glob(base + "/*.indigoPlugin") for plugin in plugins: pluginInfo = self.parsePlist (plugin) p = indigo.Dict() p["id"] = pluginInfo[0] p["name"] = pluginInfo[1] p["actions"] = {} indigo.server.log("Caching %s (%s)" % (p["name"], p["id"])) if os.path.isfile(plugin + "/Contents/Server Plugin/Actions.xml"): x = minidom.parse(plugin + "/Contents/Server Plugin/Actions.xml") actions = x.getElementsByTagName('Action') indigo.server.log("\tReading %i actions" % len(actions)) actionIdx = 0 allactions = indigo.Dict() for action in actions: paction = {} paction["id"] = action.attributes["id"].value paction["name"] = "" paction["callback"] = "" paction["devicefilter"] = "" paction["uipath"] = "" paction["separator"] = False paction["order"] = actionIdx paction["generic"] = True try: paction["devicefilter"] = action.attributes["deviceFilter"].value except: paction["devicefilter"] = "" # nothing we can do about it if paction["devicefilter"] != "": paction["devicefilter"] = paction["devicefilter"].replace("self", p["id"]) #indigo.server.log(paction["devicefilter"]) try: paction["uipath"] = action.attributes["uiPath"].value except: paction["uipath"] = "" # nothing we can do about it callback = action.getElementsByTagName("CallbackMethod") if callback: for c in callback: if c.parentNode.localName.lower() != "field": paction["callback"] = c.childNodes[0].data aname = action.getElementsByTagName("Name") if aname: for a in aname: paction["name"] = a.childNodes[0].data configUI = action.getElementsByTagName("ConfigUI") if configUI: paction["generic"] = False #if device != "": # indigo.server.log("\t\tCached action '%s' method %s for action ID %s for '%s' devices" % (name, cb, id, device)) #else: # indigo.server.log("\t\tCached action '%s' method %s for action ID %s" % (name, cb, id)) if action.hasChildNodes() == False: # Fields have children, seps do not #indigo.server.log("\t\t\tThis is a separator") paction["separator"] = True allactions[paction["id"]] = paction actionIdx = actionIdx + 1 p["actions"] = allactions self.CACHE[pluginInfo[0]] = p #indigo.server.log(unicode(self.CACHE)) except Exception as e: eps.printException(e)
def updateDevice (devId, changedStates): try: dev = indigo.devices[devId] # Our device if dev.pluginProps["chdevice"]: devEx = indigo.devices[int(dev.pluginProps["device"])] # Device we are watching if eps.valueValid (devEx.states, dev.pluginProps["states"]): value = devEx.states[dev.pluginProps["states"]] else: # It's a property if dev.pluginProps["states"] == "lastChanged": value = devEx.lastChanged else: devEx = "" value = indigo.variables[int(dev.pluginProps["variable"])] debugLog ("Processing changes on %s for value of '%s'" % (dev.name, unicode(value))) # ALWAYS TRUE if dev.pluginProps["action"] == "true": debugLog ("\tConverting to 'Always true'") setStates (dev, "true", "true", None, True) # ALWAYS FALSE if dev.pluginProps["action"] == "false": debugLog ("\tConverting to 'Always false'") dev.updateStateImageOnServer(indigo.kStateImageSel.None) setStates (dev, "false", "false", None, False) # VALUE TO BOOLEAN if dev.pluginProps["action"] == "bool": debugLog ("\tConverting value to boolean (bool)") value = unicode(value).lower() #if devEx.pluginProps["booleanstatetype"] == "float": value = float(value) truevalue = unicode(dev.pluginProps["truewhen"]).lower() falsevalue = unicode(dev.pluginProps["falsewhen"]).lower() statevalue = False if truevalue != "*else*": if value == truevalue: statevalue = True else: if falsevalue == "*else*": statevalue = False if falsevalue != "*else*": if value == falsevalue: statevalue = False else: if truevalue == "*else*": statevalue = True setStates (dev, unicode(statevalue).lower(), unicode(statevalue).lower(), None, statevalue) # BOOLEAN TO STRING if dev.pluginProps["action"] == "boolstr": debugLog ("\tConverting boolean value to string (boolstr)") value = unicode(value).lower() truevalue = unicode(dev.pluginProps["truewhen"]) falsevalue = unicode(dev.pluginProps["falsewhen"]) statevalue = falsevalue if value == "true": statevalue = truevalue setStates (dev, unicode(statevalue), unicode(statevalue)) # STRING TO NUMBER if dev.pluginProps["action"] == "strtonum": debugLog ("\tConverting string to number (strtonum)") value = unicode(value) if eps.valueValid (dev.pluginProps, "trimstart", True): if dev.pluginProps["trimstart"] != "0" and len(value) > int(dev.pluginProps["trimstart"]): self.debugLog("\tRemoving %i characters from beginning of string" % int(dev.pluginProps["trimstart"])) diff = int(dev.pluginProps["trimstart"]) value = value[diff:len(value)] if eps.valueValid (dev.pluginProps, "trimend", True): if dev.pluginProps["trimend"] != "0" and len(value) > int(dev.pluginProps["trimend"]): self.debugLog("\tRemoving %i characters from end of string" % int(dev.pluginProps["trimend"])) diff = int(dev.pluginProps["trimend"]) diff = diff * -1 value = value[:diff] try: dec = string.find (value, '.') numtype = dev.pluginProps["numtype"] if dec > -1 and numtype == "int": indigo.server.log("Input value of %s on %s contains a decimal, forcing value to be a float. Change the preferences for this device to get rid of this error." % (value, devEx.name), isError=True) numtype = "float" if numtype == "int": value = int(value) if numtype == "float": value = float(value) setStates (dev, value, value) except Exception as e: eps.printException(e) devEx.updateStateOnServer(key="statedisplay", value="Error", uiValue="Error") return except Exception as e: eps.printException(e)
def setUIValueVisibility (self, valuesDict, index): try: # Turn off everything, we'll turn it on below valuesDict["hasStartValue" + str(index)] = False valuesDict["hasStartTime" + str(index)] = False valuesDict["hasStartDate" + str(index)] = False valuesDict["hasStartDow" + str(index)] = False valuesDict["hasEndValue" + str(index)] = False valuesDict["hasEndTime" + str(index)] = False valuesDict["hasEndDate" + str(index)] = False valuesDict["hasEndDow" + str(index)] = False valuesDict["hasPythonFormat" + str(index)] = False valuesDict["hasDevice" + str(index)] = False valuesDict["hasVariable" + str(index)] = False if valuesDict["conditions"] == "none": #self.debugLog ("Condition checking has been turned off, disabling all condition fields") return valuesDict # nothing more to do, they turned off condition checking if valuesDict["expandConditions" + str(index)] == False: #self.debugLog ("Condition %i is collapsed" % index) return valuesDict # nothing more to do, they turned off condition checking if valuesDict["condition" + str(index)] == "disabled": #self.debugLog ("Condition %i is disabled" % index) return valuesDict # nothing more to do, they turned off condition checking # Turn on start values if valuesDict["condition" + str(index)] == "device" or valuesDict["condition" + str(index)] == "variable": valuesDict["hasStartValue" + str(index)] = True if valuesDict["condition" + str(index)] == "device": valuesDict["hasDevice" + str(index)] = True if valuesDict["condition" + str(index)] == "variable": valuesDict["hasVariable" + str(index)] = True elif valuesDict["condition" + str(index)] == "dateonly": valuesDict["hasStartDate" + str(index)] = True elif valuesDict["condition" + str(index)] == "timeonly": valuesDict["hasStartTime" + str(index)] = True elif valuesDict["condition" + str(index)] == "dow": valuesDict["hasStartDow" + str(index)] = True elif valuesDict["condition" + str(index)] == "datetime": valuesDict["hasStartTime" + str(index)] = True valuesDict["hasStartDate" + str(index)] = True elif valuesDict["condition" + str(index)] == "devstatedateonly": valuesDict["hasPythonFormat" + str(index)] = True valuesDict["hasStartDate" + str(index)] = True valuesDict["hasDevice" + str(index)] = True elif valuesDict["condition" + str(index)] == "devstatetimeonly": valuesDict["hasPythonFormat" + str(index)] = True valuesDict["hasStartTime" + str(index)] = True valuesDict["hasDevice" + str(index)] = True elif valuesDict["condition" + str(index)] == "devstatedatetime": valuesDict["hasPythonFormat" + str(index)] = True valuesDict["hasStartTime" + str(index)] = True valuesDict["hasStartDate" + str(index)] = True valuesDict["hasDevice" + str(index)] = True elif valuesDict["condition" + str(index)] == "devstatedow": valuesDict["hasPythonFormat" + str(index)] = True valuesDict["hasStartDow" + str(index)] = True valuesDict["hasDevice" + str(index)] = True elif valuesDict["condition" + str(index)] == "vardateonly": valuesDict["hasPythonFormat" + str(index)] = True valuesDict["hasStartDate" + str(index)] = True valuesDict["hasVariable" + str(index)] = True elif valuesDict["condition" + str(index)] == "vartimeonly": valuesDict["hasPythonFormat" + str(index)] = True valuesDict["hasStartTime" + str(index)] = True valuesDict["hasVariable" + str(index)] = True elif valuesDict["condition" + str(index)] == "vardatetime": valuesDict["hasPythonFormat" + str(index)] = True valuesDict["hasStartTime" + str(index)] = True valuesDict["hasStartDate" + str(index)] = True valuesDict["hasVariable" + str(index)] = True elif valuesDict["condition" + str(index)] == "vardow": valuesDict["hasPythonFormat" + str(index)] = True valuesDict["hasStartDow" + str(index)] = True valuesDict["hasVariable" + str(index)] = True if valuesDict["evaluation" + str(index)] == "between" or valuesDict["evaluation" + str(index)] == "notbetween": self.debugLog ("Condition %i requires an end value" % index) # See if we need to show or hide the end value or date/time contains value if valuesDict["condition" + str(index)] == "device" or valuesDict["condition" + str(index)] == "variable": valuesDict["hasEndValue" + str(index)] = True elif valuesDict["condition" + str(index)] == "devdate" or valuesDict["condition" + str(index)] == "vardate": valuesDict["hasEndValue" + str(index)] = True valuesDict["hasPythonFormat" + str(index)] = True elif valuesDict["condition" + str(index)] == "dateonly": valuesDict["hasEndDate" + str(index)] = True elif valuesDict["condition" + str(index)] == "timeonly": valuesDict["hasEndTime" + str(index)] = True elif valuesDict["condition" + str(index)] == "dow": valuesDict["hasEndDow" + str(index)] = True elif valuesDict["condition" + str(index)] == "datetime": valuesDict["hasEndTime" + str(index)] = True valuesDict["hasEndDate" + str(index)] = True elif valuesDict["condition" + str(index)] == "devstatedateonly": valuesDict["hasEndDate" + str(index)] = True elif valuesDict["condition" + str(index)] == "devstatetimeonly": valuesDict["hasEndTime" + str(index)] = True elif valuesDict["condition" + str(index)] == "devstatedow": valuesDict["hasEndDow" + str(index)] = True elif valuesDict["condition" + str(index)] == "devstatedatetime": valuesDict["hasEndTime" + str(index)] = True valuesDict["hasEndDate" + str(index)] = True elif valuesDict["condition" + str(index)] == "vardateonly": valuesDict["hasEndDate" + str(index)] = True elif valuesDict["condition" + str(index)] == "vartimeonly": valuesDict["hasEndTime" + str(index)] = True elif valuesDict["condition" + str(index)] == "vardow": valuesDict["hasEndDow" + str(index)] = True elif valuesDict["condition" + str(index)] == "vardatetime": valuesDict["hasEndTime" + str(index)] = True valuesDict["hasEndDate" + str(index)] = True else: indigo.server.log ("Unknown between condition for %i" % index, isError=True) elif valuesDict["evaluation" + str(index)] == "contains" or valuesDict["evaluation" + str(index)] == "notcontains": # Turn off start date fields since they aren't used here valuesDict["hasStartTime" + str(index)] = False valuesDict["hasStartDate" + str(index)] = False valuesDict["hasStartDow" + str(index)] = False valuesDict["hasEndValue" + str(index)] = False valuesDict["hasEndTime" + str(index)] = False valuesDict["hasEndDate" + str(index)] = False valuesDict["hasEndDow" + str(index)] = False valuesDict["hasStartValue" + str(index)] = True except Exception as e: eps.printException(e) return valuesDict
def conditionsDate (self, dev, index): ret = [] isTrue = 0 isFalse = 0 try: d = indigo.server.getTime() # If we are using a device state date (has devstate as prefix) then use that date instead if string.find (dev.pluginProps["condition" + str(index)], 'devstate') > -1: devEx = indigo.devices[int(dev.pluginProps["device" + str(index)])] d = self.getDevStateDateTime (dev, devEx, index) # If using a variable if string.find (dev.pluginProps["condition" + str(index)], 'var') > -1: d = self.getVarDateTime (dev, index) # Get the comparison startDate = self.getDateComparison (dev, index, d, "start") if dev.pluginProps["evaluation" + str(index)] == "equal" or dev.pluginProps["evaluation" + str(index)] == "notequal": self.debugLog ("\tChecking if calculated date of %s is equal to comparison date %s" % (startDate.strftime ("%Y-%m-%d %H:%M"), d.strftime ("%Y-%m-%d %H:%M"))) if startDate == d: isTrue = 1 else: isFalse = 1 if dev.pluginProps["evaluation" + str(index)] == "greater": self.debugLog ("\tChecking if calculated date of %s is greater than comparison date %s" % (startDate.strftime ("%Y-%m-%d %H:%M"), d.strftime ("%Y-%m-%d %H:%M"))) if startDate > d: isTrue = 1 else: isFalse = 1 if dev.pluginProps["evaluation" + str(index)] == "less": self.debugLog ("\tChecking if calculated date of %s is less than comparison date %s" % (startDate.strftime ("%Y-%m-%d %H:%M"), d.strftime ("%Y-%m-%d %H:%M"))) if startDate < d: isTrue = 1 else: isFalse = 1 if dev.pluginProps["evaluation" + str(index)] == "between" or dev.pluginProps["evaluation" + str(index)] == "notbetween": endDate = self.getDateComparison (dev, index, d, "end") self.debugLog ("\tChecking if comparison date of %s is between calculated dates of %s to %s" % (d.strftime ("%Y-%m-%d %H:%M"), startDate.strftime ("%Y-%m-%d %H:%M"), endDate.strftime ("%Y-%m-%d %H:%M"))) if d >= startDate and d <= endDate: isTrue = 1 else: isFalse = 1 except Exception as e: eps.printException(e) isTrue = 0 isFalse = 1 ret.append(isTrue) ret.append(isFalse) return ret
def getCachedActions (self, dev): retAry = [] try: # Anything without a type or id is typically an Indigo internal that we handle already if dev.pluginId == "" or dev.deviceTypeId == "": indigo.server.log("%s seems to be a built-in Indigo device that is not yet supported.\n\nIf you would like to see support for this device in future versions please post a request on the forum.\nPlugin:%s\nType:%s" % (dev.name, dev.pluginId, dev.deviceTypeId), isError=True) return retAry try: plugin = self.CACHE[dev.pluginId] except: indigo.server.log("%s does not have a cache, something may be wrong" % dev.name, isError=True) return retAry l = "" for i in range (0, 25): l += unicode("\xc4", "cp437") line = ["-1|" + l] #indigo.server.log("\n" + unicode(plugin["actions"])) tempAry = [] for i in range (0, len(plugin["actions"])): tempAry = self.appendOptionList (tempAry, line) for id, action in plugin["actions"].iteritems(): isMatch = self.matchesDevice (dev, plugin, action) for index, item in enumerate(tempAry): if action["separator"]: continue # that is already the default value if action["uipath"] == "hidden": continue if isMatch == False: continue if index == action["order"]: option = (action["callback"], action["name"]) tempAry[index] = option #indigo.server.log(unicode(plugin)) # Now audit the list to clean up entries that were not added newAry = [] for index, item in enumerate(tempAry): for id, action in plugin["actions"].iteritems(): if index == action["order"]: isMatch = self.matchesDevice (dev, plugin, action) if isMatch and action["uipath"] != "hidden" and action["generic"]: newAry.append(tempAry[index]) elif isMatch and action["generic"] == False and self.hasDefinedAction (dev, action["id"]): newAry.append(tempAry[index]) # Final audit to clean up anywhere that has strange separators if len(newAry) > 1: lastItem = None for index, item in enumerate(newAry): if lastItem is None: # Make sure the first item is not a separator if newAry[index] == self.appendOptionList ([], line): continue lastItem = newAry[index] continue if lastItem != newAry[index]: retAry.append(newAry[index]) else: retAry = newAry # Only one item, nothing more to do return retAry except Exception as e: eps.printException(e) return []
def getDateComparison (self, dev, index, d, prefix): curDate = indigo.server.getTime() try: # For now assume all values are equal to the date passed, this allows for use of "any" as # the value, because it's "any" that means that field will always match the comparison date year = int(d.strftime("%Y")) month = int(d.strftime("%m")) day = int(d.strftime("%d")) hour = int(d.strftime("%H")) minute = int(d.strftime("%M")) second = 0 # we never care about seconds # Evaluate the year if dev.pluginProps[prefix + "Year" + str(index)] == "any": year = year # do nothing, the default is already this elif dev.pluginProps[prefix + "Year" + str(index)] == "current": year = int(curDate.strftime("%Y")) elif dev.pluginProps[prefix + "Year" + str(index)] == "last": year = int(curDate.strftime("%Y")) - 1 elif dev.pluginProps[prefix + "Year" + str(index)] == "last": year = int(curDate.strftime("%Y")) + 1 else: year = int(dev.pluginProps[prefix + "Year" + str(index)]) # with no other options, they chose an actual year # Evaluate the month if dev.pluginProps[prefix + "Month" + str(index)] != "any": month = int(dev.pluginProps[prefix + "Month" + str(index)]) # Evaluate the day if dev.pluginProps[prefix + "Day" + str(index)] == "any": day = day # do nothing, the default is already this elif dev.pluginProps[prefix + "Day" + str(index)] == "first" or dev.pluginProps[prefix + "Day" + str(index)] == "second" or dev.pluginProps[prefix + "Day" + str(index)] == "third" or dev.pluginProps[prefix + "Day" + str(index)] == "fourth" or dev.pluginProps[prefix + "Day" + str(index)] == "last": newdate = self.getDayIteration(year, month, dev.pluginProps[prefix + "Day" + str(index)], dev.pluginProps[prefix + "Dow" + str(index)]) year = int(newdate.strftime("%Y")) month = int(newdate.strftime("%m")) day = int(newdate.strftime("%d")) elif dev.pluginProps[prefix + "Day" + str(index)] == "lastday": day = calendar.monthrange(year, month) day = day[1] else: day = int(dev.pluginProps[prefix + "Day" + str(index)]) # they chose a day # Evaluate the time if dev.pluginProps[prefix + "Time" + str(index)] == "any": hour = hour # do nothing, the default is already this else: time = dev.pluginProps[prefix + "Time" + str(index)] time = time.split(":") hour = int(time[0]) minute = int(time[1]) second = 0 # Re-assemble the date and return it retstr = str(year) + "-" + "%02d" % month + "-" + "%02d" % day + " " + "%02d" % hour + ":" + "%02d" % minute + ":" + "%02d" % second ret = datetime.datetime.strptime (retstr, "%Y-%m-%d %H:%M:%S") return ret except Exception as e: eps.printException(e) return curDate
def showPlaceholders (self, valuesDict): try: if self.enablePlaceholders == False: return valuesDict cb = valuesDict["currentCondition"] currentBlock = int(cb) if currentBlock == 0: return valuesDict # nothing to do # Disable all condition blocks valuesDict["isDisabled"] = False valuesDict["placeThree"] = False valuesDict["placeFour"] = False valuesDict["placeFive"] = False valuesDict["placeSix"] = False valuesDict["placeSeven"] = False valuesDict["placeNine"] = False valuesDict["placeTen"] = False valuesDict["placeThirteen"] = False valuesDict["placeFifteen"] = False # If there are no conditions if valuesDict["conditions"] == False: self.debugLog ("No conditions, current block is 0") valuesDict["currentCondition"] = "0" # it's the current condition and got collapsed, meaning all are collapsed return valuesDict # If it's collapsed then show that placeholder and return if valuesDict["expandConditions" + cb] == False: self.debugLog ("All blocks collapsed, current block is 0") valuesDict["currentCondition"] = "0" # it's the current condition and got collapsed, meaning all are collapsed return valuesDict valuesDict["multiConditions"] = False # Always turn it off here, save and close always turns it on bt = False # We have a "between" that extends things if valuesDict["evaluation" + cb] == "between" or valuesDict["evaluation" + cb] == "notbetween": bt = True if valuesDict["condition" + cb] == "disabled": valuesDict["isDisabled"] = True elif valuesDict["condition" + cb] == "timeonly" or valuesDict["condition" + cb] == "dow": valuesDict["placeThree"] = True elif (valuesDict["condition" + cb] == "variable" and bt == False) or valuesDict["condition" + cb] == "dateonly": valuesDict["placeFour"] = True elif (valuesDict["condition" + cb] == "device" and bt == False) or (valuesDict["condition" + cb] == "variable" and bt): valuesDict["placeFive"] = True elif (valuesDict["condition" + cb] == "device" and bt): valuesDict["placeSix"] = True elif (valuesDict["condition" + cb] == "datetime" and bt == False): valuesDict["placeSeven"] = True elif (valuesDict["condition" + cb] == "vardatetime" and bt == False): valuesDict["placeNine"] = True elif (valuesDict["condition" + cb] == "devstatedatetime" and bt == False): valuesDict["placeTen"] = True elif (valuesDict["condition" + cb] == "datetime" and bt): valuesDict["placeThirteen"] = True elif (valuesDict["condition" + cb] == "vardatetime" and bt): valuesDict["placeFifteen"] = True except Exception as e: eps.printException(e) return valuesDict
def conditionContain (self, dev, index): ret = [] isTrue = 0 isFalse = 0 try: compareString = "" devEx = None if dev.pluginProps["condition" + str(index)] == "device" or dev.pluginProps["condition" + str(index)] == "devstatedateonly" or dev.pluginProps["condition" + str(index)] == "devstatetimeonly" or dev.pluginProps["condition" + str(index)] == "devstatedatetime" or dev.pluginProps["condition" + str(index)] == "devstatedow": devEx = indigo.devices[int(dev.pluginProps["device" + str(index)])] if dev.pluginProps["condition" + str(index)] == "device": if eps.valueValid (devEx.states, dev.pluginProps["state" + str(index)]): compareString = unicode(devEx.states[dev.pluginProps["state" + str(index)]]) elif dev.pluginProps["condition" + str(index)] == "variable": var = indigo.variables[int(dev.pluginProps["variable" + str(index)])] compareString = unicode(var.value) elif dev.pluginProps["condition" + str(index)] == "datetime" or dev.pluginProps["condition" + str(index)] == "devstatedatetime" or dev.pluginProps["condition" + str(index)] == "vardatetime": d = indigo.server.getTime() if dev.pluginProps["condition" + str(index)] == "devstatedatetime": d = self.getDevStateDateTime (dev, devEx, index) if dev.pluginProps["condition" + str(index)] == "vardatetime": d = self.getVarDateTime (dev, index) compareString = d.strftime ("%Y-%m-%d %H:%M:%S | %m %b %B | %A %w | %I | %p") else: indigo.server.log("Unknown condition %s in contains" % dev.pluginProps["condition" + str(index)], isError=True) self.debugLog ("\tChecking if %s is in %s" % (dev.pluginProps["value" + str(index)], compareString)) compareValue = "" if compareString != "": compareValue = compareString.lower() findValue = "" if dev.pluginProps["value" + str(index)] != "": findValue = str(dev.pluginProps["value" + str(index)]).lower() if findValue != "": foundAt = string.find (compareString, findValue) if foundAt > -1: isTrue = 1 else: # It's the negative version so reverse the values isFalse = 1 else: if compareValue == "": isTrue = 1 else: isFalse = 1 except Exception as e: eps.printException(e) isTrue = 0 isFalse = 0 ret.append(isTrue) ret.append(isFalse) return ret
def base(self): try: X = 1 except Exception as e: eps.printException(e)