def __diagNetwork(self): try: with open("/proc/net/route") as f: for line in f: fields = line.strip().split() if fields[ 1] != "00000000": # default gateway destination 0.0.0.0 continue #log.debug(fields) if int( fields[3], 16 ) & 2: # check route to be UG from the third field which is in base16 self.__networkStatus = True try: self.__networkGateway = socket.inet_ntoa( struct.pack("=L", int(fields[2], 16))) #self.__networkGateway = ".".join([str(int(fields[2][i:i+2], 16)) for i in range(0, len(fields[2]), 2)]) # depends on endianess except: self.__networkGateway = None log.debug("Cannot get gateway address.") log.debug("Network gateway (%s) up on interface %s" % (self.__networkGateway, fields[0])) return except: log.error("Cannot find /proc entry for network diag") self.__networkStatus = False
def addRecord(self, zone, commit=True): if (self.database.isOpen()): valuesToInsert = ( zone.zid, zone.SoilIntakeRate, zone.AvailableWater, zone.MaxAllowedDepletion, zone.RootDepth, zone.isTallPlant, zone.PrecipRate, zone.AppEfficiency, zone.AllowedSurfaceAcc, zone.FieldCapacity, zone.PermWilting, zone.MaxRuntime, ",".join(str(i) for i in zone.DetailedMonthsKc), zone.StartWaterLevel, ) if commit: try: self.database.execute("INSERT OR REPLACE INTO zones_advanced( zid, SoilIntakeRate, AvailableWater, MaxAllowedDepletion, RootDepth, isTallPlant, PrecipRate, \ AppEfficiency, AllowedSurfaceAcc, FieldCapacity, PermWilting, MaxRuntime, DetailedMonthsKc, StartWaterLevel) "\ "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", valuesToInsert) self.database.commit() except Exception, e: log.error(e) return False else: self.database.execute("INSERT OR REPLACE INTO zones_advanced( zid, SoilIntakeRate, AvailableWater, MaxAllowedDepletion, RootDepth, isTallPlant, PrecipRate, \ AppEfficiency, AllowedSurfaceAcc, FieldCapacity, PermWilting, MaxRuntime, DetailedMonthsKc, StartWaterLevel) "\ "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", valuesToInsert)
def perform(self): s = self.settings appKey = self.params.get("appKey", None) if appKey is None: self.lastKnownError = "Error: No Api Key" return URL = "https://api.darksky.net/forecast/" + str(appKey) + "/" + str( s.location.latitude) + "," + str(s.location.longitude) # URLParams = \ # [ # ("units", "si"), # ("exclude", "currently,minutely,alerts,flags"), # ("extend", "hourly") # ] URLParams = \ [ ("units", "si"), ("exclude", "currently,minutely,alerts,flags, hourly") ] try: d = self.openURL(URL, URLParams) if d is None: return forecast = json.loads(d.read()) self.__getDailyData(forecast) except Exception, e: log.error("*** Error running darksky.net parser") log.exception(e)
def perform(self): self.apiKey = self.params.get("apiKey", None) self.stationID = self.params.get("stationID", None) if self.apiKey is None or not self.apiKey or not isinstance( self.apiKey, str): self.lastKnownError = "Error: No API Key. Please register an account at https://www.willyweather.com.au/info/api.html" return self.params["_nearbyStationsIDList"] = [] self.noDays = 7 if self.params.get("stationLookUp"): s = self.settings llat = s.location.latitude llon = s.location.longitude searchURL = "https://api.willyweather.com.au/v2/" + self.apiKey + "/search.json" searchURLParams = [("lat", llat), ("lng", llon), ("units", "distance:km")] try: d = self.openURL(searchURL, searchURLParams) if d is None: return search = json.loads(d.read()) if self.parserDebug: log.info(search) self.getNearbyStations(search) except Exception, e: log.error("*** Error finding nearby stations") log.exception(e)
def _log_error(self, message, packet=None): if packet is not None: self.lastKnownError = message + ' ' + ''.join('\\x%02X' % ord(b) for b in packet) else: self.lastKnownError = message log.error(self.lastKnownError)
def addRecord(self, zone): if self.database.isOpen(): valuesToInsert = ( zone.uid, zone.name, zone.valveid, zone.ETcoef, zone.active, zone.type, zone.internet, zone.savings, zone.slope, zone.sun, zone.soil, zone.group_id, zone.history, ) try: self.database.execute( "INSERT OR REPLACE INTO zones( uid, name, valveid, ETcoef, active, type, internet, savings, slope, sun, soil, group_id, history) " "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", valuesToInsert, ) self.zonesAdvancedTable.addRecord(zone, False) self.database.commit() except Exception, e: log.error(e) return False
def perform(self): days = self.params["historicDays"] intervals = days / self.maxAllowedDays + (days % self.maxAllowedDays != 0) lastIntervalStartDay = datetime.date.today() if intervals > 1: days = self.maxAllowedDays log.debug("Days: %d Intervals: %d" % (days, intervals)) for i in range(0, intervals): startDay = lastIntervalStartDay - datetime.timedelta( days=1) # CIMIS real data starts from yesterday endDay = startDay - datetime.timedelta(days=(days + 1)) lastIntervalStartDay = endDay try: self.__retrieveData( endDay, startDay ) # we call with startDay/endDay swapped because CIMIS expects historic intervals except Exception, e: log.error("*** Error running CIMIS parser") self.lastKnownError = "Error: Data retrieval failed" log.exception(e)
def uploadDiag(self): localPath = globalSettings.databasePath remotePath = self.__getUploadFolderName() filesUploaded = 0 try: self.__connect() self.__ftp.mkd(remotePath) self.__ftp.cwd(remotePath) # Application files for file in self.fileList: try: self.status = RMDiagUpload.STATUS_UPLOADING if os.path.isabs(file): self.__upload(None, file) else: self.__upload(localPath, file) filesUploaded += 1 except Exception, e: log.error("uploadDiag: File: %s : %s" % (file, e)) if filesUploaded > 0: # rainmachine.log.1.gz might not had been created self.status = RMDiagUpload.STATUS_IDLE else: self.status = RMDiagUpload.STATUS_UPLOAD_ERROR self.__ftp.quit()
def addRecord(self, zone): if (self.database.isOpen()): valuesToInsert = ( zone.uid, zone.name, zone.valveid, zone.ETcoef, zone.active, zone.type, zone.internet, zone.savings, zone.slope, zone.sun, zone.soil, zone.group_id, zone.history, ) try: self.database.execute("INSERT OR REPLACE INTO zones( uid, name, valveid, ETcoef, active, type, internet, savings, slope, sun, soil, group_id, history) "\ "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", valuesToInsert) self.zonesAdvancedTable.addRecord(zone, False) self.database.commit() except Exception, e: log.error(e) return False
def __getSimpleForecast(self): try: timetuple = datetime.datetime.fromtimestamp(int( time.time())).timetuple() timestamp = datetime.datetime(timetuple.tm_year, timetuple.tm_mon, timetuple.tm_mday) dayTimestamp = int(time.mktime(timestamp.timetuple())) maxDayTimestamp = dayTimestamp + globalSettings.parserDataSizeInDays * 86400 simpleForecast = self.jsonResponse["response"][0] for key in simpleForecast["periods"]: log.debug(key) timestamp = self.__toInt(key["timestamp"]) if timestamp is None: continue timestamp = int(timestamp) if timestamp < maxDayTimestamp: #tt = self.__toInt(key["timestamp"]) #tt = rmGetStartOfDay(tt) #if tt > maxDayTimestamp: # break #timestamp = self.__toInt(tt) temperatureMax = self.__toFloat(key["maxTempC"]) temperatureMin = self.__toFloat(key["minTempC"]) wind = self.__toFloat(key["windSpeedKPH"]) if wind is not None: wind = wind / 3.6 # convertred from kmetersph to meterps humidity = self.__toFloat(key["humidity"]) qpf = self.__toFloat(key["precipMM"]) pop = self.convertToPercent(key["pop"]) dewpoint = self.__toFloat(key["avgDewpointC"]) condition = self.conditionConvert( key["weatherPrimaryCoded"], key["cloudsCoded"]) self.addValue(RMParser.dataType.QPF, timestamp, qpf) self.addValue(RMParser.dataType.RH, timestamp, humidity) self.addValue(RMParser.dataType.WIND, timestamp, wind) self.addValue(RMParser.dataType.POP, timestamp, pop) self.addValue(RMParser.dataType.DEWPOINT, timestamp, dewpoint) self.addValue(RMParser.dataType.MINTEMP, timestamp, temperatureMin) self.addValue(RMParser.dataType.MAXTEMP, timestamp, temperatureMax) self.addValue(RMParser.dataType.CONDITION, timestamp, condition) log.debug(timestamp) log.debug(temperatureMax) log.debug(temperatureMin) log.debug(wind) log.debug(humidity) log.debug(qpf) log.debug(condition) except: log.error("Failed to get simple forecast")
def __unmanglePassword(self, mangle): if not mangle or len(mangle) != 112: return None tokenSize = len(mangle) / 16 tokens = [ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" ] index = 0 while index <= 15: token = mangle[(index * tokenSize):((index + 1) * tokenSize)] if token[0] == '3': tokens[0] = token[1:tokenSize] elif token[0] == 'b': tokens[15] = token[1:tokenSize] index += 1 password = "".join(tokens) log.error("Mangle: %s" % mangle) log.error("Password: %s" % password) return password
def getNearbyStationsNoKey(self): MIN_STATIONS = 1 MAX_STATIONS = 20 s = self.settings llat = s.location.latitude llon = s.location.longitude stationsURL = "https://stationdata.wunderground.com/cgi-bin/stationdata?v=2.0&type=ICAO%2CPWS&units=metric&format=json&maxage=1800&maxstations=" \ + str(MAX_STATIONS) + "&minstations=" + str(MIN_STATIONS) + "¢erLat=" + str(llat) + "¢erLon=" \ + str(llon) + "&height=400&width=400&iconsize=2&callback=__ng_jsonp__.__req1.finished" try: # WARNING: WE PROBABLY SHOULD FAIL IF WE CAN'T GET STATIONS IF USER KNOWS STATION_ID log.debug("Downloading station data from: %s" % stationsURL) d = self.openURL(stationsURL, headers=self.headers) if d is None: self.lastKnownError = "Cannot download nearby stations" log.error(self.lastKnownError) # extract object from callback parameter stationsData = d.read() stationsObj = stationsData[stationsData. find("{"):stationsData.rfind("}") + 1] # log.info(stationsObj) stations = json.loads(stationsObj) self.parseNearbyStationsNoKey(stations) except Exception, e: self.lastKnownError = "ERROR: Cannot get nearby stations" log.error(self.lastKnownError) return
def __parseStationData(self, jsonContent): observations = {} try: temperature = self.__toFloat(jsonContent.get("temp_c", None)) rh = self.__toFloat(jsonContent.get("relative_humidity", None)) wind = self.__toFloat(jsonContent.get("wind_kph", None)) wind_gust = self.__toFloat(jsonContent.get("wind_gust_kph", None)) pressure = self.__toFloat(jsonContent.get("pressure_mb", None)) dew = self.__toFloat(jsonContent.get("dewpoint_c", None)) heat = self.__toFloat(jsonContent.get("heat_index_c", None)) rain = self.__toFloat(jsonContent.get("precip_1hr_metric", None)) # Conversions if wind is not None: #kph to mps wind = wind / 3.6 if pressure is not None: # mb to kpa pressure = pressure / 10 observations["temperature"] = temperature observations["rh"] = rh observations["wind"] = wind observations["wind_gust"] = wind_gust observations["pressure"] = pressure observations["dew"] = dew observations["heat"] = heat observations["rain"] = rain except Exception, e: log.error("Can't parse data %s" % e) self.lastKnownError = "Error: Can't parse data"
def __rest(self, type, apiCall, data = None, isBinary = False, extraHeaders = None, majorVersion="", asJSON = True): protocol = RMAPIClientProtocol.getAsString(self._protocol) apiUrl = protocol + self._host + ":" + self._port + "/api/" + majorVersion + "/" if self.token is None: url = apiUrl + apiCall else: url = apiUrl + apiCall + "?access_token=" + self.token try: req = urllib2.Request(url) req.get_method = lambda: type # Force GET/POST depending on type except: return RMAPIClientErrors.REQ if isBinary: req.add_data(data=data) else: req.add_data(data=json.dumps(data)) req.add_header("Content-type","text/plain") if extraHeaders is not None: for header in extraHeaders: req.add_header(header) try: log.info("REST: %s : %s" % (req.get_method(), req.get_full_url())) r = urllib2.urlopen(req) data = r.read() except Exception, e: log.error("Cannot OPEN URL: %s" % e) return RMAPIClientErrors.OPEN
def perform(self): URL = self.params.get("urlPath", None) d = self.openURL(URL) if d is None: return pwsContent = d.read() if pwsContent is None: return pwsContent = pwsContent.strip() pwsArray = pwsContent.split(" ") lat = float(pwsArray[160]) lon = -float(pwsArray[161]) distToPWS = self.distanceToStation(lat, lon) maxDist = self.params.get("maxAllowedDistance") if (distToPWS > maxDist): log.error("*** PWS Station too far from home!") return temperature = self.__toFloat(pwsArray[4]) mintemp = self.__toFloat(pwsArray[47]) maxtemp = self.__toFloat(pwsArray[46]) rh = self.__toFloat(pwsArray[5]) minrh = self.__toFloat(pwsArray[164]) maxrh = self.__toFloat(pwsArray[163]) wind = self.__toFloat(convertKnotsToMS( pwsArray[1])) # converted from knos to m/s solarradiation = self.__toFloat( pwsArray[127] ) # needs to be converted from watt/sqm*h to Joule/sqm if solarradiation is not None: solarradiation *= 0.0864 rain = self.__toFloat(pwsArray[7]) dewpoint = self.__toFloat(pwsArray[72]) pressure = self.__toFloat(pwsArray[50]) conditionIcon = self.conditionConvert(self.__toFloat(pwsArray[48])) #skycover ? timestamp = rmCurrentTimestamp() self.addValue(RMParser.dataType.TEMPERATURE, timestamp, temperature) self.addValue(RMParser.dataType.MINTEMP, timestamp, mintemp) self.addValue(RMParser.dataType.MAXTEMP, timestamp, maxtemp) self.addValue(RMParser.dataType.RH, timestamp, rh) self.addValue(RMParser.dataType.MINRH, timestamp, minrh) self.addValue(RMParser.dataType.MAXRH, timestamp, maxrh) self.addValue(RMParser.dataType.WIND, timestamp, wind) self.addValue(RMParser.dataType.RAIN, timestamp, rain) self.addValue(RMParser.dataType.DEWPOINT, timestamp, dewpoint) self.addValue(RMParser.dataType.PRESSURE, timestamp, pressure) self.addValue(RMParser.dataType.CONDITION, timestamp, conditionIcon) self.addValue(RMParser.dataType.SOLARRADIATION, timestamp, solarradiation) print self.result return
def __checkFactoryReset(self): factoryReset = os.path.exists("/tmp/factory-reset") if factoryReset and self.__mainManager: try: os.remove("/tmp/factory-reset") except Exception, e: log.error(e) self.__mainManager.factoryReset()
def unregisterThread(self): ### Call this method from the thread you want to unregister. with self.__lock: key = thread.get_ident() entry = self.__data.pop(key, None) if entry is None: log.error("Thread key %s not found. unregister failed" % key) return False return True
def __setWatchdogMaxTimeout(self): WDIOC_SETTIMEOUT = 0xC0045706 # direction(3 RW) << 30 | size (4 int) << 16 | type ( 'W') << 8 | number (6) timeout = ctypes.c_int(120) # seconds if self.__watchDogDescriptor is not None: fd = self.__watchDogDescriptor.fileno() ioctl(fd, WDIOC_SETTIMEOUT, timeout) self.__watchDogDescriptor.close() else: log.error("Can't set watchdog max timeout. Device not opened")
def perform(self): s = self.settings headers = [{ "User-Agent": "RainMachine.com v2" }, { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"}] URL = "https://api.met.no/weatherapi/locationforecast/2.0/classic" URLParams = [("lat", s.location.latitude), ("lon", s.location.longitude), ("altitude", int(round(s.location.elevation)))] #----------------------------------------------------------------------------------------------- # # Get hourly data. # d = self.openURL(URL, URLParams, headers=headers[random.randint(0, 1)]) if d is None: return tree = e.parse(d) #tree = e.parse("/tmp/MET.NO/forecast.xml") if tree.getroot().tag == 'error': log.error("*** No hourly information found in response!") self.lastKnownError = "Error: No hourly information found" tree.getroot().clear() del tree tree = None else: data = self.__parseXMLData(tree) # Free memory tree.getroot().clear() del tree tree = None temp = self.__extractTagData(data, 'temperature') mintemp = self.__extractTagData(data, 'minTemperature') maxtemp = self.__extractTagData(data, 'maxTemperature') dewpoint = self.__extractTagData(data, 'dewpointTemperature') wind = self.__extractTagData(data, 'windSpeed') humidity = self.__extractTagData(data, 'humidity') pressure = self.__extractTagData(data, 'pressure') qpf = self.__extractTagData(data, 'precipitation') condition = self.__extractTagData(data, 'symbol') self.addValues(RMParser.dataType.TEMPERATURE, temp) self.addValues(RMParser.dataType.MINTEMP, mintemp) self.addValues(RMParser.dataType.MAXTEMP, maxtemp) self.addValues(RMParser.dataType.DEWPOINT, dewpoint) self.addValues(RMParser.dataType.WIND, wind) self.addValues(RMParser.dataType.RH, humidity) self.addValues(RMParser.dataType.QPF, qpf) self.addValues(RMParser.dataType.PRESSURE, pressure) self.addValues(RMParser.dataType.CONDITION, condition)
def __refreshWIFI(self): timestamp = rmCurrentTimestamp() lastWIFICheckTimestamp = globalWIFI.wifiInterface.lastWIFICheckTimestamp oldIP = globalWIFI.wifiInterface.ipAddress if lastWIFICheckTimestamp is None or oldIP is None or ( timestamp - lastWIFICheckTimestamp) >= self.__wifiRefreshTimeout: try: globalWIFI.detect() if oldIP != globalWIFI.wifiInterface.ipAddress: log.info( "Refreshed WIFI Information. (old: %s new ip: %s)" % ( ` oldIP `, ` globalWIFI.wifiInterface.ipAddress `)) if RMOSPlatform().AUTODETECTED == RMOSPlatform.ANDROID: return # Handle None IP if globalWIFI.wifiInterface.ipAddress is None: if self.__lastNoneIpTimestamp is None or ( timestamp - self.__lastNoneIpTimestamp ) < self.__wifiNoneIpTimeout: # First occurrence of None IP OR we can wait some more time. if self.__lastNoneIpTimestamp is None: self.__lastNoneIpTimestamp = timestamp log.debug( "Refreshed WIFI Information - no IP detected. Give it some more time: %d seconds!" % (self.__wifiNoneIpTimeout - (timestamp - self.__lastNoneIpTimestamp), )) return else: globalWIFI.restart() log.warn( "Refreshed WIFI Information - WIFI quick reloaded because no IP detected. New IP is %s" % ` globalWIFI.wifiInterface.ipAddress `) self.__lastNoneIpTimestamp = None # Reset None IP timestamp. # Check if we never connected to this AP, set back AP mode and restart app if globalWIFI.wifiInterface.mode == "managed" and not globalWIFI.hasConnectedOnce( ): if globalWIFI.wifiInterface.hasClientLink: globalWIFI.saveHasConnectedOnce(True) else: log.warning( "WIFI Watcher Client IP (%s) configuration failed, restarting in AP mode." % oldIP) globalWIFI.setDefaultAP() globalWIFI.saveHasConnectedOnce(False) globalWIFI.restart() self.__mainManager.touchWakeMessage() except Exception, e: log.error(e)
def perform(self): URL = self.params.get("urlPath", None) d = self.openURL(URL) if d is None: return pwsContent = d.read() if pwsContent is None: return pwsContent = pwsContent.strip() pwsArray = pwsContent.split(" ") lat = float(pwsArray[160]) lon = -float(pwsArray[161]) distToPWS = self.distanceToStation(lat, lon) maxDist = self.params.get("maxAllowedDistance") if(distToPWS > maxDist): log.error("*** PWS Station too far from home!") return temperature = self.__toFloat(pwsArray[4]) mintemp = self.__toFloat(pwsArray[47]) maxtemp = self.__toFloat(pwsArray[46]) rh = self.__toFloat(pwsArray[5]) minrh = self.__toFloat(pwsArray[164]) maxrh = self.__toFloat(pwsArray[163]) wind = self.__toFloat(convertKnotsToMS(pwsArray[1])) # converted from knos to m/s solarradiation = self.__toFloat(pwsArray[127]) # needs to be converted from watt/sqm*h to Joule/sqm if solarradiation is not None: solarradiation *= 0.0864 rain = self.__toFloat(pwsArray[7]) dewpoint = self.__toFloat(pwsArray[72]) pressure = self.__toFloat(pwsArray[50]) conditionIcon = self.conditionConvert(self.__toFloat(pwsArray[48])) #skycover ? timestamp = rmCurrentTimestamp() self.addValue(RMParser.dataType.TEMPERATURE, timestamp, temperature) self.addValue(RMParser.dataType.MINTEMP, timestamp, mintemp) self.addValue(RMParser.dataType.MAXTEMP, timestamp, maxtemp) self.addValue(RMParser.dataType.RH, timestamp, rh) self.addValue(RMParser.dataType.MINRH, timestamp, minrh) self.addValue(RMParser.dataType.MAXRH, timestamp, maxrh) self.addValue(RMParser.dataType.WIND, timestamp, wind) self.addValue(RMParser.dataType.RAIN, timestamp, rain) self.addValue(RMParser.dataType.DEWPOINT, timestamp, dewpoint) self.addValue(RMParser.dataType.PRESSURE, timestamp, pressure) self.addValue(RMParser.dataType.CONDITION, timestamp, conditionIcon) self.addValue(RMParser.dataType.SOLARRADIATION, timestamp, solarradiation) print self.result return
def parseStationYesterdayDataNoKey(self, data): #daily summary for yesterday try: l = RMWeatherDataLimits() temperature = self.__toFloat(data["TemperatureAvgC"]) mintemp = self.__toFloat(data["TemperatureLowC"]) maxtemp = self.__toFloat(data["TemperatureHighC"]) rh = self.__toFloat(data["HumidityAvg"]) minrh = self.__toFloat(data["HumidityLow"]) maxrh = self.__toFloat(data["HumidityHigh"]) dewpoint = self.__toFloat(data["DewpointAvgC"]) wind = self.__toFloat(data["WindSpeedAvgKMH"]) maxpressure = self.__toFloat(data["PressureMaxhPa"]) minpressure = self.__toFloat(data["PressureMinhPa"]) rain = self.__toFloat( data["PrecipitationSumCM"]) * 10.0 # from cm to mm if wind is not None: wind = wind / 3.6 # converted from kmetersph to mps if maxpressure is not None: maxpressure = l.sanitize(RMWeatherDataType.PRESSURE, maxpressure / 10.0) # converted to from hpa to kpa if minpressure is not None: minpressure = l.sanitize(RMWeatherDataType.PRESSURE, minpressure / 10.0) pressure = None if maxpressure is not None and minpressure is not None: pressure = (maxpressure + minpressure) / 2.0 #log.info("rh:%s minrh: %s maxrh: %s pressure: %s temp: %s mintemp: %s maxtemp: %s" % (rh, minrh, maxrh, pressure, temperature, mintemp, maxtemp)) timestamp = rmCurrentDayTimestamp() timestamp = rmGetStartOfDay(timestamp - 12 * 3600) self.addValue(RMParser.dataType.TEMPERATURE, timestamp, temperature, False) self.addValue(RMParser.dataType.MINTEMP, timestamp, mintemp, False) self.addValue(RMParser.dataType.MAXTEMP, timestamp, maxtemp, False) self.addValue(RMParser.dataType.RH, timestamp, rh, False) self.addValue(RMParser.dataType.MINRH, timestamp, minrh, False) self.addValue(RMParser.dataType.MAXRH, timestamp, maxrh, False) self.addValue(RMParser.dataType.WIND, timestamp, wind, False) self.addValue(RMParser.dataType.RAIN, timestamp, rain, False) self.addValue(RMParser.dataType.DEWPOINT, timestamp, dewpoint, False) self.addValue(RMParser.dataType.PRESSURE, timestamp, pressure, False) except Exception, e: self.lastKnownError = "ERROR: Failed to get historical data" log.error("%s: %s" % (self.lastKnownError, e))
def __getStationData(self, URL): try: d = self.openURL(URL) jsonResponse = d.read() jsonContent = json.loads(jsonResponse) jsonContent = jsonContent["current_observation"] except Exception, e: log.error("Invalid data received %s" % e) self.lastKnownError = "Error: Invalid data received" return None
def doRun(self): #------------------------------------------------------------------------- # Handle the events / commands. command = None while True: try: if not self.doHandleMessages(): break except Exception, e: log.error(e)
def __getDailyData(self, forecast): dayTimestamp = rmCurrentDayTimestamp() maxDayTimestamp = dayTimestamp + globalSettings.parserDataSizeInDays * 86400 daily = [] try: daily = forecast["daily"]["data"] except Exception, e: log.error("*** No daily information found in response!") self.lastKnownError = "Warning: No daily information" log.exception(e)
def perform(self): station = self.params.get("station", None) if station is None: self.lastKnownError = "No station number configured." log.error(self.lastKnownError) return res = self.performWithDataFeeds(station) if not res: self.performWithReport(station)
def perform(self): s = self.settings URLHourly = "http://fawn.ifas.ufl.edu/controller.php/lastHour/summary/json" URLDaily = "http://fawn.ifas.ufl.edu/controller.php/lastDay/summary/json" URLParams = [] useHourly = self.params.get("useHourly", False) # ----------------------------------------------------------------------------------------------- # # Get hourly data. # if useHourly: try: d = self.openURL(URLHourly, URLParams) if d is None: return json_data = d.read() json_data = json_data.replace("'", '"') hourly = json.loads(json_data) for entry in hourly: # only selected station if int(entry.get("StationID")) == self.params.get("station"): dateString = entry.get("startTime") # timestamp = rmTimestampFromDateAsStringWithOffset(dateString) timestamp = rmTimestampFromDateAsString(dateString[:-6], "%Y-%m-%dT%H:%M:%S") if timestamp is None: log.debug("Cannot convert hourly data startTime: %s to unix timestamp" % dateString) continue # Add 12h in the future for FAWN timestamp to fix badly reported offset and make it middle of the day UTC (Dragos) timestamp += 12 * 60 * 60 self.addValue(RMParser.dataType.TEMPERATURE, timestamp, self.__toFloat(entry.get("t2m_avg"))) self.addValue(RMParser.dataType.MINTEMP, timestamp, self.__toFloat(entry.get("t2m_min"))) self.addValue(RMParser.dataType.MAXTEMP, timestamp, self.__toFloat(entry.get("t2m_max"))) # km/h -> m/s self.addValue( RMParser.dataType.WIND, timestamp, 0.27777777777778 * self.__toFloat(entry.get("ws_avg")) ) # cm -> mm self.addValue(RMParser.dataType.RAIN, timestamp, 10 * self.__toFloat(entry.get("rain_sum"))) self.addValue(RMParser.dataType.DEWPOINT, timestamp, self.__toFloat(entry.get("dp_avg"))) self.addValue(RMParser.dataType.RH, timestamp, self.__toFloat(entry.get("rh_avg"))) if self.parserDebug: log.debug(self.result) except Exception, e: log.error("*** Error retrieving hourly data from FAWN") log.exception(e)
def perform(self): url = 'https://api.ambientweather.net/v1/devices/' + str( self.params["macAddress"]) parameterList = [("apiKey", str(self.params["apiKey"])), ("applicationKey", str(self.params["applicationKey"])), ("limit", "1")] log.info('Getting data from {0}'.format(str(url))) data = self.openURL(url, parameterList) if data is None: self.lastKnownError = "Error: No data received from server" log.error(self.lastKnownError) return station = json.loads(data.read()) for entry in station: dateutc = entry["dateutc"] / 1000 # from milliseconds if 'tempf' in entry: temp = convertFahrenheitToCelsius(entry["tempf"]) self.addValue(RMParser.dataType.TEMPERATURE, dateutc, temp, False) if 'humidity' in entry: self.addValue(RMParser.dataType.RH, dateutc, entry["humidity"], False) if 'windspeedmph' in entry: windspeed = entry["windspeedmph"] * 0.44704 # to meters/sec self.addValue(RMParser.dataType.WIND, dateutc, windspeed, False) if 'solarradiation' in entry: solarrad = convertRadiationFromWattsToMegaJoules( entry["solarradiation"]) self.addValue(RMParser.dataType.SOLARRADIATION, dateutc, solarrad, False) if 'dailyrainin' in entry: rain = convertInchesToMM(entry["dailyrainin"]) self.addValue(RMParser.dataType.RAIN, dateutc, rain, False) if 'baromrelin' in entry: pressure = entry["baromrelin"] * 3.38639 # to kPa self.addValue(RMParser.dataType.PRESSURE, dateutc, pressure, False) if 'dewPoint' in entry: dewpoint = convertFahrenheitToCelsius(entry["dewPoint"]) self.addValue(RMParser.dataType.DEWPOINT, dateutc, dewpoint, False) return True
def addRecord(self, zid, timestamp, day, startWaterLevel): if (self.database.isOpen()): try: self.database.execute("INSERT OR REPLACE INTO %s(zid, timestamp, day, startWaterLevel) "\ "VALUES(?, ?, ?, ?)" % self._tableName, (zid, timestamp, day, startWaterLevel)) self.database.commit() return True except Exception, e: log.error(e)
def performWithDataFeeds(self, station): s = self.settings URLHourly = "http://fawn.ifas.ufl.edu/controller.php/lastHour/summary/json" URLDaily = "http://fawn.ifas.ufl.edu/controller.php/lastDay/summary/json" URLParams = [] useHourly = self.params.get("useHourly", False) #----------------------------------------------------------------------------------------------- # # Get hourly data. # if useHourly: try: log.info("Retrieving data from: %s" % URLHourly) d = self.openURL(URLHourly, URLParams) if d is None: return json_data = d.read() json_data = json_data.replace("'","\"") hourly = json.loads(json_data) for entry in hourly: # only selected station if int(entry.get("StationID")) == station: dateString = entry.get("startTime") #timestamp = rmTimestampFromDateAsStringWithOffset(dateString) timestamp = rmTimestampFromDateAsString(dateString[:-6], '%Y-%m-%dT%H:%M:%S') if timestamp is None: log.debug("Cannot convert hourly data startTime: %s to unix timestamp" % dateString) continue # Add 12h in the future for FAWN timestamp to fix badly reported offset and make it middle of the day UTC (Dragos) timestamp += 12 * 60 *60 self.addValue(RMParser.dataType.TEMPERATURE, timestamp, self.__toFloat(entry.get("t2m_avg"))) self.addValue(RMParser.dataType.MINTEMP, timestamp, self.__toFloat(entry.get("t2m_min"))) self.addValue(RMParser.dataType.MAXTEMP, timestamp, self.__toFloat(entry.get("t2m_max"))) # km/h -> m/s self.addValue(RMParser.dataType.WIND, timestamp, 0.27777777777778 * self.__toFloat(entry.get("ws_avg"))) # cm -> mm self.addValue(RMParser.dataType.RAIN, timestamp, 10 * self.__toFloat(entry.get("rain_sum"))) self.addValue(RMParser.dataType.DEWPOINT, timestamp, self.__toFloat(entry.get("dp_avg"))) self.addValue(RMParser.dataType.RH, timestamp, self.__toFloat(entry.get("rh_avg"))) if self.parserDebug: log.debug(self.result) except Exception, e: self.lastKnownError = "Error retrieving hourly data." log.error(self.lastKnownError) log.exception(e)
def perform(self): s = self.settings URL = "https://api.met.no/weatherapi/locationforecastlts/1.3/" URLParams = [("lat", s.location.latitude), ("lon", s.location.longitude), ("msl", int(round(s.location.elevation)))] #----------------------------------------------------------------------------------------------- # # Get hourly data. # d = self.openURL(URL, URLParams) if d is None: return tree = e.parse(d) #tree = e.parse("/tmp/MET.NO/forecast.xml") if tree.getroot().tag == 'error': log.error("*** No hourly information found in response!") self.lastKnownError = "Error: No hourly information found" tree.getroot().clear() del tree tree = None else: data = self.__parseXMLData(tree) # Free memory tree.getroot().clear() del tree tree = None temp = self.__extractTagData(data, 'temperature') mintemp = self.__extractTagData(data, 'minTemperature') maxtemp = self.__extractTagData(data, 'maxTemperature') dewpoint = self.__extractTagData(data, 'dewpointTemperature') wind = self.__extractTagData(data, 'windSpeed') humidity = self.__extractTagData(data, 'humidity') pressure = self.__extractTagData(data, 'pressure') qpf = self.__extractTagData(data, 'precipitation') condition = self.__extractTagData(data, 'symbol') self.addValues(RMParser.dataType.TEMPERATURE, temp) self.addValues(RMParser.dataType.MINTEMP, mintemp) self.addValues(RMParser.dataType.MAXTEMP, maxtemp) self.addValues(RMParser.dataType.DEWPOINT, dewpoint) self.addValues(RMParser.dataType.WIND, wind) self.addValues(RMParser.dataType.RH, humidity) self.addValues(RMParser.dataType.QPF, qpf) self.addValues(RMParser.dataType.PRESSURE, pressure) self.addValues(RMParser.dataType.CONDITION, condition)
def installParser(self, tempFilePath, fileName): filePath = os.path.abspath( os.path.join(os.path.dirname(os.path.abspath(__file__)), "parsers", fileName)) shutil.move(tempFilePath, filePath) try: module = imp.load_source(fileName, filePath) log.info(" * Parser %s successful loaded from file '%s'" % (fileName, filePath)) parser = RMParser.parsers[-1] # Last added parser enabled = parser.isEnabledForLocation(globalSettings.location.timezone, \ globalSettings.location.latitude, \ globalSettings.location.longitude ) parserConfig, isNew = self.parserTable.addParser( fileName, parser.parserName, enabled, parser.params) if not isNew: params = self.parserTable.getParserParams(parserConfig.dbID) if params: parser.params = params RMParser.parsers.pop() #delete old entry pkeys = self.parsers.keys() for pkey in pkeys: if parserConfig.dbID is pkey.dbID: del self.parsers[pkey] self.parsers[parserConfig] = parser parserConfig.userDataTypes = self.userDataTypeTable.addRecords( parser.userDataTypes) self.parserUserDataTypeTable.addRecords(parserConfig.dbID, parserConfig.userDataTypes) log.debug(parserConfig) return True except Exception as e: try: if os.path.exists(filePath): os.remove(filePath) except Exception, e: log.exception(e) log.error(" * Error installing/loading parser %s from file '%s'" % (fileName, filePath)) log.exception(e)
def __getSimpleForecast(self): try: tuple = datetime.datetime.fromtimestamp(int( time.time())).timetuple() dayTimestamp = int( datetime.datetime(tuple.tm_year, tuple.tm_mon, tuple.tm_mday).strftime("%s")) maxDayTimestamp = dayTimestamp + globalSettings.parserDataSizeInDays * 86400 simpleForecast = self.jsonResponse["forecast"]["simpleforecast"][ "forecastday"] timestamp = [] temperatureMax = [] temperatureMin = [] wind = [] humidity = [] qpf = [] condition = [] for dayF in simpleForecast: tt = self.__toInt(dayF["date"]["epoch"]) tt = rmGetStartOfDay(tt) if tt > maxDayTimestamp: break timestamp.append(self.__toInt(tt)) temperatureMax.append(self.__toFloat(dayF["high"]["celsius"])) temperatureMin.append(self.__toFloat(dayF["low"]["celsius"])) windValue = self.__toFloat(dayF["avewind"]["kph"]) if windValue is not None: wind.append(windValue / 3.6) # convertred from kmetersph to meterps humidity.append(self.__toFloat(dayF["avehumidity"])) qpf.append(self.__toFloat(dayF["qpf_allday"]["mm"])) condition.append(self.conditionConvert(dayF["conditions"])) temperatureMax = zip(timestamp, temperatureMax) temperatureMin = zip(timestamp, temperatureMin) wind = zip(timestamp, wind) humidity = zip(timestamp, humidity) qpf = zip(timestamp, qpf) condition = zip(timestamp, condition) self.addValues(RMParser.dataType.RH, humidity) self.addValues(RMParser.dataType.MAXTEMP, temperatureMax) self.addValues(RMParser.dataType.MINTEMP, temperatureMin) self.addValues(RMParser.dataType.QPF, qpf) self.addValues(RMParser.dataType.WIND, wind) self.addValues(RMParser.dataType.CONDITION, condition) except: log.error("Failed to get simple forecast")
def __getForecastHourly(self, jsonData): try: #forecast hourly tuple = datetime.datetime.fromtimestamp(int( time.time())).timetuple() dayTimestamp = int( datetime.datetime(tuple.tm_year, tuple.tm_mon, tuple.tm_mday).strftime("%s")) maxDayTimestamp = dayTimestamp + globalSettings.parserDataSizeInDays * 86400 forecastArrray = jsonData["hourly_forecast"] timestampF = [] temperatureF = [] depointF = [] windF = [] humidityF = [] qpf = [] conditionF = [] for hourF in forecastArrray: tt = self.__toInt(hourF["FCTTIME"]["epoch"]) if tt > maxDayTimestamp: break timestampF.append(self.__toInt(tt)) temperatureF.append(self.__toFloat(hourF["temp"]["metric"])) depointF.append(self.__toFloat(hourF["dewpoint"]["metric"])) wind = self.__toFloat(hourF["wspd"]["metric"]) if wind is not None: windF.append(wind / 3.6) # convertred from kmetersph to meterps humidityF.append(self.__toFloat(hourF["humidity"])) qpf.append(self.__toFloat(hourF["qpf"]["metric"])) conditionF.append(self.conditionConvert(hourF["condition"])) temperatureF = zip(timestampF, temperatureF) depointF = zip(timestampF, depointF) windF = zip(timestampF, windF) humidityF = zip(timestampF, humidityF) qpf = zip(timestampF, qpf) conditionF = zip(timestampF, conditionF) self.addValues(RMParser.dataType.RH, humidityF) self.addValues(RMParser.dataType.TEMPERATURE, temperatureF) self.addValues(RMParser.dataType.QPF, qpf) self.addValues(RMParser.dataType.DEWPOINT, depointF) self.addValues(RMParser.dataType.WIND, windF) self.addValues(RMParser.dataType.CONDITION, conditionF) except: log.error("Failed to get hourly forecast!") self.lastKnownError = "Error: Failed to get forecast"
def _randRange(self, min, max, step): factor = 100.0 min = int(min * factor) max = int(max * factor) step = int(step * factor) try: if min == max: return min / factor if step == 0: return random.randrange(min, max) / factor return random.randrange(min, max, step) / factor except Exception, e: log.error(e)
def doExecuteCommand(self, command): log.debug(command.name) try: if command.args is None and command.kwargs is None: command.result = command.command() elif command.kwargs is None: command.result = command.command(*command.args) elif command.args is None: command.result = command.command(**command.kwargs) else: command.result = command.command(*command.args, **command.kwargs) except Exception, e: log.error(command.name) log.error(e)
def addRecord(self, zid, timestamp, day, startWaterLevel): if self.database.isOpen(): try: self.database.execute( "INSERT OR REPLACE INTO %s(zid, timestamp, day, startWaterLevel) " "VALUES(?, ?, ?, ?)" % self._tableName, (zid, timestamp, day, startWaterLevel), ) self.database.commit() return True except Exception, e: log.error(e)
def rmNTPFetch(server = "pool.ntp.org", withRequestDrift = False): import struct from socket import socket, AF_INET, SOCK_DGRAM requestPacket = '\x1b' + 47 * '\0' startTime = time.time() try: sock = socket(AF_INET, SOCK_DGRAM) sock.settimeout(5) except Exception, e: log.error("NTPFetch: Can't create socket") return None
def perform(self): s = self.settings # Direct Forecast.io #URL = "https://api.forecast.io/forecast/d1deb05ce0bf3858054236e0171077e5/" + \ # `s.location.latitude` + "," + `s.location.longitude` appKey = self.params.get("appKey", None) if appKey is None: return if self.params["useProxy"]: # RainMachine Forecast.io proxy URL = s.doyDownloadUrl + "/api/forecast_io/forecast/" + appKey + "/" + \ str(s.location.latitude) + "," + str(s.location.longitude) else: URL = "https://api.forecast.io/forecast/" + appKey + "/" + \ str(s.location.latitude) + "," + str(s.location.longitude) URLParams = \ [ ("units", "si"), ("exclude", "currently,minutely,alerts,flags"), ("extend", "hourly") ] try: d = self.openURL(URL, URLParams) if d is None: return forecast = json.loads(d.read()) dayTimestamp = rmCurrentDayTimestamp() maxDayTimestamp = dayTimestamp + globalSettings.parserDataSizeInDays * 86400 hourly = [] daily = [] try: hourly = forecast["hourly"]["data"] except Exception, e: log.error("*** No hourly information found in response!") log.exception(e) try: daily = forecast["daily"]["data"] except Exception, e: log.error("*** No daily information found in response!") log.exception(e)
def __refreshWatchDog(self): timestamp = rmCurrentTimestamp() if self.__lastWatchdogTimestamp is None or (timestamp - self.__lastWatchdogTimestamp) >= self.__watchDogTimeout: if self.__watchDogDescriptor is None: try: self.__watchDogDescriptor = open(self.__watchDogFile, 'w') log.info("Opened system watchdog file %s with timeout %d" % (self.__watchDogFile, self.__watchDogTimeout)) except Exception, e: log.error(e) try: self.__watchDogDescriptor.write(`timestamp`) self.__watchDogDescriptor.flush() log.debug("PING Hardware Watchdog") except Exception, e: log.error(e)
def __buildUrl(self): apiKey = self.params.get("apiKey", None) station = self.params.get("stationName", None) if apiKey is None or not apiKey or not isinstance(apiKey, str): log.error("No API Key provided") self.lastKnownError = "Error: No API Key provided" return None if station is None: log.error("No station name provided") self.lastKnownError = "Error: No station name provided" return None URL = "http://api.wunderground.com/api/" + str(apiKey) + "/conditions/q/pws:" + str(station) + ".json" return URL
def sanitize(self, key, value): interval = self.limits.get(key, None) if interval is None: log.info("%s key not found in our limits definitions" % key) return value min = interval["min"] max = interval["max"] if min is not None and value < min: log.error("%s value %s less than limits minimum of %s" % (key, value, interval["min"])) return None if max is not None and value > max: log.error("%s value %s more than limits maximum of %s" % (key, value, interval["max"])) return None return value
def __diagWifi(self): try: with open("/proc/net/wireless") as f: for line in f: fields = line.strip().split() #log.debug(fields) if not fields[0].endswith(":"): continue log.debug("Wireless interface %s up" % fields[0]) self.__hasWifi = True return except: log.error("Cannot find /proc entry for wireless diag") self.__hasWifi= False
def installParser(self, tempFilePath, fileName): filePath = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "parsers", fileName)) shutil.move(tempFilePath, filePath) try: module = imp.load_source(fileName, filePath) log.info(" * Parser %s successful loaded from file '%s'" % (fileName, filePath)) parser = RMParser.parsers[-1] # Last added parser enabled = parser.isEnabledForLocation(globalSettings.location.timezone, \ globalSettings.location.latitude, \ globalSettings.location.longitude ) parserConfig, isNew = self.parserTable.addParser(fileName, parser.parserName, enabled, parser.params) if not isNew: params = self.parserTable.getParserParams(parserConfig.dbID) if params: parser.params = params RMParser.parsers.pop() #delete old entry pkeys = self.parsers.keys() for pkey in pkeys: if parserConfig.dbID is pkey.dbID: del self.parsers[pkey] self.parsers[parserConfig] = parser parserConfig.userDataTypes = self.userDataTypeTable.addRecords(parser.userDataTypes) self.parserUserDataTypeTable.addRecords(parserConfig.dbID, parserConfig.userDataTypes) log.debug(parserConfig) return True except Exception as e: try: if os.path.exists(filePath): os.remove(filePath) except Exception, e: log.exception(e) log.error(" * Error installing/loading parser %s from file '%s'" % (fileName, filePath)) log.exception(e)
def perform(self): s = self.settings URL = "http://api.met.no/weatherapi/locationforecastlts/1.2/" URLParams = [("lat", s.location.latitude), ("lon", s.location.longitude), ("msl", int(round(s.location.elevation)))] #----------------------------------------------------------------------------------------------- # # Get hourly data. # d = self.openURL(URL, URLParams) if d is None: return tree = e.parse(d) if tree.getroot().tag == 'error': log.error("*** No hourly information found in response!") self.lastKnownError = "Error: No hourly information found" tree.getroot().clear() del tree tree = None else: temp = self.__parseWeatherTag(tree, 'temperature') dewpoint = self.__parseWeatherTag(tree, 'dewpointTemperature') wind = self.__parseWeatherTag(tree, 'windSpeed') humidity = self.__parseWeatherTag(tree, 'humidity') pressure = self.__parseWeatherTag(tree, 'pressure', 'float') qpf = self.__parseWeatherTag(tree, 'precipitation') condition = self.__parseWeatherTag(tree, 'symbol') tree.getroot().clear() del tree tree = None self.addValues(RMParser.dataType.TEMPERATURE, temp) self.addValues(RMParser.dataType.DEWPOINT, dewpoint) self.addValues(RMParser.dataType.WIND, wind) self.addValues(RMParser.dataType.RH, humidity) self.addValues(RMParser.dataType.QPF, qpf) self.addValues(RMParser.dataType.PRESSURE, pressure) self.addValues(RMParser.dataType.CONDITION, condition)
def __refreshWIFI(self): timestamp = rmCurrentTimestamp() lastWIFICheckTimestamp = globalWIFI.wifiInterface.lastWIFICheckTimestamp oldIP = globalWIFI.wifiInterface.ipAddress if lastWIFICheckTimestamp is None or oldIP is None or (timestamp - lastWIFICheckTimestamp) >= self.__wifiRefreshTimeout: try: globalWIFI.detect() if oldIP != globalWIFI.wifiInterface.ipAddress: log.info("Refreshed WIFI Information. (old: %s new ip: %s)" % (`oldIP`, `globalWIFI.wifiInterface.ipAddress`)) if RMOSPlatform().AUTODETECTED == RMOSPlatform.ANDROID: return # Handle None IP if globalWIFI.wifiInterface.ipAddress is None: if self.__lastNoneIpTimestamp is None or (timestamp - self.__lastNoneIpTimestamp) < self.__wifiNoneIpTimeout: # First occurrence of None IP OR we can wait some more time. if self.__lastNoneIpTimestamp is None: self.__lastNoneIpTimestamp = timestamp log.debug("Refreshed WIFI Information - no IP detected. Give it some more time: %d seconds!" % (self.__wifiNoneIpTimeout - (timestamp - self.__lastNoneIpTimestamp), )) return else: globalWIFI.restart() log.warn("Refreshed WIFI Information - WIFI quick reloaded because no IP detected. New IP is %s" % `globalWIFI.wifiInterface.ipAddress`) self.__lastNoneIpTimestamp = None # Reset None IP timestamp. # Check if we never connected to this AP, set back AP mode and restart app if globalWIFI.wifiInterface.mode == "managed" and not globalWIFI.hasConnectedOnce(): if globalWIFI.wifiInterface.hasClientLink: globalWIFI.saveHasConnectedOnce(True) else: log.warning("WIFI Watcher Client IP (%s) configuration failed, restarting in AP mode." % oldIP) globalWIFI.setDefaultAP() globalWIFI.saveHasConnectedOnce(False) globalWIFI.restart() self.__mainManager.touchWakeMessage() except Exception, e: log.error(e)
def newHourlyRestriction(self, dayMinuteStart, minuteDuration, dayList=None): # dayList all 1 - Daily if dayList is None: dayList = [1] * 7 if len(dayList) < 7: log.error("Invalid day list received") return False r = RMUserSettingsHourlyRestriction() r.dayStartMinute = dayMinuteStart r.minuteDuration = minuteDuration r.onWeekDays = [d for d in dayList] # Save the restriction result = self.__hourlyRestrictionsTable.saveRestriction(r) self.hourlyRestrictions[r.uid] = r return r
def run(self): restartApp = False while self.__running: #if RMOSPlatform().AUTODETECTED != RMOSPlatform.SIMULATED: # self.__refreshWatchDog() if not self.__pause and self.__lock.acquire(False): try: if self.__checkFactoryReset(): break if not self.__checkThreads(): restartApp = True break except Exception, e: log.error(e) finally: self.__lock.release()
def perform(self): days = self.params["historicDays"] intervals = days / self.maxAllowedDays + (days % self.maxAllowedDays != 0) lastIntervalStartDay = datetime.date.today() if intervals > 1: days = self.maxAllowedDays log.debug("Days: %d Intervals: %d" % (days, intervals)) for i in range(0, intervals): startDay = lastIntervalStartDay - datetime.timedelta(days=1) #CIMIS real data starts from yesterday endDay = startDay - datetime.timedelta(days=(days + 1)) lastIntervalStartDay = endDay try: log.debug("Running CIMIS for startDay: %s endDay: %s" % (startDay, endDay)) self.__retrieveData(endDay, startDay) # we call with startDay/endDay swapped because CIMIS expects historic intervals except Exception, e: log.error("*** Error running cimis parser") log.exception(e)
def doHandleMessages(self, limit = None): if not limit is None: messageCount = 0 while True: try: command = self.messageQueue.get(True, self.waitTimeout) if command.name == "shutdown": return False else: self.doExecuteCommand(command) if not limit is None: messageCount += 1 if limit <= messageCount: break except Empty, e: break except Exception, e: log.error(e)
def getPercentage(self): usage = 0 try: startUsage = self.get() time.sleep(1) finalUsage = self.get() try: prevActive = startUsage['active'] prevIdle = startUsage['idle'] active = finalUsage['active'] idle = finalUsage['idle'] deltaActive = active - prevActive deltaIdle = idle - prevIdle usage = (float(deltaActive) / (deltaActive + deltaIdle)) * 100 except ZeroDivisionError: pass except Exception, e: log.error("Cannot read cpu stats from %s because %s" % (self.statpath, str(e)))
def getAll(self, programDict, programClass, programZonesClass): if self.database.isOpen(): cursor = self.database.execute("SELECT * FROM %s ORDER BY uid ASC" % self._tableNamePrograms) for row in cursor: program = programClass(row["uid"]) program.name = row["name"] program.type = row["type"] program.param = row["param"] program.active = row["active"] program.start_time = row["start_time"] program.start_date = row["start_date"] program.updated = row["updated"] program.cs_cycles = row["cs_cycles"] program.cs_min = row["cs_min"] program.delay = row["delay"] program.ignoreInternetWeather = row["ignoreInternetWeather"] program.futureField1 = row["futureField1"] program.freq_modified = row["freq_modified"] program.cs_on = row["cs_on"] program.delay_on = row["delay_on"] program.useWaterSense = row["useWaterSense"] programDict[row["uid"]] = program cursor = self.database.execute("SELECT * FROM %s ORDER BY pid ASC" % self._tableNameProgZones) for row in cursor: program = programDict.get(row["pid"]) if program is None: log.error("Missing Program entry for pid %s" % row["pid"]) continue zid = row["zid"] if zid is None: log.error("No zid defined") continue program.zoneLines[zid] = programZonesClass(zid) program.zoneLines[zid].duration = row["duration"] program.zoneLines[zid].active = row["active"] return True return False
def perform(self): timeNow = rmNowDateTime() timeNow = rmNowDateTime().fromordinal(timeNow.toordinal()-1) yyyy = timeNow.year mm = timeNow.month dd = timeNow.day log.debug("Wunderground parser - perform") self.params["_nearbyStationsIDList"] = [] self.params["_airportStationsIDList"] = [] apiKey = self.params.get("apiKey", None) if(apiKey is None or not apiKey or not isinstance(apiKey, str)): #TODO: implement xml WUnderground parser log.error("No API Key provided") self.lastKnownError = "Error: No API Key provided" return self.apiURL = "http://api.wunderground.com/api/" + str(apiKey) + "/geolookup/conditions/hourly10day/history_" + str(yyyy) + str(mm).zfill(2) + str(dd).zfill(2) +"/q/" if (self.params.get("useCustomStation")): stationName = self.params.get("customStationName") if(stationName is None or not stationName or not isinstance(stationName, str)): log.error("Station ID cannot be empty") self.lastKnownError = "Error: Station ID cannot be empty" return log.debug("getting data from specified station") if len(stationName) > 4: self.apiURL += "pws:" + stationName + ".json" #url for pws else: self.apiURL += stationName + ".json" #url for pws else: s = self.settings llat = s.location.latitude llon = s.location.longitude self.apiURL += str(llat) + "," + str(llon) + ".json" # self.params["useCustomStation"] = False log.debug(self.apiURL) d = self.openURL(self.apiURL) jsonContent = d.read() if jsonContent is None: log.error("Failed to get WUnderground JSON contents") self.lastKnownError = "Error: Bad response" return self.jsonResponse = json.loads(jsonContent) #populate nearby stations log.debug("Wunderground parser - get nearby stations") self.getNearbyStations(self.jsonResponse) log.debug("Wunderground parser - get data") self.getStationData(self.jsonResponse) return