コード例 #1
0
    def getStationData(self, jsonData):
        #daily summary for yesterday
        try:
            dailysummary = jsonData["history"]["dailysummary"][0]
            temperature = self.__toFloat(dailysummary["meantempm"])
            mintemp = self.__toFloat(dailysummary["mintempm"])
            maxtemp = self.__toFloat(dailysummary["maxtempm"])
            rh = self.__toFloat(dailysummary["humidity"])
            minrh = self.__toFloat(dailysummary["minhumidity"])
            maxrh = self.__toFloat(dailysummary["maxhumidity"])
            dewpoint = self.__toFloat(dailysummary["meandewptm"])
            wind = self.__toFloat(dailysummary["meanwindspdm"])
            if wind is not None:
                wind = wind / 3.6  # convertred from kmetersph to mps

            maxpressure = self.__toFloat(dailysummary["maxpressurem"])
            minpressure = self.__toFloat(dailysummary["minpressurem"])
            pressure = None
            if maxpressure is not None and minpressure is not None:
                pressure = (maxpressure / 2 +
                            minpressure / 2) / 10  #converted to from mb to kpa

            rain = self.__toFloat(dailysummary["precipm"])

            #time utc
            jutc = jsonData["history"]["utcdate"]
            yyyy = self.__toInt(jutc["year"])
            mm = self.__toInt(jutc["mon"])
            dd = self.__toInt(jutc["mday"])
            hour = self.__toInt(jutc["hour"])
            mins = self.__toInt(jutc["min"])
            log.debug("Observations for date: %d/%d/%d Temp: %s, Rain: %s" %
                      (yyyy, mm, dd, temperature, rain))

            dd = datetime.datetime(yyyy, mm, dd, hour, mins)
            timestamp = calendar.timegm(dd.timetuple())

            timestamp = self.__parseDateTime(timestamp)

            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.QPF, timestamp, rain) # uncomment to report measured rain as previous day QPF
            self.addValue(RMParser.dataType.DEWPOINT, timestamp, dewpoint)
            self.addValue(RMParser.dataType.PRESSURE, timestamp, pressure)

        except:
            log.warning("Failed to get daily summary")
            self.lastKnownError = "Warning: Failed to get daily summary"

        self.__getSimpleForecast()
コード例 #2
0
    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)
コード例 #3
0
    def perform(self):
        timeNow = rmNowDateTime()
        timeNow = rmNowDateTime().fromordinal(timeNow.toordinal()-1)
        yyyy = timeNow.year
        mm = timeNow.month
        dd = timeNow.day

        self.params["_nearbyStationsIDList"] = []
        self.params["_airportStationsIDList"] = []

        apiKey =  self.params.get("apiKey", 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

        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"

        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
        self.getNearbyStations(self.jsonResponse)

        self.getStationData(self.jsonResponse)

        if self.params.get("useCustomStation") and self.params.get("useSolarRadiation"):
            self.__getSolarRadiation()
        elif self.params.get("useSolarRadiation"):
            log.warning("Unable to get solar radiation. You need to specify a pws.")

        return
コード例 #4
0
    def __checkThreads(self):

        timestamp = rmCurrentTimestamp()

        # Work around for a system date change
        resetWatcher = not self.__lastCheckTimestamp is None and \
                       abs(timestamp - self.__lastCheckTimestamp) >= self.__systemTimeChangeThreshold

        everythingOk = True

        if resetWatcher:
            fromTime = rmTimestampToDateAsString(
                self.__lastCheckTimestamp
            ) if self.__lastCheckTimestamp else None
            toTime = rmTimestampToDateAsString(timestamp)

            log.warning(
                "System time has changed (from %s, to %s)! Resetting thread watcher!"
                % (fromTime, toTime))

            self.__lastWatchdogTimestamp = None
            for threadId in self.__data:
                details = self.__getThreadEntry(threadId)
                details[RMThreadWatcher.LastUpdateKey] = None

            if self.__mainManager:
                self.__mainManager.systemDateTimeChanged()
        else:

            for threadId in self.__data:
                details = self.__getThreadEntry(threadId)

                timeoutHint = details[RMThreadWatcher.TimeoutHintKey]
                lastUpdate = details[RMThreadWatcher.LastUpdateKey]

                if timeoutHint is None:
                    log.debug("Thread %d (%s) has no timeout hint!" %
                              (threadId, details[RMThreadWatcher.NameHintKey]))
                elif lastUpdate is None:
                    log.debug("Thread %d (%s) is not started yet!" %
                              (threadId, details[RMThreadWatcher.NameHintKey]))
                elif timeoutHint < (timestamp - lastUpdate):
                    everythingOk = False
                    log.debug("Thread %d (%s) didn't responde since [%s] (timeoutHint=%d, timeout=%d)!" % \
                              (threadId, details[RMThreadWatcher.NameHintKey], rmTimestampToDateAsString(lastUpdate), timeoutHint, (timestamp - lastUpdate)))

        self.__lastCheckTimestamp = timestamp
        return everythingOk
コード例 #5
0
    def getNearbyStations(self, jsonData):

        nearbyStations = jsonData["location"][ "nearby_weather_stations"]
        airportStations = None
        pwsStations = None
        try:
            airportStations = nearbyStations["airport"]
        except:
            log.warning("No airport stations found!")
            self.lastKnownError = "Warning: No airport stations found!"
        try:
            pwsStations = nearbyStations["pws"]
        except:
            log.warning("No pws stations found!")
            self.lastKnownError = "Warning: No pws stations found!"

        if(pwsStations is not None):
            arrStations = pwsStations["station"]
            for st in arrStations:
                self.params["_nearbyStationsIDList"].append(str(st["id"]) + "(" + str(st["distance_km"]) + "km" + "; lat=" + str(round(st["lat"],2)) + ", lon=" + str(round(st["lon"],2)) + ")")

        if(airportStations is not None):
            arrStations = airportStations["station"]
            for st in arrStations:
                distance = None

                if not st["icao"]:
                    continue

                lat = self.__toFloat(st["lat"])
                lon = self.__toFloat(st["lon"])
                llat = self.settings.location.latitude
                llon = self.settings.location.longitude

                if lat is not None and lon is not None:  # some airports don't report lat/lon
                    distance = distanceBetweenGeographicCoordinatesAsKm(lat, lon, llat, llon)

                if distance is not None:
                    distance = self.__toInt(round(distance))
                else:
                    distance = -1

                self.params["_airportStationsIDList"].append(str(st["icao"]) + "(" + str(distance) + "km" + "; lat=" + str(round(lat,2)) + ", lon=" + str(round(lon,2)) + ")" )

        return self.params["_nearbyStationsIDList"]
コード例 #6
0
    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)
コード例 #7
0
    def getNearbyStations(self, jsonData):
        try:
            nearestStation = jsonData["location"].get("id")
        except:
            log.warning("No closest station found!")
            self.lastKnownError = "Warning: No closest station found!"
            return

        closestURL = "https://api.willyweather.com.au/v2/" + self.apiKey + "/search/closest.json"
        closestURLParams = [("id", nearestStation),
                            ("weatherTypes", "general"),
                            ("units", "distance:km")]

        try:
            d = self.openURL(closestURL, closestURLParams)
            if d is None:
                return

            closest = json.loads(d.read())

            if self.parserDebug:
                log.info(closest)

            for i in closest["general"]:
                id = i["id"]
                name = i["name"]
                region = i["region"]
                postcode = i["postcode"]
                distance = i["distance"]

                infoStr = "Station ID = " + str(
                    id) + " (" + name + ", " + region + ", " + str(
                        postcode) + ", " + str(distance) + " kms away)"

                self.params["_nearbyStationsIDList"].append(infoStr)

            if self.parserDebug:
                log.debug(self.params["_nearbyStationsIDList"])

        except Exception, e:
            log.error("*** Error running WillyWeather parser")
            log.exception(e)
コード例 #8
0
    def __checkThreads(self):

        timestamp = rmCurrentTimestamp()

        # Work around for a system date change
        resetWatcher = not self.__lastCheckTimestamp is None and \
                       abs(timestamp - self.__lastCheckTimestamp) >= self.__systemTimeChangeThreshold

        everythingOk = True

        if resetWatcher:
            fromTime = rmTimestampToDateAsString(self.__lastCheckTimestamp) if self.__lastCheckTimestamp else None
            toTime = rmTimestampToDateAsString(timestamp)

            log.warning("System time has changed (from %s, to %s)! Resetting thread watcher!" % (fromTime, toTime))

            self.__lastWatchdogTimestamp = None
            for threadId in self.__data:
                details = self.__getThreadEntry(threadId)
                details[RMThreadWatcher.LastUpdateKey] = None

            if self.__mainManager:
                self.__mainManager.systemDateTimeChanged()
        else:

            for threadId in self.__data:
                details = self.__getThreadEntry(threadId)

                timeoutHint = details[RMThreadWatcher.TimeoutHintKey]
                lastUpdate = details[RMThreadWatcher.LastUpdateKey]

                if timeoutHint is None:
                    log.debug("Thread %d (%s) has no timeout hint!" % (threadId, details[RMThreadWatcher.NameHintKey]))
                elif lastUpdate is None:
                    log.debug("Thread %d (%s) is not started yet!" % (threadId, details[RMThreadWatcher.NameHintKey]))
                elif timeoutHint < (timestamp - lastUpdate):
                    everythingOk = False
                    log.debug("Thread %d (%s) didn't responde since [%s] (timeoutHint=%d, timeout=%d)!" % \
                              (threadId, details[RMThreadWatcher.NameHintKey], rmTimestampToDateAsString(lastUpdate), timeoutHint, (timestamp - lastUpdate)))

        self.__lastCheckTimestamp = timestamp
        return everythingOk
コード例 #9
0
    def setParserParams(self, parserID, params):
        parserConfig = self.findParserConfig(parserID)
        if parserConfig is None:
            return False

        parser = self.parsers[parserConfig]

        newParams = copy.deepcopy(parser.params)
        hasChanges = False

        try:
            for key, oldValue in parser.params.iteritems():
                newValue = params.get(key, None)
                if newValue is not None:
                    if oldValue is None or type(oldValue) == type(newValue):
                        newParams[key] = newValue
                        hasChanges = True
                    else:
                        log.warning("Types do not match: oldType=%s, newType=%s" % (type(oldValue), type(newValue)))
        except Exception, e:
            log.exception(e)
            return False
コード例 #10
0
    def getNearbyStations(self, jsonData):
        try:
            nearbyStations = jsonData["location"]["nearby_weather_stations"]
        except:
            log.warning("No nearby stations found!")
            self.lastKnownError = "Warning: No nearby stations found!"
            return

        airportStations = None
        pwsStations = None

        try:
            airportStations = nearbyStations["airport"]
        except:
            log.warning("No airport stations found!")
            self.lastKnownError = "Warning: No airport stations found!"

        try:
            pwsStations = nearbyStations["pws"]
        except:
            log.warning("No pws stations found!")
            self.lastKnownError = "Warning: No pws stations found!"

        if pwsStations is not None:
            arrStations = pwsStations["station"]
            for st in arrStations:
                self.params["_nearbyStationsIDList"].append(
                    str(st["id"]) + "(" + str(st["distance_km"]) + "km" +
                    "; lat=" + str(round(st["lat"], 2)) + ", lon=" +
                    str(round(st["lon"], 2)) + ")")

        if airportStations is not None:
            arrStations = airportStations["station"]
            for st in arrStations:
                distance = None

                if not st["icao"]:
                    continue

                lat = self.__toFloat(st["lat"])
                lon = self.__toFloat(st["lon"])
                llat = self.settings.location.latitude
                llon = self.settings.location.longitude

                if lat is not None and lon is not None:  # some airports don't report lat/lon
                    distance = distanceBetweenGeographicCoordinatesAsKm(
                        lat, lon, llat, llon)

                if distance is not None:
                    distance = self.__toInt(round(distance))
                    infoStr = "(" + str(distance) + "km" + "; lat=" + str(
                        round(lat, 2)) + ", lon=" + str(round(lon, 2)) + ")"
                else:
                    distance = -1
                    infoStr = "(unknown distance)"

                self.params["_airportStationsIDList"].append(
                    str(st["icao"]) + infoStr)
コード例 #11
0
    def setParserParams(self, parserID, params):
        parserConfig = self.findParserConfig(parserID)
        if parserConfig is None:
            return False

        parser = self.parsers[parserConfig]

        newParams = copy.deepcopy(parser.params)
        hasChanges = False

        try:
            for key, oldValue in parser.params.iteritems():
                newValue = params.get(key, None)
                if newValue is not None:
                    if oldValue is None or type(oldValue) == type(newValue):
                        newParams[key] = newValue
                        hasChanges = True
                    else:
                        log.warning(
                            "Types do not match: oldType=%s, newType=%s" %
                            (type(oldValue), type(newValue)))
        except Exception, e:
            log.exception(e)
            return False
コード例 #12
0
    def getNearbyStations(self, jsonData):

        airportStations = {}
        pwsStations = {}
        llat = self.settings.location.latitude
        llon = self.settings.location.longitude

        try:
            for key in jsonData['response']:
                if len(key['id']) == 4:
                    airportStations.update({str(key['id']): key['loc']})

            log.debug("airportStations: {}".format(airportStations))
        except:
            log.warning("No airport stations found!")
            self.lastKnownError = "Warning: No airport stations found!"

        try:
            for key in jsonData['response']:
                if ("MID" in key['id']) or ("PWS" in key['id']):
                    pwsStations.update({str(key['id']): key['loc']})

            log.debug("pwsStations: {}".format(pwsStations))

        except:
            log.warning("No pws stations found!")
            self.lastKnownError = "Warning: No pws stations found!"

        if pwsStations:
            # arrStations = pwsStations["station"]
            for key in pwsStations:
                # print key
                # print pwsStations.get(key)['lat']
                distance = None

                lat = pwsStations.get(key)['lat']
                lon = pwsStations.get(key)['long']
                log.debug("lat: {}, lon: {}, llat: {}, llon: {}".format(
                    lat, lon, llat, llon))

                if lat is not None and lon is not None:  # some airports don't report lat/lon
                    distance = distanceBetweenGeographicCoordinatesAsKm(
                        lat, lon, llat, llon)
                    print(distance)

                if distance is not None:
                    distance = int(round(distance))
                    infoStr = "(" + str(distance) + "km" + "; lat=" + str(
                        round(lat, 2)) + ", lon=" + str(round(lon, 2)) + ")"
                else:
                    distance = -1
                    infoStr = "(unknown distance)"

                self.params["_nearbyStationsIDList"].append(key + infoStr)

        log.debug(self.params["_nearbyStationsIDList"])

        if airportStations:

            for key in airportStations:
                distance = None

                lat = airportStations.get(key)['lat']
                lon = airportStations.get(key)['long']
                log.debug("lat: {}, lon: {}, llat: {}, llon: {}".format(
                    lat, lon, llat, llon))

                if lat is not None and lon is not None:  # some airports don't report lat/lon
                    distance = distanceBetweenGeographicCoordinatesAsKm(
                        lat, lon, llat, llon)
                    print(distance)

                if distance is not None:
                    distance = int(round(distance))
                    infoStr = "(" + str(distance) + "km" + "; lat=" + str(
                        round(lat, 2)) + ", lon=" + str(round(lon, 2)) + ")"
                else:
                    distance = -1
                    infoStr = "(unknown distance)"

                self.params["_airportStationsIDList"].append(key + infoStr)

        log.debug(self.params["_airportStationsIDList"])
コード例 #13
0
    def run(self, parserId = None, forceRunParser = False, forceRunMixer = False):
        currentTimestamp = rmCurrentTimestamp()
        forceRunParser = True

        if not forceRunParser and self.__lastRunningTimestamp is not None and (currentTimestamp - self.__lastRunningTimestamp) < self.__runningInterval:
            # We want to run the parser only each N minutes. This condition is not met, try later.
            log.debug("Parser %r not run lastRunning timestamp %s current %s" % (parserId, self.__lastRunningTimestamp, currentTimestamp))
            return None, None

        self.__lastRunningTimestamp = currentTimestamp

        newValuesAvailable = False
        newForecast = RMForecastInfo(None, currentTimestamp)

        log.debug("*** BEGIN Running parsers: %d (%s)" % (newForecast.timestamp, rmTimestampToDateAsString(newForecast.timestamp)))
        for parserConfig in self.parsers:
            if parserId is not None and parserId != parserConfig.dbID:
                continue

            log.debug("   * Parser: %s -> %s" % (parserConfig, parserConfig.runtimeLastForecastInfo))
            if parserConfig.enabled:
                if parserConfig.failCounter >= self.__maxFails:
                    if forceRunParser or parserConfig.lastFailTimestamp is None or (abs(newForecast.timestamp - parserConfig.lastFailTimestamp) >= self.__delayAfterMaxFails):
                        parserConfig.failCounter = 0
                        parserConfig.lastFailTimestamp = None
                    else:
                        if parserConfig.failCounter == self.__maxFails:
                            log.warning("     * Parser: %s - ignored because of lack of data (failCounter=%s, lastFail=%s)!" %
                                        (parserConfig, `parserConfig.failCounter`, rmTimestampToDateAsString(parserConfig.lastFailTimestamp)))
                            parserConfig.failCounter += 1 # Increment this to get rid of the above message.
                        continue
                elif parserConfig.failCounter > 0:
                    retryDelay = min(self.__minDelayBetweenFails + (parserConfig.failCounter - 1) * self.__stepDelayBetweenFails, self.__maxDelayBetweenFails)
                    nextRetryTimestamp = parserConfig.lastFailTimestamp + retryDelay
                    if newForecast.timestamp < nextRetryTimestamp:
                        log.debug("     * Ignored because retry delay %d (sec) was not reached" % retryDelay)
                        continue
                    log.debug("     * Parser retry after previous fail")

                parser = self.parsers[parserConfig]

                lastUpdate = None
                if parserConfig.runtimeLastForecastInfo:
                    # Check if parser hasn't run with an invalid future date
                    if parserConfig.runtimeLastForecastInfo.timestamp <= currentTimestamp:
                        lastUpdate = parserConfig.runtimeLastForecastInfo.timestamp

                # Save the newest parser run
                if lastUpdate is not None and lastUpdate > self.__lastUpdateTimestamp:
                    self.__lastUpdateTimestamp = lastUpdate

                if not forceRunParser and not self.forceParsersRun and (lastUpdate != None and (newForecast.timestamp - lastUpdate) < parser.parserInterval):
                    log.debug("     * Ignored because interval %d not expired for timestamp %d lastUpdate: %d" % (parser.parserInterval, newForecast.timestamp, lastUpdate))
                    continue

                log.debug("  * Running parser %s with interval %d" % (parser.parserName, parser.parserInterval))
                parser.settings = globalSettings.getSettings()
                parser.runtime[RMParser.RuntimeDayTimestamp] = rmCurrentDayTimestamp()

                try:
                    parser.lastKnownError = ''
                    parser.isRunning = True
                    parser.perform()
                    parser.isRunning = False
                except Exception, e:
                    log.error("  * Cannot execute parser %s" % parser.parserName)
                    log.exception(e)
                    parser.isRunning = False
                    if len(parser.lastKnownError) == 0:
                        parser.lastKnownError = 'Error: Failed to run'

                if not parser.hasValues():
                    parserConfig.failCounter += 1
                    parserConfig.lastFailTimestamp = newForecast.timestamp
                    if len(parser.lastKnownError) == 0:
                        parser.lastKnownError = 'Error: parser returned no values'
                    parser.isRunning = False
                    if parserConfig.failCounter == 1:
                        log.warn ("  * Parser %s returned no values" % parser.parserName)
                    continue


                parserConfig.failCounter = 0
                parserConfig.lastFailTimestamp = None

                if newForecast.id == None:
                    self.forecastTable.addRecordEx(newForecast)
                parserConfig.runtimeLastForecastInfo = newForecast

                if not globalSettings.vibration:
                    self.parserDataTable.removeEntriesWithParserIdAndTimestamp(parserConfig.dbID, parser.getValues())

                self.parserDataTable.addRecords(newForecast.id, parserConfig.dbID, parser.getValues())
                parser.clearValues()

                newValuesAvailable = True
コード例 #14
0
    def perform(self):
        timeNow = rmNowDateTime()
        timeYesterday = rmNowDateTime().fromordinal(timeNow.toordinal() - 1)
        yyyyy = timeYesterday.year
        mmy = timeYesterday.month
        ddy = timeYesterday.day
        yyyy = timeNow.year
        mm = timeNow.month
        dd = timeNow.day

        self.params["_nearbyStationsIDList"] = []
        self.params["_airportStationsIDList"] = []
        self.lastKnownError = ""
        apiKey = self.params.get("apiKey", 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

        self.apiURL = "http://api.wunderground.com/api/" + str(
            apiKey) + "/geolookup/conditions/forecast10day/yesterday/q/"

        success = False
        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")
            #try to split

            self.arrStationNames = stationName.split(",")

            for stationName in self.arrStationNames:
                if len(stationName) > 4:
                    self.csapiURL = self.apiURL + "pws:" + stationName + ".json"  # url for pws
                else:
                    self.csapiURL = self.apiURL + stationName + ".json"  # url for airport stations
                log.debug(self.apiURL)

                d = self.openURL(self.csapiURL)
                jsonContent = d.read()
                if jsonContent is None:
                    self.lastKnownError = "Error: Bad response"
                    continue
                self.jsonResponse = json.loads(jsonContent)
                err = self.jsonResponse.get("response").get("error")
                if not err:
                    success = True
                    break
                self.lastKnownError = "Error: Failed to get custom station"
                log.error(self.lastKnownError)
        else:
            s = self.settings
            llat = s.location.latitude
            llon = s.location.longitude
            self.apiURL += str(llat) + "," + str(llon) + ".json"
            log.debug(self.apiURL)
            d = self.openURL(self.apiURL)
            jsonContent = d.read()
            if jsonContent is None:
                self.lastKnownError = "Error: Bad response"
                return
            self.jsonResponse = json.loads(jsonContent)
            err = self.jsonResponse.get("response").get("error")
            if not err:
                success = True

        if not success:
            log.error(self.lastKnownError)
            return

        #populate nearby stations
        self.getNearbyStations(self.jsonResponse)

        self.getStationData(self.jsonResponse)

        if self.params.get("useCustomStation") and self.params.get(
                "useSolarRadiation"):
            self.__getSolarRadiation()
        elif self.params.get("useSolarRadiation"):
            log.warning(
                "Unable to get solar radiation. You need to specify a pws.")

        return
コード例 #15
0
    def getStationData(self, jsonData):

        #daily summary
        try:
            dailysummary = jsonData["history"]["dailysummary"][0]
            temperature = self.__toFloat(dailysummary["meantempm"])
            mintemp = self.__toFloat(dailysummary["mintempm"])
            maxtemp = self.__toFloat(dailysummary["maxtempm"])
            rh = self.__toFloat(dailysummary["humidity"])
            minrh = self.__toFloat(dailysummary["minhumidity"])
            maxrh = self.__toFloat(dailysummary["maxhumidity"])
            dewpoint = self.__toFloat(dailysummary["meandewptm"])
            wind = self.__toFloat(dailysummary["meanwindspdm"]) / 3.6 # convertred from kmetersph to meterps
            pressure = self.__toFloat(dailysummary["maxpressurem"])/2 + self.__toFloat(dailysummary["minpressurem"])/2 # to be compared
            rain = self.__toFloat(dailysummary["precipm"])
            solarradiation = self.__toFloat(jsonData["current_observation"]["solarradiation"])  #to be compared

            condition = self.conditionConvert(jsonData["current_observation"]["weather"])
            log.debug("Wunderground parser - got daily data")

            #time utc
            jutc = jsonData["history"]["utcdate"]
            yyyy = self.__toInt(jutc["year"])
            mm = self.__toInt(jutc["mon"])
            dd = self.__toInt(jutc["mday"])
            hour = self.__toInt(jutc["hour"])
            mins = self.__toInt(jutc["min"])
            log.debug("Wunderground parser - got time")

            dd = datetime.datetime(yyyy, mm, dd, hour, mins)
            timestamp = calendar.timegm( dd.timetuple())

            timestamp = self.__parseDateTime(timestamp)

            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.SOLARRADIATION, timestamp, solarradiation)
            self.addValue(RMParser.dataType.CONDITION, timestamp, condition)

        except:
            log.warning("Failed to get daily summary")
            self.lastKnownError = "Warning: Failed to get daily summary"

        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 = []
            log.debug("Wunderground parser - getting forecast")
            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"]))
                windF.append(self.__toFloat(hourF["wspd"]["metric"])/ 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)

            log.debug("Wunderground parser - got forecast")
        except:
            log.error("Failed to get forecast!")
            self.lastKnownError = "Error: Failed to get forecast"

        return
コード例 #16
0
    def perform(self):
        timeNow = rmNowDateTime()
        timeYesterday = rmNowDateTime().fromordinal(timeNow.toordinal()-1)
        yyyyy = timeYesterday.year
        mmy = timeYesterday.month
        ddy = timeYesterday.day
        yyyy = timeNow.year
        mm = timeNow.month
        dd = timeNow.day


        self.params["_nearbyStationsIDList"] = []
        self.params["_airportStationsIDList"] = []

        apiKey =  self.params.get("apiKey", 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

        self.apiURL = "http://api.wunderground.com/api/" + str(apiKey) + "/geolookup/conditions/forecast10day/yesterday/q/"

        # / history_
        # " \
        #     + str(yyyyy) + str(mmy).zfill(2) + str(ddy).zfill(2)\
        #     + 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"

        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
        self.getNearbyStations(self.jsonResponse)

        self.getStationData(self.jsonResponse)

        if self.params.get("useCustomStation") and self.params.get("useSolarRadiation"):
            self.__getSolarRadiation()
        elif self.params.get("useSolarRadiation"):
            log.warning("Unable to get solar radiation. You need to specify a pws.")

        return
コード例 #17
0
    def getStationData(self, jsonData):
        # daily summary for yesterday
        try:
            if self.params.get("useCustomStation"):
                dailysummary = jsonData["response"]["periods"][0]["summary"]
            else:
                dailysummary = jsonData["response"][0]["periods"][0]["summary"]

            log.debug("Daily Summary: {}".format(dailysummary))
            temperature = self.__toFloat(dailysummary["temp"]["avgC"])

            mintemp = self.__toFloat(dailysummary["temp"]["minC"])
            maxtemp = self.__toFloat(dailysummary["temp"]["maxC"])
            rh = self.__toFloat(dailysummary["rh"]["avg"])
            minrh = self.__toFloat(dailysummary["rh"]["min"])
            maxrh = self.__toFloat(dailysummary["rh"]["max"])
            dewpoint = self.__toFloat(dailysummary["dewpt"]["avgC"])
            wind = self.__toFloat(dailysummary["wind"]["avgKPH"])
            if wind is not None:
                wind = wind / 3.6  # convertred from kmetersph to mps

            maxpressure = self.__toFloat(dailysummary["pressure"]["maxMB"])
            minpressure = self.__toFloat(dailysummary["pressure"]["minMB"])
            pressure = None
            if maxpressure is not None and minpressure is not None:
                pressure = (maxpressure / 2 + minpressure /
                            2) / 10  # converted to from mb to kpa
            rain = self.__toFloat(dailysummary["precip"]["totalMM"])

            # time utc
            timestamp = dailysummary["range"]["maxTimestamp"]
            print(timestamp)
            timestampiso = dailysummary["range"]["maxDateTimeISO"]
            print("Observations for date: %s Temp: %s, Rain: %s" %
                  (timestampiso[0:16].replace("T", " "), temperature, rain))

            timestamp = self.__parseDateTime(timestamp)

            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.QPF, timestamp, rain) # uncomment to report measured rain as previous day QPF
            self.addValue(RMParser.dataType.DEWPOINT, timestamp, dewpoint)
            self.addValue(RMParser.dataType.PRESSURE, timestamp, pressure)

            if self.params.get("useSolarRadiation"):
                solarradiation = self.__toFloat(
                    dailysummary["solrad"]["avgWM2"])
                # needs to be converted from watt/sqm*h to Joule/sqm

                if solarradiation is not None:
                    solarradiation *= 0.0864

                self.addValue(RMParser.dataType.SOLARRADIATION, timestamp,
                              solarradiation)

            log.debug(
                "temp {}, minT {}, maxT {}, rh {}, minrh {}, maxrh {}, dewpoint {}, wind (MPS) {}, maxpress {}, "
                "minpress {}, avgpress {}, rain {}, solrad {}".format(
                    temperature, mintemp, maxtemp, rh, minrh, maxrh, dewpoint,
                    wind, maxpressure, minpressure, pressure, rain,
                    solarradiation))

        except:
            log.warning("Failed to get daily summary")
            self.lastKnownError = "Warning: Failed to get daily summary"
コード例 #18
0
    def getStationData(self, jsonData):
        #daily summary for yesterday
        try:
            dailysummary = jsonData["history"]["dailysummary"][0]
            temperature = self.__toFloat(dailysummary["meantempm"])
            mintemp = self.__toFloat(dailysummary["mintempm"])
            maxtemp = self.__toFloat(dailysummary["maxtempm"])
            rh = self.__toFloat(dailysummary["humidity"])
            minrh = self.__toFloat(dailysummary["minhumidity"])
            maxrh = self.__toFloat(dailysummary["maxhumidity"])
            dewpoint = self.__toFloat(dailysummary["meandewptm"])
            wind = self.__toFloat(dailysummary["meanwindspdm"])
            if wind is not  None:
                wind = wind / 3.6 # convertred from kmetersph to mps

            maxpressure = self.__toFloat(dailysummary["maxpressurem"])
            minpressure = self.__toFloat(dailysummary["minpressurem"])
            pressure = None
            if maxpressure is not None and minpressure is not None:
                pressure = (maxpressure/2 + minpressure/2) / 10 #converted to from mb to kpa

            rain = self.__toFloat(dailysummary["precipm"])

            #time utc
            jutc = jsonData["history"]["utcdate"]
            yyyy = self.__toInt(jutc["year"])
            mm = self.__toInt(jutc["mon"])
            dd = self.__toInt(jutc["mday"])
            hour = self.__toInt(jutc["hour"])
            mins = self.__toInt(jutc["min"])
            log.debug("Observations for date: %d/%d/%d Temp: %s, Rain: %s" % (yyyy, mm, dd, temperature, rain))

            dd = datetime.datetime(yyyy, mm, dd, hour, mins)
            timestamp = calendar.timegm( dd.timetuple())

            timestamp = self.__parseDateTime(timestamp)

            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)

        except:
            log.warning("Failed to get daily summary")
            self.lastKnownError = "Warning: Failed to get daily summary"

        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 forecast!")
            self.lastKnownError = "Error: Failed to get forecast"
コード例 #19
0
    def perform(self):
        timeNow = rmNowDateTime()
        timeYesterday = rmNowDateTime().fromordinal(timeNow.toordinal() - 1)
        yyyyy = timeYesterday.year
        mmy = timeYesterday.month
        ddy = timeYesterday.day
        yyyy = timeNow.year
        mm = timeNow.month
        dd = timeNow.day

        limit = 10

        self.params["_nearbyStationsIDList"] = []
        self.params["_airportStationsIDList"] = []
        log.debug("Params: {}".format(self.params))
        clientID = self.params.get("clientID", None)
        if clientID is None or not clientID or not isinstance(clientID, str):
            log.error("No Client ID provided")
            self.lastKnownError = "Error: No Client ID provided"
            return

        secret = self.params.get("Secret", None)
        if secret is None or not secret or not isinstance(secret, str):
            log.error("No Secret provided")
            self.lastKnownError = "Error: No Secret provided"
            return

        if self.params.get("useCustomStation"):
            stationName = self.params.get("customStationName")
            if stationName is None or not stationName or not isinstance(
                    stationName, str):
                stationName = ":auto"
                log.info(
                    "Station name not valid, using automatic location identifier"
                )
            limit = 10
        else:
            stationName = ":auto"
            log.info("Station not set, using automatic location identifier")
            limit = 10

        stationName = stationName.replace(" ", "")
        log.debug("stationName: {}".format(stationName))

        apiURL = \
            "http://api.aerisapi.com/observations/summary/" + stationName + "?&format=json&radius=75mi&filter=allstations&limit=" + \
            str(limit) + "&client_id=" \
            + str(clientID) + "&client_secret=" + str(secret)
        log.debug("apiURL is: {}".format(apiURL))

        self.jsonResponse = self.apiCall(apiURL)
        log.debug(self.jsonResponse)

        if self.jsonResponse['success']:
            # populate nearby stations

            if self.params.get("useCustomStation") and self.params.get(
                    "customStationName"):

                pass
            else:
                log.debug("Getting nearby stations")
                self.getNearbyStations(self.jsonResponse)
                return

            self.getStationData(self.jsonResponse)

        if self.params.get("useCustomStation") and self.params.get(
                "useSolarRadiation"):
            pass
        elif self.params.get("useSolarRadiation"):
            log.warning(
                "Unable to get solar radiation. You need to specify a pws.")

        log.debug("self.parserForecast={}".format(self.parserForecast))
        if self.parserForecast:
            apiURL = \
                "http://api.aerisapi.com/forecasts/" + stationName + "?&format=json&filter=mdnt2mdnt&limit=7" + \
                "&client_id=" + str(clientID) + "&client_secret=" + str(secret)
            log.debug("Getting forecast from {}".format(apiURL))
            self.jsonResponse = self.apiCall(apiURL)

            self.__getSimpleForecast()

        return