Beispiel #1
0
    def render(self, data={}, context={}):
        try:
            assert self.username is not None, "'MetofficeWOW.siteid' must be set"
            assert self.password is not None, "'MetofficeWOW.siteAuthenticationKey' must be set"
            assert self.period is not None, "'MetofficeWOW.period' must be set"

            self.logger.info("Initializing MetOffice WOW Upload (user %s)" % self.username)

            self.alive = True

            accu = AccumulatorDatasource()
            accu.slice = 'hour'
            accu.span = 2
            accu.storage = self.storage

            accu.formulas = {'current': {
                 'temp'         : LastFormula('temp'),
                 'hum'          : LastFormula('hum'),
                 'pressure'     : LastFormula('pressure'),
                 'wind'         : LastFormula('wind'),
                 'wind_deg'     : LastFormula('wind_dir'),
                 'rain'         : SumFormula('rain'),
                 'utctime'      : LastFormula('utctime') } }

            while self.alive:
                try:
                    data = accu.execute()['current']['series']
                    index = len(data['lbl'])-1

                    args = {
                        'dateutc':                data['utctime'][index].strftime('%Y-%m-%d %H:%M:%S'),
                        # Some ARGs are hashed out here as Metoffice WOW needs them in the correct order or it will reject the post
                        # I found that if I used the args they are in a random order so define them on the URL encode instead
                        #'siteAuthenticationKey': str(self.password),
                        #'softwaretype':          "Wfrog",
                        'humidity':               int(round(data['hum'][index])),
                        'tempf':                  str(CToF(data['temp'][index])),
                        #'siteid':                str(self.username),
                        'winddir':                int(round(data['wind_deg'][index])),
                        'windspeedmph':           str(MpsToMph(data['wind'][index])),
                        'baromin':                str(HPaToInHg(data['pressure'][index])),
                        'rainin':                 str(MmToIn(data['rain'][index])) }

                    self.logger.info("Publishing Metoffice WOW data: %s " % urlencode(args))
                    self._publish(args, 'wow.metoffice.gov.uk', '/automaticreading')

                except Exception, e:
                    if (str(e) == "'NoneType' object has no attribute 'strftime'") or (str(e) == "a float is required"):
                        self.logger.error('Could not publish: no valid values at this time. Retry next run...')
                    else:
                        self.logger.error('Got unexpected error. Retry next run. Error: %s' % e)
 
                time.sleep(self.period)

        except Exception, e:
            self.logger.exception(e)
            raise
Beispiel #2
0
    def render(self, data={}, context={}):
        try:
            assert self.stationId is not None, "'wettercom.stationId' must be set"
            assert self.password is not None, "'wettercom.password' must be set"
            assert self.period is not None, "'wettercom.period' must be set"

            self.logger.info("Initializing Wetter.com (stationID %s)" % self.stationId)

            self.alive = True

            accu = AccumulatorDatasource()
            accu.slice = 'hour'
            accu.span = 1
            accu.storage = self.storage

            accu.formulas =     {'current': {
                 'temp'         : LastFormula('temp'),
                 'hum'          : LastFormula('hum'),
                 'hum2'         : LastFormula('hum2'),
                 'pressure'     : LastFormula('pressure'),
                 'wind'         : LastFormula('wind'),
                 'wind_deg'     : LastFormula('wind_dir'),
                 'rain'         : LastFormula('rain'),
                 'localtime'    : LastFormula('localtime'),
                 'utctime'      : LastFormula('utctime'),
                 'dew_point'    : LastFormula('dew_point') } }

            while self.alive:
                try:
                    data = accu.execute()['current']['series']
                    self.logger.debug("Got data from accumulator: %s" % data)
                    index = len(data['lbl'])-1

                    try:
                        # If date is NoneType (see except for this try), we need to wait for a new value in wfrog.csv

                        args = {
                            'sid'                   : 'wfrog',
                            'id'                    : str(self.stationId),
                            'pwd'                   : str(self.password),
                            'dt'                    : data['localtime'][index].strftime('%Y%m%d%H%M'),
                            'dtutc'                 : data['utctime'][index].strftime('%Y%m%d%H%M'), # we need both, dt (date) and dtutc (date in UTC).
                            'hu'                    : int(round(data['hum'][index])),
                            'te'                    : str(data['temp'][index]),
                            'dp'                    : str(data['dew_point'][index]),
                            'wd'                    : int(round(data['wind_deg'][index])),
                            'ws'                    : str(data['wind'][index]),
                            'pr'                    : str(data['pressure'][index]),
                            'pa'                    : str(data['rain'][index])
                            }
                            
                        if self.test:
                            args["test"] = "true"
                            self.logger.info('#!#!#!#!#!#!#!#!#!#! >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Running in test-mode!! The data wont be stored. #!#!#!#!#!#!#!#!#!#!')

                        self.logger.debug("Publishing wettercom data: %s " % args)
                        rawResponse = self._publish(args, 'interface.wetterarchiv.de', '/weather/')
                        self.logger.debug('Server response: Code: %s Status: %s API-Answer: %s' % rawResponse)
                        
                        # Ok, now create an JSON-object
                        response = json.loads(rawResponse[2])
                        
                        # With the new API, checking for any error is very easy!
                        if (response["status"] == "success"):
                            self.logger.info('Data published successfully!')
                        else:
                            self.logger.error('Data publishing fails! Code: %s | Description: %s' % response["errorcode"], response["errormessage"])

                    except Exception, e:
                        if (str(e) == "'NoneType' object has no attribute 'strftime'") or (str(e) == "a float is required"):
                            self.logger.error('Could not publish: no valid values at this time. Retry next run...')
                        else:
                            self.logger.error('Got unexpected error. Retry next run. Error: %s' % e)
                            raise
                except Exception, e:
                    self.logger.exception(e)

                time.sleep(self.period)

        except Exception, e:
            self.logger.exception(e)
            raise
Beispiel #3
0
    def render(self, data={}, context={}):
        try:
            assert self.id is not None, "'wunderground.id' must be set"
            assert self.password is not None, "'wunderground.password' must be set"
            assert self.period is not None, "'wunderground.period' must be set"

            self.real_time = self.real_time and self.period < 30

            rtfreq = None
            if self.real_time: rtfreq = self.period

            self.logger.info(
                "Initializing Wunderground publisher (station %s)" % self.id)
            import weather.services
            self.publisher = weather.services.Wunderground(
                self.id, self.password, rtfreq)

            self.alive = True
            if not self.real_time:

                accu = AccumulatorDatasource()
                accu.slice = 'day'
                accu.span = 1
                accu.storage = self.storage
                accu.formulas = {
                    'current': {
                        'temp': LastFormula('temp'),
                        'dew_point': LastFormula('dew_point'),
                        'hum': LastFormula('hum'),
                        'pressure': LastFormula('pressure'),
                        'wind': LastFormula('wind'),
                        'wind_deg': LastFormula('wind_dir'),
                        'gust': LastFormula('wind_gust'),
                        'gust_deg': LastFormula('wind_gust_dir'),
                        'rain_rate': LastFormula('rain_rate'),
                        'rain_fall': SumFormula('rain'),
                        'utctime': LastFormula('utctime')
                    }
                }

                while self.alive:
                    try:
                        data = accu.execute()['current']['series']
                        index = len(data['lbl']) - 1

                        params = {
                            # <float> pressure: in inches of Hg
                            'pressure':
                            HPaToInHg(data['pressure'][index]),
                            # <float> dewpoint: in Fahrenheit
                            'dewpoint':
                            CToF(data['dew_point'][index]),
                            # <float> humidity: between 0.0 and 100.0 inclusive
                            'humidity':
                            data['hum'][index],
                            # <float> tempf: in Fahrenheit
                            'tempf':
                            CToF(data['temp'][index]),
                            # <float> rainin: inches/hour of rain
                            'rainin':
                            MmToIn(data['rain_rate'][index]),
                            # <float> rainday: total rainfall in day (localtime)
                            'rainday':
                            MmToIn(data['rain_fall'][index]),
                            # <string> dateutc: date "YYYY-MM-DD HH:MM:SS" in GMT timezone
                            'dateutc':
                            data['utctime'][index].strftime(
                                '%Y-%m-%d %H:%M:%S'),
                            # <float> windspeed: in mph
                            'windspeed':
                            MpsToMph(data['wind'][index]),
                            # <float> winddir: in degrees, between 0.0 and 360.0
                            'winddir':
                            data['wind_deg'][index],
                            # <float> windgust: in mph
                            'windgust':
                            MpsToMph(data['gust'][index]),
                            # <float> windgustdir: in degrees, between 0.0 and 360.0
                            'windgustdir':
                            data['gust_deg'][index]
                        }

                        # Do not send parameters that are null (None).
                        # from above only dateutc is a mandatory parameter.
                        params = dict(
                            filter(lambda (p, v): v,
                                   [(p, v) for p, v in params.iteritems()]))
                        self.logger.info(
                            "Publishing Wunderground data (normal server): %s "
                            % str(params))
                        self.publisher.set(**params)
                        response = self.publisher.publish()
                        self.logger.info('Result Wunderground publisher: %s' %
                                         str(response))

                    except Exception, e:
                        self.logger.exception(e)

                    time.sleep(self.period)
            else:
Beispiel #4
0
    def render(self, data={}, context={}):
        try:
            assert self.username is not None, "'openweathermap.id' must be set"
            assert self.password is not None, "'openweathermap.password' must be set"
            assert self.name is not None, "'openweathermap.name' must be set"
            assert self.latitude is not None, "'openweathermap.latitude' must be set"
            assert self.longitude is not None, "'openweathermap.longitude' must be set"
            assert self.altitude is not None, "'openweathermap.altitude' must be set"
            
            self.logger.info("Initializing openweathermap.com (user %s)" % self.username)

            self.alive = True

            accu = AccumulatorDatasource()
            accu.slice = 'day'
            accu.span = 1
            accu.storage = self.storage

            accu.formulas =     {'current': {
                 'temp'      : LastFormula('temp'),
                 'hum'       : LastFormula('hum'),
                 'pressure'  : LastFormula('pressure'),
                 'dew_point' : LastFormula('dew_point'),
                 'wind'      : LastFormula('wind'),
                 'wind_gust' : LastFormula('wind_gust'),
                 'wind_deg'  : LastFormula('wind_dir'),
                 'rain'      : SumFormula('rain'),
                 'utctime'   : LastFormula('utctime') } }

            if self.send_uv:
                accu.formulas['current']['uv'] = LastFormula('uv')

            if self.send_radiation:
                accu.formulas['current']['solar_rad'] = LastFormula('solar_rad')

            accu24h = AccumulatorDatasource()
            accu24h.slice = 'hour'
            accu24h.span = 24
            accu24h.storage = self.storage
            accu24h.formulas =  {'current': {'rain': SumFormula('rain')} }

            accu60min = AccumulatorDatasource()
            accu60min.slice = 'minute'
            accu60min.span = 60
            accu60min.storage = self.storage
            accu60min.formulas =  {'current': {'rain': SumFormula('rain')} }

            last_timestamp = None
            while self.alive:

                try:
                    data = accu.execute()['current']['series']
                    index = len(data['lbl'])-1
                    rain_1h = sum(map(lambda x: x if x is not None else 0, accu60min.execute()['current']['series']['rain'][:60]))
                    rain_24h = sum(map(lambda x: x if x is not None else 0, accu24h.execute()['current']['series']['rain'][:24]))

                    if last_timestamp == None or last_timestamp < data['utctime'][index]:
                        last_timestamp = data['utctime'][index]

                        args = {
                            'wind_dir':   int(round(data['wind_deg'][index])), # grad
                            'wind_speed': str(data['wind'][index]),            # mps
                            'wind_gust':  str(data['wind_gust'][index]),       # mps
                            'temp':       str(data['temp'][index]),            # grad C
                            #'dewpoint':   str(data['dew_point'][index]),       # NOT WORKING PROPERLY
                            'humidity':   int(round(data['hum'][index])),      # relative humidity %
                            'pressure':   str(data['pressure'][index]),        # mb 
                            'rain_1h':    rain_1h,                             # mm 
                            'rain_24h':   rain_24h,                            # mm
                            'rain_today': str(data['rain'][index]),            # mm
                            'lat':        self.latitude,
                            'long':        self.longitude,
                            'alt':        self.altitude,
                            'name':       self.name
                            }

                        if self.send_uv:
                            args['uv'] = str(data['uv'][index])
                        if self.send_radiation: 
                            args['lum'] = str(data['solar_rad'][index])
 
                        self.logger.debug("Publishing openweathermap data: %s " % urllib.urlencode(args))
                        response = self._publish(args, 'openweathermap.org', '/data/post')

                        if response[0] == 200:
                            self.logger.info('Data published successfully')
                            self.logger.debug('Code: %s Status: %s Answer: %s' % response)
                        else:
                            self.logger.error('Error publishing data. Code: %s Status: %s Answer: %s' % response)

                except Exception, e:
                    if (str(e) == "'NoneType' object has no attribute 'strftime'") or (str(e) == "a float is required"):
                        self.logger.error('Could not publish: no valid values at this time. Retry next run...')
                    else:
                        self.logger.exception(e)

                time.sleep(60) # each minute we check for new records to send to openweathermap

        except Exception, e:
            self.logger.exception(e)
            raise
Beispiel #5
0
    def render(self, data={}, context={}):
        try:
            assert self.id is not None, "'wunderground.id' must be set"
            assert self.password is not None, "'wunderground.password' must be set"
            assert self.period is not None, "'wunderground.period' must be set"

            self.real_time = self.real_time and self.period < 30

            rtfreq = None
            if self.real_time: rtfreq = self.period

            self.logger.info("Initializing Wunderground publisher (station %s)" % self.id)
            import weather.services
            self.publisher = weather.services.Wunderground(self.id, self.password, rtfreq)

            self.alive = True
            if not self.real_time:

                accu = AccumulatorDatasource()
                accu.slice = 'day'
                accu.span = 1
                accu.storage = self.storage
                accu.formulas = {'current': {
                     'temp' : LastFormula('temp'),
                     'dew_point': LastFormula('dew_point'),
                     'hum' : LastFormula('hum'),
                     'pressure' : LastFormula('pressure'),
                     'wind' : LastFormula('wind'),
                     'wind_deg' : LastFormula('wind_dir'),
                     'gust' : LastFormula('wind_gust'),
                     'gust_deg' : LastFormula('wind_gust_dir'),
                     'rain_rate' : LastFormula('rain_rate'),
                     'rain_fall' : SumFormula('rain'), 
                     'utctime' : LastFormula('utctime') } }

                while self.alive:
                    try:
                        data = accu.execute()['current']['series']
                        index = len(data['lbl'])-1

                        params = {
                            # <float> pressure: in inches of Hg
                            'pressure' : HPaToInHg(data['pressure'][index]),
                            # <float> dewpoint: in Fahrenheit
                            'dewpoint' : CToF(data['dew_point'][index]),
                            # <float> humidity: between 0.0 and 100.0 inclusive
                            'humidity' : data['hum'][index],
                            # <float> tempf: in Fahrenheit
                            'tempf' : CToF(data['temp'][index]),
                            # <float> rainin: inches/hour of rain
                            'rainin' : MmToIn(data['rain_rate'][index]),
                            # <float> rainday: total rainfall in day (localtime)
                            'rainday' : MmToIn(data['rain_fall'][index]),
                            # <string> dateutc: date "YYYY-MM-DD HH:MM:SS" in GMT timezone
                            'dateutc' : data['utctime'][index].strftime('%Y-%m-%d %H:%M:%S'),
                            # <float> windspeed: in mph
                            'windspeed' : MpsToMph(data['wind'][index]),
                            # <float> winddir: in degrees, between 0.0 and 360.0
                            'winddir' : data['wind_deg'][index],
                            # <float> windgust: in mph
                            'windgust' : MpsToMph(data['gust'][index]),
                            # <float> windgustdir: in degrees, between 0.0 and 360.0
                            'windgustdir' : data['gust_deg'][index] }

                        # Do not send parameters that are null (None).
                        # from above only dateutc is a mandatory parameter.
                        params = dict(filter(lambda (p,v): v, [(p,v) for p,v in params.iteritems()]))
                        self.logger.info("Publishing Wunderground data (normal server): %s " % str(params))
                        self.publisher.set(**params)
                        response = self.publisher.publish()               
                        self.logger.info('Result Wunderground publisher: %s' % str(response))

                    except Exception, e:
                        self.logger.exception(e)

                    time.sleep(self.period)
            else:
Beispiel #6
0
    def render(self, data={}, context={}):
        try:
            assert self.username is not None, "'MetofficeWOW.siteid' must be set"
            assert self.password is not None, "'MetofficeWOW.siteAuthenticationKey' must be set"
            assert self.period is not None, "'MetofficeWOW.period' must be set"

            self.logger.info("Initializing MetOffice WOW Upload (user %s)" %
                             self.username)

            self.alive = True

            accu = AccumulatorDatasource()
            accu.slice = 'hour'
            accu.span = 2
            accu.storage = self.storage

            accu.formulas = {
                'current': {
                    'temp': LastFormula('temp'),
                    'hum': LastFormula('hum'),
                    'pressure': LastFormula('pressure'),
                    'wind': LastFormula('wind'),
                    'wind_deg': LastFormula('wind_dir'),
                    'rain': SumFormula('rain'),
                    'utctime': LastFormula('utctime')
                }
            }

            while self.alive:
                try:
                    data = accu.execute()['current']['series']
                    index = len(data['lbl']) - 1

                    args = {
                        'dateutc':
                        data['utctime'][index].strftime('%Y-%m-%d %H:%M:%S'),
                        # Some ARGs are hashed out here as Metoffice WOW needs them in the correct order or it will reject the post
                        # I found that if I used the args they are in a random order so define them on the URL encode instead
                        #'siteAuthenticationKey': str(self.password),
                        #'softwaretype':          "Wfrog",
                        'humidity':
                        int(round(data['hum'][index])),
                        'tempf':
                        str(CToF(data['temp'][index])),
                        #'siteid':                str(self.username),
                        'winddir':
                        int(round(data['wind_deg'][index])),
                        'windspeedmph':
                        str(MpsToMph(data['wind'][index])),
                        'baromin':
                        str(HPaToInHg(data['pressure'][index])),
                        'rainin':
                        str(MmToIn(data['rain'][index]))
                    }

                    self.logger.info("Publishing Metoffice WOW data: %s " %
                                     urlencode(args))
                    self._publish(args, 'wow.metoffice.gov.uk',
                                  '/automaticreading')

                except Exception, e:
                    if (str(e)
                            == "'NoneType' object has no attribute 'strftime'"
                        ) or (str(e) == "a float is required"):
                        self.logger.error(
                            'Could not publish: no valid values at this time. Retry next run...'
                        )
                    else:
                        self.logger.error(
                            'Got unexpected error. Retry next run. Error: %s' %
                            e)

                time.sleep(self.period)

        except Exception, e:
            self.logger.exception(e)
            raise
Beispiel #7
0
    def render(self, data={}, context={}):
        try:
            assert self.id is not None, "'meteoclimatic.id' must be set"
            assert self.storage is not None, "'meteoclimatic.storage' must be set"

            if self.accuD == None:
                self.logger.info("Initializing accumulators")

                # Accumulator for yearly data
                self.accuY = AccumulatorDatasource()
                self.accuY.slice = 'year'
                self.accuY.span = 1
                self.accuY.caching = True
                self.accuY.storage = self.storage
                self.accuY.formulas = {
                    'data': {
                        'max_temp': MaxFormula('temp'),
                        'min_temp': MinFormula('temp'),
                        'max_hum': MaxFormula('hum'),
                        'min_hum': MinFormula('hum'),
                        'max_pressure': MaxFormula('pressure'),
                        'min_pressure': MinFormula('pressure'),
                        'max_gust': MaxFormula('wind_gust'),
                        'rain_fall': SumFormula('rain')
                    }
                }

                # Accumulator for monthly data
                self.accuM = AccumulatorDatasource()
                self.accuM.slice = 'month'
                self.accuM.span = 1
                self.accuM.storage = self.storage
                self.accuM.caching = True
                self.accuM.formulas = {
                    'data': {
                        'max_temp': MaxFormula('temp'),
                        'min_temp': MinFormula('temp'),
                        'max_hum': MaxFormula('hum'),
                        'min_hum': MinFormula('hum'),
                        'max_pressure': MaxFormula('pressure'),
                        'min_pressure': MinFormula('pressure'),
                        'max_gust': MaxFormula('wind_gust'),
                        'rain_fall': SumFormula('rain')
                    }
                }

                # Accumulator for daily and current data
                self.accuD = AccumulatorDatasource()
                self.accuD.slice = 'day'
                self.accuD.span = 1
                self.accuD.storage = self.storage
                self.accuD.caching = True
                self.accuD.formulas = {
                    'data': {
                        'max_temp': MaxFormula('temp'),
                        'min_temp': MinFormula('temp'),
                        'max_hum': MaxFormula('hum'),
                        'min_hum': MinFormula('hum'),
                        'max_pressure': MaxFormula('pressure'),
                        'min_pressure': MinFormula('pressure'),
                        'max_gust': MaxFormula('wind_gust'),
                        'rain_fall': SumFormula('rain')
                    },
                    'current': {
                        'temp': LastFormula('temp'),
                        'hum': LastFormula('hum'),
                        'pressure': LastFormula('pressure'),
                        'gust': LastFormula('wind_gust'),
                        'wind_deg': LastFormula('wind_dir'),
                        'time': LastFormula('localtime')
                    }
                }

                if 'solar_rad' in self.storage.keys():
                    self.accuD.formulas['current']['solar_rad'] = LastFormula(
                        'solar_rad')

            self.logger.info("Calculating ...")

            template = "*VER=DATA2*COD=%s*%s*%s*%s*%s*EOT*" % (
                self.id, self._calculateCurrentData(
                    self.accuD), self._calculateAggregData('D', self.accuD),
                self._calculateAggregData('M', self.accuM),
                self._calculateAggregData('Y', self.accuY))

            self.lastTemplate = template

            self.logger.info("Template calculated: %s" % template)

            return ['text/plain', template]

        except Exception, e:
            self.logger.warning("Error rendering meteoclimatic data: %s" %
                                str(e))
            if self.lastTemplate == None:
                return ['text/plain', "*VER=DATA2*COD=%s*EOT*" % self.id]
            else:
                return ['text/plain', self.lastTemplate]
Beispiel #8
0
    def render(self, data={}, context={}):
        try:
            assert self.id is not None, "'pws.id' must be set"
            assert self.password is not None, "'pws.password' must be set"
            assert self.period is not None, "'pws.period' must be set"

            self.logger.info("Initializing PWS publisher (station %s)" % self.id)
            import weather.services

            self.publisher = weather.services.PwsWeather(self.id, self.password)

            self.alive = True

            accu = AccumulatorDatasource()
            accu.slice = "day"
            accu.span = 1
            accu.storage = self.storage
            accu.formulas = {
                "current": {
                    "temp": LastFormula("temp"),
                    "dew_point": LastFormula("dew_point"),
                    "hum": LastFormula("hum"),
                    "pressure": LastFormula("pressure"),
                    "wind": LastFormula("wind"),
                    "wind_deg": LastFormula("wind_dir"),
                    "gust": LastFormula("wind_gust"),
                    "gust_deg": LastFormula("wind_gust_dir"),
                    "rain_rate": LastFormula("rain_rate"),
                    "rain_fall": SumFormula("rain"),
                    "utctime": LastFormula("utctime"),
                }
            }

            accu_month = AccumulatorDatasource()
            accu_month.slice = "month"
            accu_month.span = 1
            accu_month.storage = self.storage
            accu_month.formulas = {"current": {"rain_fall": SumFormula("rain")}}

            accu_year = AccumulatorDatasource()
            accu_year.slice = "year"
            accu_year.span = 1
            accu_year.storage = self.storage
            accu_year.formulas = {"current": {"rain_fall": SumFormula("rain")}}

            while self.alive:
                try:
                    data = accu.execute()["current"]["series"]
                    index = len(data["lbl"]) - 1
                    data_month = accu_month.execute()["current"]["series"]
                    index_month = len(data_month["lbl"]) - 1
                    data_year = accu_year.execute()["current"]["series"]
                    index_year = len(data_year["lbl"]) - 1

                    params = {
                        # <float> pressure: in inches of Hg
                        "pressure": HPaToInHg(data["pressure"][index]),
                        # <float> dewpoint: in Fahrenheit
                        "dewpoint": CToF(data["dew_point"][index]),
                        # <float> humidity: between 0.0 and 100.0 inclusive
                        "humidity": data["hum"][index],
                        # <float> tempf: in Fahrenheit
                        "tempf": CToF(data["temp"][index]),
                        # <float> rainin: inches/hour of rain
                        "rainin": MmToIn(data["rain_rate"][index]),
                        # <float> rainday: total rainfall in day (localtime)
                        "rainday": MmToIn(data["rain_fall"][index]),
                        # <float> rainmonth:  total rainfall for month (localtime)
                        "rainmonth": MmToIn(data_month["rain_fall"][index_month]),
                        # <float> rainyear:   total rainfall for year (localtime)
                        "rainyear": MmToIn(data_year["rain_fall"][index_year]),
                        # <string> dateutc: date "YYYY-MM-DD HH:MM:SS" in GMT timezone
                        "dateutc": data["utctime"][index].strftime("%Y-%m-%d %H:%M:%S"),
                        # <float> windgust: in mph
                        "windgust": MpsToMph(data["gust"][index]),
                        # <float> windspeed: in mph
                        "windspeed": MpsToMph(data["wind"][index]),
                        # <float> winddir: in degrees, between 0.0 and 360.0
                        "winddir": data["wind_deg"][index],
                    }

                    # Do not send parameters that are null (None), but don't remove zeroes (0.0)
                    # from above only dateutc is a mandatory parameter.
                    params = dict(filter(lambda (p, v): v is not None, [(p, v) for p, v in params.iteritems()]))
                    self.logger.info("Publishing PWS data: %s " % str(params))
                    self.publisher.set(**params)
                    response = self.publisher.publish()
                    self.logger.info("Result PWS publisher: %s" % str(response))

                except Exception, e:
                    self.logger.exception(e)

                time.sleep(self.period)

        except Exception, e:
            self.logger.exception(e)
            raise
Beispiel #9
0
    def render(self, data={}, context={}):
        try:
            import Image
            import ImageDraw
            import ImageColor

            assert self.storage is not None, "'sticker.storage' must be set"

            # Initialize accumulators

            if self.accuD == None:
                self.logger.info("Initializing accumulators")

                # Accumulator for yearly data
                self.accuY = AccumulatorDatasource()
                self.accuY.slice = 'year'
                self.accuY.span = 1
                self.accuY.caching = True
                self.accuY.storage = self.storage
                self.accuY.formulas = {
                    'data': {
                        'max_temp': MaxFormula('temp'),
                        'min_temp': MinFormula('temp'),
                        'max_gust': MaxFormula('wind_gust'),
                        'rain_fall': SumFormula('rain')
                    }
                }

                # Accumulator for monthly data
                self.accuM = AccumulatorDatasource()
                self.accuM.slice = 'month'
                self.accuM.span = 1
                self.accuM.storage = self.storage
                self.accuM.caching = True
                self.accuM.formulas = {
                    'data': {
                        'max_temp': MaxFormula('temp'),
                        'min_temp': MinFormula('temp'),
                        'max_gust': MaxFormula('wind_gust'),
                        'rain_fall': SumFormula('rain')
                    }
                }

                # Accumulator for daily and current data
                self.accuD = AccumulatorDatasource()
                self.accuD.slice = 'day'
                self.accuD.span = 1
                self.accuD.storage = self.storage
                self.accuD.caching = True
                self.accuD.formulas = {
                    'data': {
                        'max_temp': MaxFormula('temp'),
                        'min_temp': MinFormula('temp'),
                        'max_gust': MaxFormula('wind_gust'),
                        'rain_fall': SumFormula('rain')
                    },
                    'current': {
                        'temp': LastFormula('temp'),
                        'hum': LastFormula('hum'),
                        'pressure': LastFormula('pressure'),
                        'gust': LastFormula('wind_gust'),
                        'wind_deg': LastFormula('wind_dir'),
                        'time': LastFormula('localtime')
                    }
                }

            # Calculate data

            self.logger.info("Calculating ...")
            current = self._calculateCurrentData(self.accuD)

            # Create Sticker

            green = ImageColor.getrgb("#007000")
            wheat = ImageColor.getrgb("#F5DEB3")
            dark_wheat = ImageColor.getrgb("#8D7641")
            black = ImageColor.getrgb("#000000")
            width = 260
            height = 100
            corner = 10

            im = Image.new('RGBA', (width, height), wheat)
            draw = ImageDraw.Draw(im)

            # 1) Transparency
            mask = Image.new('L', im.size, color=0)
            mdraw = ImageDraw.Draw(mask)
            mdraw.rectangle((corner, 0, width - corner, height), fill=255)
            mdraw.rectangle((0, corner, width, height - corner), fill=255)
            mdraw.chord((0, 0, corner * 2, corner * 2), 0, 360, fill=255)
            mdraw.chord((0, height - corner * 2 - 1, corner * 2, height - 1),
                        0,
                        360,
                        fill=255)
            mdraw.chord((width - corner * 2 - 1, 0, width - 1, corner * 2),
                        0,
                        360,
                        fill=255)
            mdraw.chord((width - corner * 2 - 1, height - corner * 2 - 1,
                         width - 1, height - 1),
                        0,
                        360,
                        fill=255)
            im.putalpha(mask)

            # 2) Borders
            draw.arc((0, 0, corner * 2, corner * 2), 180, 270, fill=dark_wheat)
            draw.arc((0, height - corner * 2 - 1, corner * 2, height - 1),
                     90,
                     180,
                     fill=dark_wheat)
            draw.arc((width - corner * 2 - 1, 0, width, corner * 2),
                     270,
                     360,
                     fill=dark_wheat)
            draw.arc((width - corner * 2 - 1, height - corner * 2 - 1,
                      width - 1, height - 1),
                     0,
                     90,
                     fill=dark_wheat)
            draw.line((corner, 0, width - corner - 1, 0), fill=dark_wheat)
            draw.line((corner, height - 1, width - corner - 1, height - 1),
                      fill=dark_wheat)
            draw.line((0, corner, 0, height - corner - 1), fill=dark_wheat)
            draw.line((width - 1, corner, width - 1, height - corner - 1),
                      fill=dark_wheat)

            # 3) Logo
            logo = Image.open(self.logo_file)
            im.paste(logo, (4, 3),
                     logo)  # using the same image with transparencies as mask

            # 4) Current data
            draw.text((65, 5), self.station_name, fill=green)
            draw.text((65, 25),
                      "%0.1fC  %d%%  %0.1fKm/h  %dmb" % current[0],
                      fill=black)
            draw.text((65, 38), current[1], fill=dark_wheat)

            draw.text((6, 60),
                      " Today:   %4.1fC-%4.1fC  %4.1fKm/h  %5.1fl." %
                      self._calculateAggregData(self.accuD),
                      fill=dark_wheat)
            draw.text((6, 72),
                      " Monthly: %4.1fC-%4.1fC  %4.1fKm/h  %5.1fl." %
                      self._calculateAggregData(self.accuM),
                      fill=dark_wheat)
            draw.text((6, 84),
                      " Yearly:  %4.1fC-%4.1fC  %4.1fKm/h  %5.1fl." %
                      self._calculateAggregData(self.accuY),
                      fill=dark_wheat)

            # Save sticker
            im.save(self.filename)
            self.logger.info("Sticker generated")

            f = open(self.filename, "rb")
            d = f.read()
            f.close()

            return ['image/png', d]

        except Exception, e:
            self.logger.warning("Error rendering sticker: %s" % str(e))
            return None