def NoteMsgDetails(devKey, arg): devIndex = GetIndexFromKey(devKey) if devIndex == None: synopsis.problem("Unknown device:",str(devKey)) return if arg[0] == expRsp[devIndex]: expRsp[devIndex] = None # Note that we've found the expected response now, so we're now clear to send presence.Set(devKey) # Note presence, and update radio quality if isnumeric(arg[-2]): if int(arg[-2]) < 0: # Assume penultimate item is RSSI, and thus that ultimate one is LQI rssi = arg[-2] lqi = arg[-1] try: signal = int((int(lqi, 16) * 100) / 255) # Convert 0-255 to 0-100. Ignore RSSI for now except ValueError: signal = -1 # Cannot get signal if signal != -1: entry = database.GetLatestLoggedItem(devKey, "SignalPercentage") if entry != None: oldSignal = entry[0] # Just the value fmt = "%Y-%m-%d %H:%M:%S" oldTimestamp = datetime.strptime(entry[1], fmt) if oldSignal == None: oldSignal = signal + 100 # Force an update if no previous signal deltaSignal = signal - oldSignal deltaTime = datetime.now() - oldTimestamp if abs(deltaSignal) > 5: if deltaTime.seconds > 600: # Only note signal level that's different enough and at least 10 minutes since last one database.LogItem(devKey, "SignalPercentage", signal) else: # signal is sufficiently similar to last one, so update timestamp database.RefreshLoggedItem(devKey, "SignalPercentage") # Update timestamp to avoid too many >10 minutes! arg.remove(rssi) arg.remove(lqi)
def EnsureReporting(devKey, clstrId, attrId, attrVal): # Check when this attr last reported and update device's reporting if necessary if isnumeric(attrVal, 16): newVal = int(attrVal, 16) # Assume value arrives in hex else: return if clstrId == zcl.Cluster.SimpleMetering and attrId == zcl.Attribute.InstantaneousDemand: prevItem = database.GetLatestLoggedItem(devKey, "PowerReadingW") # Check when we got last reading field = "powerReporting" #elif clstrId == zcl.Cluster.SimpleMetering and attrId == zcl.Attribute.CurrentSummationDelivered: # These energy* fields don't work, so interpolate power over time # prevItem = database.GetLatestLoggedItem(devKey, "EnergyConsumedWh") # field = "energyConsumedReporting" #elif clstrId == zcl.Cluster.SimpleMetering and attrId == zcl.Attribute.CurrentSummationReceived: # prevItem = database.GetLatestLoggedItem(devKey, "EnergyGeneratedWh") # field = "energyGeneratedReporting" else: # Don't know how often it should report. Could add temperature and battery return if prevItem != None: prevTime = prevItem[1] prevVal = prevItem[0] minMaxDelta = database.GetDeviceItem(devKey, field) # Look up min and max for this item if minMaxDelta != None: confList = minMaxDelta.split(",") min = int(confList[0]) max = int(confList[1]) delta = int(confList[2]) change = abs(newVal - int(prevVal)) secsSinceLastReport = (datetime.now() - datetime.strptime(prevTime, "%Y-%m-%d %H:%M:%S")).seconds # Work out time between now and prevTime in seconds log.debug("Prev report "+str(secsSinceLastReport)+" s ago, min="+str(min)+" for devKey "+str(devKey)+" with old val="+str(prevVal)+" vs new val of "+str(newVal)) if max == -1 or secsSinceLastReport < min or secsSinceLastReport > max: # Check whether min>secsSincelastReport>max or max==-1 Config(devKey, field) # Re-configure device elif secsSinceLastReport < max-(max/10) and change<delta: # Check delta if not too close to max Config(devKey, field) # Re-configure device
def MakeText(id): if weather.forecastPeriod=="": return None; reportDict = dict() reportDict["target"] = id minutes = datetime.now().minute #if minutes % 2 == 0: # reportDict["display"] = "off" #else: reportDict["display"] = "on" # For now at least reportDict["period"] = weather.forecastPeriod reportDict["icon"] = str(weather.symSym)[4:] reportDict["cloudText"] = weather.cloudText reportDict["maxTemp"] = str(round(weather.maxTemp))+"C" reportDict["minTemp"] = str(round(weather.minTemp))+"C" reportDict["windSpeed"] = str(round(weather.maxWind)) reportDict["windDir"] = str(weather.windDir) reportDict["windText"] = weather.windText now = datetime.now() reportDict["timeDigits"] = str(now.strftime("%H:%M")) reportDict["timeText"] = GetTimeInWords() reportDict["dayOfWeekText"] = str(now.strftime("%A")) reportDict["dayOfMonthText"] = str(int(now.strftime("%d"))) # Use int() to remove leading zero reportDict["monthText"] = str(now.strftime("%B")) powerMonitorName = config.Get("PowerMonitor") # House power monitoring device if powerMonitorName != None: devKey = devices.FindDev(powerMonitorName) if devKey != None: powerW = database.GetLatestLoggedItem(devKey, "PowerReadingW") if powerW != None: reportDict["powerNow"] = str(powerW[0]) energyToday = variables.Get("energyToday_kWh") if energyToday: reportDict["energyToday"] = energyToday tempMonitorName = config.Get("HouseTempDevice") # House temperature monitoring device if tempMonitorName != None: devKey = devices.FindDev(tempMonitorName) if devKey != None: houseTemp = database.GetLatestLoggedItem(devKey, "TemperatureCelsius") reportDict["houseTemp"] = '%.1f' % (houseTemp[0]) targetTemp = variables.Get("TargetTemp") if targetTemp != None: reportDict["TargetTemp"] = targetTemp #log.debug("ReportDict for:" +id + "=" + str(reportDict)) # Already reported in WiFiServer.py return (str(reportDict))
def Get(devKey): entry = database.GetLatestLoggedItem(devKey, "Presence") if entry != None: #log.debug("Presence entry says " + str(entry)) return datetime.strptime( entry[1], "%Y-%m-%d %H:%M:%S"), entry[0] # Should be time, val else: database.LogItem(devKey, "Presence", states.unknown ) # Set up an entry for this device for use in future return datetime.now(), states.unknown # Return something for now