def __parseXMLData(self, tree):
        dateFormat = "%Y-%m-%dT%H:%M:%SZ"
        data = {}

        for w in tree.getroot().find('product'):
            for wd in w.find('location'):
                tag = wd.tag

                from_time = w.get('from')
                to_time = w.get('to')

                intervalStartTimestamp = rmTimestampFromDateAsString(
                    from_time,
                    dateFormat) + 1  # 1 second more than hour boundary
                intervalEndTimestamp = rmTimestampFromDateAsString(
                    to_time,
                    dateFormat) - 1  # 1 second less than hour boundary

                day, startTimeStr = from_time.split("T")
                endTimeStr = to_time.split("T")[1]

                if tag not in data:
                    data[tag] = {}

                if day not in data[tag]:
                    data[tag][day] = []

                startHourStr = startTimeStr.split(":")[0]
                endHourStr = endTimeStr.split(":")[0]

                try:
                    if (tag == 'windDirection'):
                        val = toFloat(wd.get('deg'))
                    elif (tag == 'windSpeed'):
                        val = toFloat(wd.get('mps'))
                    elif (tag == 'symbol'):
                        condition = toInt(wd.get('number'))
                        val = self.conditionConvert(condition)
                    elif (tag == 'cloudiness' or tag == 'fog'
                          or tag == 'lowClouds' or tag == 'mediumClouds'
                          or tag == 'highClouds'):
                        val = toFloat(wd.get('percent'))
                    else:
                        val = toFloat(wd.get('value'))

                    # hPa -> kPa
                    if (tag == 'pressure'):
                        val = val / 10

                except Exception, e:
                    val = None
                    log.debug(e)

                data[tag][day].append({
                    "startHour": startHourStr,
                    "endHour": endHourStr,
                    "start": intervalStartTimestamp,
                    "end": intervalEndTimestamp,
                    "value": val
                })
    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)
Example #3
0
 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) + "&centerLat=" + str(llat) + "&centerLon=" \
                   + 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 __manglePassword(self, password):
        if not password or len(password) != 96:
            return None

        tokenSize = len(password) / 16
        tokens = []

        tokens.append("3" + password[(0 * tokenSize):(1 * tokenSize)])
        tokens.append("b" + password[(15 * tokenSize):(16 * tokenSize)])

        mangle = ""

        count = 15
        while count >= 0:
            index = random.randint(0, count)
            mangle += tokens[index]

            del tokens[index]

            count -= 1

        log.debug("Password: %s" % password)
        log.debug("Mangle: %s" % mangle)

        return mangle
    def __manglePassword(self, password):
        if not password or len(password) != 96:
            return None

        tokenSize = len(password) / 16
        tokens = []

        tokens.append("3" + password[(0 * tokenSize):(1 * tokenSize)])
        tokens.append("b" + password[(15 * tokenSize):(16 * tokenSize)])

        mangle = ""

        count = 15
        while count >= 0:
            index = random.randint(0, count)
            mangle += tokens[index]

            del tokens[index]

            count -= 1

        log.debug("Password: %s" % password)
        log.debug("Mangle: %s" % mangle)

        return mangle
 def __fahrenheitToCelsius(self, temp):
     try:
         temp = float(temp)
         return (temp - 32) * 5.0/9.0
     except:
         log.debug("Can't convert fahrenheit to celsius !")
         return None
 def __knotsToMS(self, knots):
     try:
         knots = float(knots)
         return knots * 0.514444
     except:
         log.debug("Can't convert knots to m/s !")
         return None
 def __inchesToMM(self, inches):
     try:
         inches = float(inches)
         return inches * 25.4
     except:
         log.debug("Can't convert inches to mm !")
         return None
Example #9
0
    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 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
Example #11
0
def rmGetSunriseTimestampForDayTimestamp(ts, lat, lon, elevation):
    if lat is None or lon is None:
        log.debug("Latitude or longitude is not set. Returning same timestamp")
        return ts
    Jtr, w0 = computeSuntransitAndDayLenghtForDayTs(ts, lat, -lon, elevation)
    Jrise = Jtr-w0/360
    tsJrise = julianDayToUTC(Jrise)
    return  tsJrise
Example #12
0
 def executeCommand(self, command):
     log.debug("Schedule execute command: %s" % `command.name`)
     log.debug(command)
     self.messageQueue.put(command)
     if command.event:
         command.wait()
         log.debug(command)
         log.debug("Command finished %s" % `command.name`)
         return command.result
Example #13
0
    def __getForecastData(self, forecast):
        dayTimestamp = rmCurrentDayTimestamp()

        if "list" not in forecast:
            self.lastKnownError = "Error: Missing data cannot parse response JSON."
            log.info(self.lastKnownError)
            return

        for entry in forecast["list"]:
            timestamp = entry["dt"]

            if self.parserDebug:
                log.info("Date: %s" % rmTimestampToDateAsString(timestamp))

            maxtemp = None
            mintemp = None
            temp = None
            humidity = None
            pressure = None

            if "main" in entry:
                maxtemp = entry["main"].get("temp_max")
                mintemp = entry["main"].get("temp_min")
                temp = entry["main"].get("temp")
                humidity = entry["main"].get("humidity")
                pressure = entry["main"].get("grnd_level")
                try:
                    pressure = pressure / 10  # hPa to kPa
                except:
                    pressure = None

            self.addValue(RMParser.dataType.MINTEMP, timestamp, mintemp)
            self.addValue(RMParser.dataType.MAXTEMP, timestamp, maxtemp)
            self.addValue(RMParser.dataType.TEMPERATURE, timestamp, temp)
            self.addValue(RMParser.dataType.RH, timestamp, humidity)
            self.addValue(RMParser.dataType.PRESSURE, timestamp, pressure)

            qpf = None
            if "rain" in entry:
                qpf = entry["rain"].get("3h")

            self.addValue(RMParser.dataType.QPF, timestamp, qpf)

            wind = None
            if "wind" in entry:
                wind = entry["wind"].get("speed")

            self.addValue(RMParser.dataType.WIND, timestamp, wind)

            icon = None
            if entry["weather"][0]:
                icon = self.conditionConvert(entry["weather"][0].get("id"))

            self.addValue(RMParser.dataType.CONDITION, timestamp, icon)

        if self.parserDebug:
            log.debug(self.result)
    def isInMonthRestriction(self, timestamp):
        d = datetime.fromtimestamp(timestamp)
        currentMonth = d.month - 1

        if self.globalRestrictions.noWaterInMonths[currentMonth] == 1:
            log.debug("Restricted for %d month" % (currentMonth))
            return True

        return False
    def isInDayRestriction(self, timestamp):
        d = datetime.fromtimestamp(timestamp)
        currentWeekDay = d.weekday()

        if self.globalRestrictions.noWaterInWeekDays[currentWeekDay] == 1:
            log.debug("Restricted for %d weekday" % currentWeekDay)
            return True

        return False
    def isInMonthRestriction(self, timestamp):
        d = datetime.fromtimestamp(timestamp)
        currentMonth = d.month - 1

        if self.globalRestrictions.noWaterInMonths[currentMonth] == 1:
            log.debug("Restricted for %d month" % (currentMonth))
            return True

        return False
    def isInDayRestriction(self, timestamp):
        d = datetime.fromtimestamp(timestamp)
        currentWeekDay = d.weekday()

        if self.globalRestrictions.noWaterInWeekDays[currentWeekDay] == 1:
            log.debug("Restricted for %d weekday" % currentWeekDay)
            return True

        return False
    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()
    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)
Example #20
0
    def perform(self):
        # downloading data from a URL convenience function since other python libraries can be used
        URL = "http://lab.zanek.net/mesonet/api/currentobservations"
        stationID = "ALTU"
        data = self.openURL(URL)


        if data is None:
            return

        stationsData = json.loads(data.read())

        if stationsData is None:
            self.lastKnownError = "Error: Invalid response from server"
            return

        timestamp = rmCurrentTimestamp()

        for station in stationsData:
            if station['STID'] == stationID:
                try:
                    rain = self.__toFloat(station.get("RAIN"))
                except:
                    rain = None

                try:
                    tmin = self.__toFloat(station.get("TMIN"))
                    tmax = self.__toFloat(station.get("TMAX"))
                except:
                    self.lastKnownError = "Error: No minimum or maximum temperature can be retrieved"
                    return

                try:
                    pressure = self.__toFloat(station.get("PRES"))
                except:
                    pressure = None

                try:
                    wind = self.__toFloat(station.get("WSPD"))
                except:
                    wind = None

                try:
                    dew = self.__toFloat(station.get("TDEW"))
                except:
                    dew = None

                self.addValue(RMParser.dataType.MINTEMP, timestamp, tmin)
                self.addValue(RMParser.dataType.MAXTEMP, timestamp, tmax)
                self.addValue(RMParser.dataType.RAIN, timestamp, rain)
                self.addValue(RMParser.dataType.PRESSURE, timestamp, pressure)
                self.addValue(RMParser.dataType.WIND, timestamp, wind)
                self.addValue(RMParser.dataType.DEWPOINT, timestamp, dew)

                if self.parserDebug:
                    log.debug(self.result)
    def __toUtc(self, jutc, t, r, w):

        # time utc
        yyyy = self.__toInt(jutc[:4])
        mm = self.__toInt(jutc[4:6])
        dd = self.__toInt(jutc[6:8])
        hour = self.__toInt(jutc[8:10])
        mins = self.__toInt(jutc[10:12])
        log.debug(
            "Observations for date: {:d}/{:d}/{:d}, time: {:d}{:d}z Temp: {}, Rain: {}, Wind: {}"
            .format(yyyy, mm, dd, hour, mins, t, r, w))
    def __parseWeatherTag(self, tree, tag, typeConvert = None):
        values = []
        startTimes = []
        lastEndTime = None

        for w in tree.getroot().find('product'):
            for wd in w.find('location'):
                if wd.tag == tag:

                    from_time = w.get('from')
                    to_time = w.get('to')
                    ft = datetime.datetime.strptime(from_time, "%Y-%m-%dT%H:%M:%SZ")
                    tt = datetime.datetime.strptime(to_time, "%Y-%m-%dT%H:%M:%SZ")
                    td = tt - ft

                    shouldSkip = False
                    # skip 6h intervals as they aren't disjoint between them (eg: 0-6, 3-9)
                    # only if we had a previous report with same end time
                    if lastEndTime is not None and lastEndTime == tt and td.seconds == 6 * 3600:
                        shouldSkip = True


                    log.debug("Tag %s [%s - %s] Skip: %s" % (tag, from_time, to_time, shouldSkip))

                    if shouldSkip:
                        continue

                    lastEndTime = tt
                    startTimes.append(self.__parseDateTime(ft))
                    try:
                        if (tag == 'windDirection'):
                            val = wd.get('deg')
                        elif (tag == 'windSpeed'):
                            val = wd.get('mps')
                        elif (tag == 'symbol'):
                            condition = int(wd.get('number'), RMParser.conditionType.Unknown)
                            val = self.conditionConvert(condition)
                        elif (tag == 'cloudiness' or tag == 'fog' or tag == 'lowClouds' or tag == 'mediumClouds' or tag == 'highClouds'):
                            val = wd.get('percent')
                        else:
                            val = wd.get('value')

                        if typeConvert == 'int':
                            val = int(val)
                        if typeConvert == 'float':
                            val = float(val)

                        # hPa -> kPa
                        if (tag == 'pressure'):
                            val = val / 10                            
                    except Exception, e:
                        val = None
                        log.debug(e)
                    values.append(val)
 def __writeNotification(string):
     #log.info("NotifyCloud: %s" % string)
     try:
         if stat.S_ISFIFO(os.stat(RMNotification.__cloudClientControlFile).st_mode) > 0:
             fd = os.open(RMNotification.__cloudClientControlFile, os.O_WRONLY | os.O_NONBLOCK)
             try:
                 os.write(fd, string)
                 log.debug("Notified cloud client about change")
             except Exception, e:
                 log.debug("Can't notify cloud client about settings change %s", str(e))
             finally:
                 os.close(fd)
Example #24
0
    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
        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 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)
Example #27
0
    def getUptime(self):
        uptimeSeconds = 0
        if RMOSPlatform().AUTODETECTED == RMOSPlatform.ANDROID:
            uptimeSeconds = getAlarmElapsedRealTime()
        else:
            try:
                with open('/proc/uptime') as f:
                    procLine = f.readline().split()[0]

                uptimeSeconds = int(float(procLine))
            except (IOError, OSError):
                log.debug("Cannot get platform uptime.")

        return uptimeSeconds
    def isInFreezeProtect(self, timestamp):
        if self.globalRestrictions.useFreezeControlTemp:
            dayMinTemp = self.__dayMinTemperature.get(rmGetStartOfDay(timestamp), None)

            if dayMinTemp is None:
                log.debug("No minimum temperature for %d found, won't restrict." % rmGetStartOfDay(timestamp))
                return False

            if int(dayMinTemp) <= int(self.globalRestrictions.minFreezeControlTemp):
                log.debug("Restricted for minimum temperature %s <= %s" % \
                          (`dayMinTemp`, `self.globalRestrictions.minFreezeControlTemp`))
                return True

        return False
    def perform(self):
        # downloading data from a URL convenience function since other python libraries can be used
        URL = self.params["URL"]
        data = self.openURL(URL)

        if data is None:
            self.lastKnownError = "Error: No data received from server"
            return

        #xmldata = e.parse("/tmp/IDQ11295.xml")

        xmldata = e.parse(data)

        for node in xmldata.getroot().getiterator(tag="area"):
            if node.attrib['description'] != self.params["city"]:
                continue

            for subnode in node.getiterator(tag="forecast-period"):
                subnodeDate = subnode.get("start-time-utc")
                subnodeTimestamp = rmTimestampFromDateAsString(
                    subnodeDate, '%Y-%m-%dT%H:%M:%SZ')
                log.info("%s" % subnodeDate)
                for element in subnode.getiterator(tag="element"):
                    mint = None
                    maxt = None
                    qpfMin = None
                    qpfMax = None
                    qpfAvg = None

                    type = element.get("type")
                    if type == "air_temperature_minimum":
                        try:
                            mint = self.__toFloat(element.text)
                            log.info("\tMin Temp: %s" % mint)
                            self.addValue(RMParser.dataType.MINTEMP,
                                          subnodeTimestamp, mint)
                        except:
                            log.debug("Cannot get minimum temperature")
                    elif type == "air_temperature_maximum":
                        try:
                            maxt = self.__toFloat(element.text)
                            self.addValue(RMParser.dataType.MAXTEMP,
                                          subnodeTimestamp, maxt)
                            log.info("\tMax Temp: %s" % maxt)
                        except:
                            log.debug("Cannot get max temperature")
                    elif type == "precipitation_range":
                        try:
                            qpfMin, _, qpfMax, _ = element.text.split(
                            )  # will result in ['15', 'to', '35', 'mm']
                            qpfAvg = (self.__toFloat(qpfMin) +
                                      self.__toFloat(qpfMax)) / 2
                            log.info("\tQPF Avg: %s" % qpfAvg)
                            self.addValue(RMParser.dataType.QPF,
                                          subnodeTimestamp, qpfAvg)
                        except:
                            log.debug("Cannot get precipitation forecast")

            if self.parserDebug:
                log.debug(self.result)
    def getUptime(self):
        uptimeSeconds = 0
        if RMOSPlatform().AUTODETECTED == RMOSPlatform.ANDROID:
            uptimeSeconds = getAlarmElapsedRealTime()
        else:
            try:
                with open('/proc/uptime') as f:
                    procLine = f.readline().split()[0]

                uptimeSeconds = int(float(procLine))
            except (IOError, OSError):
                log.debug("Cannot get platform uptime.")

        return uptimeSeconds
Example #31
0
 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 conditionConvert(self, weathercodes, cloudcodes):
        temparr = str(weathercodes).split(":")

        log.debug("Weatherarray: {}, conditions: {}".format(
            temparr, cloudcodes))
        intensity = temparr[1]
        conditionStr = temparr[2]

        if (conditionStr == 'L') or (conditionStr == 'ZL'):
            return RMParser.conditionType.LightRain
        elif (conditionStr == 'R') or (conditionStr == 'RW') or (
                conditionStr == 'RS') or (conditionStr
                                          == 'ZR') or (conditionStr == 'WM'):
            if (intensity == 'H') or (intensity == 'VH'):
                return RMParser.conditionType.HeavyRain
            else:
                return RMParser.conditionType.LightRain
        elif 'M' in conditionStr:
            return RMParser.conditionType.LightRain
        elif 'BR' in conditionStr:
            return RMParser.conditionType.LightRain
        elif 'S' in conditionStr:
            return RMParser.conditionType.Snow
        elif 'IP' in conditionStr:
            return RMParser.conditionType.IcePellets
        elif 'A' in conditionStr:
            return RMParser.conditionType.IcePellets
        elif (conditionStr == 'F') or (conditionStr == 'ZF'):
            return RMParser.conditionType.Fog
        elif 'H' in conditionStr:
            return RMParser.conditionType.Haze
        elif 'T' in conditionStr:
            return RMParser.conditionType.Thunderstorm
        elif 'K' in conditionStr:
            return RMParser.conditionType.Smoke

        elif '' in conditionStr:
            if 'OV' in cloudcodes:
                return RMParser.conditionType.Overcast
            elif 'CL' in cloudcodes:
                return RMParser.conditionType.Fair
            elif 'SC' in cloudcodes:
                return RMParser.conditionType.Fair
            elif 'BK' in cloudcodes:
                return RMParser.conditionType.PartlyCloudy
            elif 'FW' in cloudcodes:
                return RMParser.conditionType.Fair
        else:
            return RMParser.conditionType.Unknown
 def renewAccesTokenIfNeeded(self):
     try:
         if self.accessTokenExpiration < time.time():
             postParams = {
                 "grant_type" : "refresh_token",
                 "refresh_token" : self.refreshToken,
                 "client_id" : self.clientID,
                 "client_secret" : self.clientSecret
             }
             response = self.postRequest(self.authReq, postParams)
             self.accessToken = response['access_token']
             self.refreshToken = response['refresh_token']
             self.accessTokenExpiration = int(response['expire_in']) + time.time()
     except:
         log.debug("Failed to refresh token")
    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)
Example #35
0
    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 __upload(self, localPath, file):
        with open(os.path.join(localPath, file), "rb") as f:
            log.debug("Uploading file: %s" % file)

            extraRemotePath = os.path.split(file)[0]

            if extraRemotePath:
                if os.path.isabs(extraRemotePath):
                    extraRemotePath = extraRemotePath.lstrip("/")
                    file = file.lstrip("/")
                try:
                    self.__ftp.mkd(extraRemotePath)
                except Exception, e:
                    log.debug("Folder %s/ creation failed: %s" % (extraRemotePath, e))

            self.__ftp.storbinary("STOR " + file, f)
Example #37
0
 def getFromProc(self):
     status = None
     result = {'peak': 0, 'rss': 0}
     try:
         status = open(self.statpath)
         for line in status:
             parts = line.split()
             key = parts[0][2:-1].lower()
             if key in result:
                 result[key] = int(parts[1])
     except (IOError, OSError):
         log.debug("Cannot get memory stats from /proc")
     finally:
         if status is not None:
             status.close()
     return result
 def renewAccesTokenIfNeeded(self):
     try:
         if self.accessTokenExpiration < time.time():
             postParams = {
                 "grant_type": "refresh_token",
                 "refresh_token": self.refreshToken,
                 "client_id": self.clientID,
                 "client_secret": self.clientSecret
             }
             response = self.postRequest(self.authReq, postParams)
             self.accessToken = response['access_token']
             self.refreshToken = response['refresh_token']
             self.accessTokenExpiration = int(
                 response['expire_in']) + time.time()
     except:
         log.debug("Failed to refresh token")
 def getFromProc(self):
     status = None
     result = {'peak': 0, 'rss': 0}
     try:
         status = open(self.statpath)
         for line in status:
             parts = line.split()
             key = parts[0][2:-1].lower()
             if key in result:
                 result[key] = int(parts[1])
     except (IOError, OSError):
         log.debug("Cannot get memory stats from /proc")
     finally:
         if status is not None:
             status.close()
     return result
 def clientOauth(self):
     postParams = {
         "grant_type": "password",
         "client_id": self.clientID,
         "client_secret": self.clientSecret,
         "username": self.username,
         "password": self.password,
         "scope": "read_station"
     }
     try:
         resp = self.postRequest(self.authReq, postParams)
         self.accessToken = resp['access_token']
         self.refreshToken = resp['refresh_token']
         self.accessTokenExpiration = int(resp['expire_in']) + time.time()
     except:
         log.debug("Failed to get oauth token")
 def clientOauth(self):
     postParams = {
         "grant_type" : "password",
         "client_id" : self.clientID,
         "client_secret" : self.clientSecret,
         "username" : self.username,
         "password" : self.password,
         "scope" : "read_station"
      }
     # try:
     resp = self.postRequest(self.authReq, postParams)
     self.accessToken = resp['access_token']
     self.refreshToken = resp['refresh_token']
     self.accessTokenExpiration = int(resp['expire_in']) + time.time()
     # except:
     log.debug("Failed to get oauth token")
    def postRequest(self, url, params):
        params = urlencode(params)
        headers = {"Content-Type" : "application/x-www-form-urlencoded;charset=utf-8"}
        req = urllib2.Request(url=url, data=params, headers=headers)
        resp = None

        try:
            resp = urllib2.urlopen(req).read()
        except urllib2.URLError, e:
            log.debug(e)
            try:
                context = ssl._create_unverified_context()
                resp = urllib2.urlopen(req, context=context).read()
            except Exception, e:
                log.exception(e)
                return None
    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
Example #44
0
    def __upload(self, localPath, file):
        with open(os.path.join(localPath, file), "rb") as f:
            log.debug("Uploading file: %s" % file)

            extraRemotePath = os.path.split(file)[0]

            if extraRemotePath:
                if os.path.isabs(extraRemotePath):
                    extraRemotePath = extraRemotePath.lstrip("/")
                    file = file.lstrip("/")
                try:
                    self.__ftp.mkd(extraRemotePath)
                except Exception, e:
                    log.debug("Folder %s/ creation failed: %s" %
                              (extraRemotePath, e))

            self.__ftp.storbinary("STOR " + file, f)
Example #45
0
 def __writeNotification(string):
     #log.info("NotifyCloud: %s" % string)
     try:
         if stat.S_ISFIFO(
                 os.stat(
                     RMNotification.__cloudClientControlFile).st_mode) > 0:
             fd = os.open(RMNotification.__cloudClientControlFile,
                          os.O_WRONLY | os.O_NONBLOCK)
             try:
                 os.write(fd, string)
                 log.debug("Notified cloud client about change")
             except Exception, e:
                 log.debug(
                     "Can't notify cloud client about settings change %s",
                     str(e))
             finally:
                 os.close(fd)
Example #46
0
    def apiCall(self, apiURL):

        # try:
        d = self.openURL(apiURL)
        # request = urllib2.urlopen(apiURL)
        jsonContent = d.read()
        if jsonContent is None:
            log.debug("Failed to get Aeris JSON contents")
            self.lastKnownError = "Error: Bad response"
            return

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

        jsonResponse = (json.loads(jsonContent))
        # print (jsonResponse)
        if (jsonResponse['success']):
            return jsonResponse
    def perform(self):
        if self.params["minTemp"] is not None:
            self.tempMin = self.params["minTemp"]
        if self.params["maxTemp"] is not  None:
            self.tempMax = self.params["maxTemp"]

        startDayTimestamp = (self._currentDayTimestamp())
        #prediction timestamps
        noOfDays = 6
        arrTimestamps = [x for x in range(startDayTimestamp, startDayTimestamp+noOfDays*24*3600, 4*3600)]

        #-----------------------------------------------------------------------------------------------
        #
        # Get hourly data.
        self.addValues(RMParser.dataType.TEMPERATURE, self._generatePeriodicalData(arrTimestamps, self.tempMin
            , self.tempMax, 6, -2.5))

        self.addValues(RMParser.dataType.MINTEMP, self._generateCumulativeData(arrTimestamps, self.tempMin/2, self.tempMin*2))
        self.addValues(RMParser.dataType.MAXTEMP, self._generateCumulativeData(arrTimestamps, self.tempMax/2, self.tempMax*2))

        self.addValues(RMParser.dataType.DEWPOINT, self._generateCumulativeData(arrTimestamps, self.dewMin, self.dewMax))
        self.addValues(RMParser.dataType.WIND, self._generateCumulativeData(arrTimestamps, self.windMin, self.windMax))
        self.addValues(RMParser.dataType.POP, self._generateCumulativeData(arrTimestamps, self.popMin, self.popMax))
        self.addValues(RMParser.dataType.RH, self._generatePeriodicalData(arrTimestamps, 2*math.fabs(self.tempMin)
            , 2*math.fabs(self.tempMax), 6, 0))

        #-----------------------------------------------------------------------------------------------
        #
        # Get daily data.
        #
        #self.addValues(RMParser.dataType.CONDITION, parsedConditions)
        #
        self._generateQpfRainModelData()
        #
        ##add history for yesterday
        startYesterday = self._currentDayTimestamp() - 24*3600
        self.addValue(RMParser.dataType.TEMPERATURE, startYesterday, (self.tempMax+self.tempMin)*random.random())
        self.addValue(RMParser.dataType.MINTEMP, startYesterday, self.tempMin*random.random())
        self.addValue(RMParser.dataType.MAXTEMP, startYesterday, self.tempMax*random.random())
        self.addValue(RMParser.dataType.RH, startYesterday, (self.humidityMin+self.humidityMax)*random.random())
        self.addValue(RMParser.dataType.MINRH, startDayTimestamp, self.humidityMin*random.random())
        self.addValue(RMParser.dataType.MAXRH, startDayTimestamp, self.humidityMax*random.random())

        if self.parserDebug:
            log.debug(self.result)
Example #48
0
    def perform(
            self):  # The function that will be executed must have this name
        if self.params['stationID']:
            stationID = self.params['stationID']
        else:
            log.error("*** No Station ID")
            self.lastKnownError = "No Station ID"

        #NOAA has a bunch of different feeds for the weather data, but only obhistory has rainfall
        # A full listing of stations/urls can be found here: https://w1.weather.gov/xml/current_obs/index.xml
        stationURL = "https://w1.weather.gov/data/obhistory/" + stationID + ".html"
        self.params['_stationURL'] = stationURL

        # downloading data from a URL convenience function since other python libraries can be used
        self.getObservations(stationURL)

        if self.parserDebug:
            log.debug(self.result)
    def getDayGlobalRestriction(self, timestamp, ignoreFreezeProtect=False):
        # Cyclic import workaround
        from RMDataFramework.rmMainDataRecords import RMZoneWateringFlag

        if self.isInMonthRestriction(timestamp):
            return RMZoneWateringFlag.zwfRestrictionMonth

        if self.isInDayRestriction(timestamp):
            return RMZoneWateringFlag.zwfRestrictionDay

        if self.getRainDelayRestriction(timestamp) > 0:
            log.debug("Restricted for rain delay")
            return RMZoneWateringFlag.zwfRestrictionRainDelay

        if not ignoreFreezeProtect and self.isInFreezeProtect(timestamp):
            return RMZoneWateringFlag.zwfRestrictionFreezeProtect

        return RMZoneWateringFlag.zwfNormal
    def getDayGlobalRestriction(self, timestamp, ignoreFreezeProtect=False):
        # Cyclic import workaround
        from RMDataFramework.rmMainDataRecords import RMZoneWateringFlag

        if self.isInMonthRestriction(timestamp):
            return RMZoneWateringFlag.zwfRestrictionMonth

        if self.isInDayRestriction(timestamp):
            return RMZoneWateringFlag.zwfRestrictionDay

        if self.getRainDelayRestriction(timestamp) > 0:
            log.debug("Restricted for rain delay")
            return RMZoneWateringFlag.zwfRestrictionRainDelay

        if not ignoreFreezeProtect and self.isInFreezeProtect(timestamp):
            return RMZoneWateringFlag.zwfRestrictionFreezeProtect

        return RMZoneWateringFlag.zwfNormal
    def isInFreezeProtect(self, timestamp):
        if self.globalRestrictions.useFreezeControlTemp:
            dayMinTemp = self.__dayMinTemperature.get(
                rmGetStartOfDay(timestamp), None)

            if dayMinTemp is None:
                log.debug(
                    "No minimum temperature for %d found, won't restrict." %
                    rmGetStartOfDay(timestamp))
                return False

            if int(dayMinTemp) <= int(
                    self.globalRestrictions.minFreezeControlTemp):
                log.debug("Restricted for minimum temperature %s <= %s" % \
                          (`dayMinTemp`, `self.globalRestrictions.minFreezeControlTemp`))
                return True

        return 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 __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 __getSolarRadiation(self):
        historyForecast = self.jsonResponse["history"]["observations"]
        if historyForecast is None:
            log.debug("No hourly forecast found for solar radiation")
            return

        arrSR = []
        arrT = []

        for obsdict in historyForecast:
            instantSr = self.__toFloat(obsdict["solarradiation"])
            if instantSr is None:
                log.debug("Invalid solar radiation value found in forecast")
                return
            arrSR.append(instantSr)
            hour = self.__toInt(obsdict["date"]["hour"])
            min = self.__toInt(obsdict["date"]["min"])
            mm = hour*60 + min
            arrT.append(mm)
        #computing solar energy per minute (measurement unit = W*min*m-2)
        solarRadEnergy = 0
        for i in range(0, len(arrSR)):
            dt = arrT[i]
            if(i>0):
                dt -= arrT[i-1]
            solarRadEnergy += dt * arrSR[i]

        #converting to W*h*m-2
        solarRadEnergy = solarRadEnergy / 60
        #converting to MJ*m-2
        solarRadEnergyMJ = solarRadEnergy * 3.6 /1000

        #time utc
        jutc = self.jsonResponse["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"])
        dd = datetime.datetime(yyyy, mm, dd, hour, mins)
        timestamp = calendar.timegm( dd.timetuple())
        self.addValue(RMParser.dataType.SOLARRADIATION, timestamp, solarRadEnergyMJ)
    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 preRun(self):
        unmixedForecastAvailable = False

        lastForecast = None
        latestForecastByParser = self.parserDataTable.getLastForecastByParser()
        for parserID in latestForecastByParser:
            parserConfig = self.findParserConfig(parserID)
            if parserConfig != None:
                parserConfig.runtimeLastForecastInfo = latestForecastByParser[parserID]
                if not parserConfig.runtimeLastForecastInfo.processed:
                    unmixedForecastAvailable = True
                if lastForecast == None:
                    lastForecast = parserConfig.runtimeLastForecastInfo

        log.debug("*** All values are already mixed! No need to run the Mixer!")

        for parserConfig in self.parsers:
            self.parserDataTable.clearHistory(parserConfig.dbID, False)
        globalDbManager.parserDatabase.commit()
        globalDbManager.parserDatabase.vacuum()

        return None, None
    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