def get_gts(self, obs_type, sod_ts, soy_ts): """ read GTS value out of the array """ if obs_type == 'GTS': # Gruenlandtemperatursumme GTS try: if soy_ts is None or soy_ts not in self.gts_values: __x = None else: __x = self.gts_values[soy_ts][dayOfGTSYear(sod_ts, soy_ts)] return weewx.units.ValueTuple(__x, 'degree_C_day', 'group_degree_day') except (ValueError, TypeError, IndexError, KeyError): logerr("soy_ts=%s sod_ts=%s" % (soy_ts, sod_ts)) raise weewx.CannotCalculate(obs_type) elif obs_type == 'GTSdate': # date of value 200 if soy_ts is None or soy_ts not in self.gts_date: return weewx.units.ValueTuple(None, 'unix_epoch', 'group_time') else: return weewx.units.ValueTuple(self.gts_date[soy_ts], 'unix_epoch', 'group_time') else: # unknown type (should not happen here) raise weewx.UnknownType(obs_type)
def add_record(self, record): """Add a new record, then return the difference in value divided by the difference in time.""" # If the type does not appear in the incoming record, then we can't calculate the derivative if self.obs_type not in record: raise weewx.CannotCalculate(self.obs_type) derivative = None if record[self.obs_type] is not None: # We can't calculate anything if we don't have an old record if self.old_timestamp: # Check to make sure the incoming record is later than the retained record if record['dateTime'] < self.old_timestamp: raise weewx.ViolatedPrecondition( "Records presented out of order (%s vs %s)" % (record['dateTime'], self.old_timestamp)) # Calculate the time derivative only if the old record is not too old. if record['dateTime'] - self.old_timestamp <= self.stale_age: # It's OK. derivative = (record[self.obs_type] - self.old_value) / ( record['dateTime'] - self.old_timestamp) # Save the current values self.old_timestamp = record['dateTime'] self.old_value = record[self.obs_type] return derivative
def get_scalar(self, obs_type, record, db_manager): # We only know how to calculate 'vapor_p'. For everything else, raise an exception if obs_type != 'vapor_p': raise weewx.UnknownType(obs_type) # We need outTemp in order to do the calculation. if 'outTemp' not in record or record['outTemp'] is None: raise weewx.CannotCalculate(obs_type) # We have everything we need. Start by forming a ValueTuple for the outside temperature. # To do this, figure out what unit and group the record is in ... unit_and_group = weewx.units.getStandardUnitType(record['usUnits'], 'outTemp') # ... then form the ValueTuple. outTemp_vt = weewx.units.ValueTuple(record['outTemp'], *unit_and_group) # We need the temperature in Kelvin outTemp_K_vt = weewx.units.convert(outTemp_vt, 'degree_K') # Now we can use the formula. Results will be in mmHg. Create a ValueTuple out of it: p_vt = weewx.units.ValueTuple(math.exp(20.386 - 5132.0 / outTemp_K_vt[0]), 'mmHg', 'group_pressure') # We have the vapor pressure as a ValueTuple. Convert it back to the units used by # the incoming record and return it return weewx.units.convertStd(p_vt, record['usUnits'])
def get_scalar(obs_type, record, db_manager=None): log.debug('get_scalar(%s)' % obs_type) if obs_type not in [ 'pm2_5_aqi', 'pm2_5_aqi_color', 'pm2_5_lrapa', 'pm2_5_lrapa_aqi', 'pm2_5_lrapa_aqi_color', 'pm2_5_unbc', 'pm2_5_unbc_aqi', 'pm2_5_unbc_aqi_color' ]: raise weewx.UnknownType(obs_type) log.debug('get_scalar(%s)' % obs_type) if record is None: log.debug('get_scalar called where record is None.') raise weewx.CannotCalculate(obs_type) if 'pm2_5' not in record: log.info('get_scalar called where record does not contain pm2_5.') raise weewx.CannotCalculate(obs_type) if record['pm2_5'] is None: log.info('get_scalar called where record[pm2_5] is None.') raise weewx.CannotCalculate(obs_type) try: pm2_5 = record['pm2_5'] if obs_type == 'pm2_5_aqi': value = AQI.compute_pm2_5_aqi(pm2_5) if obs_type == 'pm2_5_aqi_color': value = AQI.compute_pm2_5_aqi_color( AQI.compute_pm2_5_aqi(pm2_5)) elif obs_type == 'pm2_5_lrapa': value = AQI.compute_pm2_5_lrapa(pm2_5) elif obs_type == 'pm2_5_lrapa_aqi': pm2_5_lrapa = AQI.compute_pm2_5_lrapa(pm2_5) value = AQI.compute_pm2_5_aqi(pm2_5_lrapa) elif obs_type == 'pm2_5_lrapa_aqi_color': value = AQI.compute_pm2_5_aqi_color( AQI.compute_pm2_5_aqi(AQI.compute_pm2_5_lrapa(pm2_5))) elif obs_type == 'pm2_5_unbc': value = AQI.compute_pm2_5_unbc(pm2_5) elif obs_type == 'pm2_5_unbc_aqi': pm2_5_unbc = AQI.compute_pm2_5_unbc(pm2_5) value = AQI.compute_pm2_5_aqi(pm2_5_unbc) elif obs_type == 'pm2_5_unbc_aqi_color': value = AQI.compute_pm2_5_aqi_color( AQI.compute_pm2_5_aqi(AQI.compute_pm2_5_unbc(pm2_5))) t, g = weewx.units.getStandardUnitType(record['usUnits'], obs_type) # Form the ValueTuple and return it: return weewx.units.ValueTuple(value, t, g) except KeyError: # Don't have everything we need. Raise an exception. raise weewx.CannotCalculate(obs_type)
def calc_GDD_integral(self, obs_type, timespan, db_manager, base_t, limit_t, stop_t): """ calculate growing degree days as integral over time""" try: # make sure limit_t and stop_t are not None if not limit_t: limit_t = 1000.0 if not stop_t: stop_t = 1000.0 logdbg("GDD integral base=%s limit=%s stop=%s" % (base_t, limit_t, stop_t)) # maximum growing degree value __gdlimit = limit_t - base_t # query data base and calculate integral _result = db_manager.getSql( 'SELECT sum(' ' CASE' ' WHEN `%s`>%.1f THEN 0.0' ' WHEN `%s`>%.1f THEN %.1f' ' WHEN `%s`<%.1f THEN 0.0' ' ELSE `%s`-%.1f' ' END*`interval`/1440.0),' ' MIN(usUnits),MAX(usUnits) ' 'FROM %s ' 'WHERE dateTime>? AND dateTime<=?' % (obs_type, stop_t, obs_type, limit_t, __gdlimit, obs_type, base_t, obs_type, base_t, db_manager.table_name), timespan) if _result is None: raise weewx.CannotCalculate( "calculate GDD: no temperature data in database") if _result[0] is not None: if not _result[1] == _result[2]: raise weewx.CannotCalculate( "calculate GDD: inconsistent units") _unit, _ugroup = weewx.units.getStandardUnitType( _result[1], obs_type, 'GDD') logdbg("GDD integral unit=%s unitgroup=%s" % (_unit, _ugroup)) return weewx.units.ValueTuple(_result[0], _unit, _ugroup) except weedb.OperationalError as e: raise weewx.CannotCalculate( "calculate GDD integral: Database OperationalError '%s'" % e) except (ValueError, TypeError) as e: raise weewx.CannotCalculate("calculate GDD integral: %s" % e) return None
def get_scalar(self, obs_type, record, db_manager): # We only know how to calculate 'makkink'. For everything else, raise an exception UnknownType if obs_type != 'makkink': raise weewx.UnknownType(obs_type) # We need outTemp and the radiation in order to do the calculation. if 'outTemp' not in record or record['outTemp'] is None: raise weewx.CannotCalculate(obs_type) if 'radiation' not in record or record['radiation'] is None: raise weewx.CannotCalculate(obs_type) # We have everything we need. Start by forming a ValueTuple for the outside temperature. # To do this, figure out what unit and group the record is in ... unit_and_group = weewx.units.getStandardUnitType( record['usUnits'], 'outTemp') # ... then form the ValueTuple. outTemp_vt = ValueTuple(record['outTemp'], *unit_and_group) # same for radiation unit_and_group = weewx.units.getStandardUnitType( record['usUnits'], 'radiation') # ... then form the ValueTuple. radiation_vt = ValueTuple(record['radiation'], *unit_and_group) outTemp_C_vt = weewx.units.convert(outTemp_vt, 'degree_C') # Get the first element of the ValueTuple. This will be in Celsius: T = outTemp_C_vt[0] # just to make sure nothing fancy happens we do this for radiation as well # even though this is W/m2 in us as well as metric radiation_Wm2_vt = weewx.units.convert(radiation_vt, 'watt_per_meter_squared') Kin = radiation_Wm2_vt[0] makkink = ValueTuple( self.Eref(T, Kin) * 3600, 'mm_per_hour', 'group_rainrate') # convert from kg/m2*s --> mm/hour # Convert it back to the units used by # the incoming record and return it return weewx.units.convertStd(makkink, record['usUnits'])
def get_scalar(self, obs_type, record, db_manager): # We only know how to calculate 'vapor_p'. For everything else, raise an exception UnknownType if obs_type != 'vapor_p': raise weewx.UnknownType(obs_type) # We need outTemp in order to do the calculation. if 'outTemp' not in record or record['outTemp'] is None: raise weewx.CannotCalculate(obs_type) # We have everything we need. Start by forming a ValueTuple for the outside temperature. # To do this, figure out what unit and group the record is in ... unit_and_group = weewx.units.getStandardUnitType( record['usUnits'], 'outTemp') # ... then form the ValueTuple. outTemp_vt = ValueTuple(record['outTemp'], *unit_and_group) # Both algorithms need temperature in Celsius, so let's make sure our incoming temperature # is in that unit. Use function convert(). The results will be in the form of a ValueTuple outTemp_C_vt = weewx.units.convert(outTemp_vt, 'degree_C') # Get the first element of the ValueTuple. This will be in Celsius: outTemp_C = outTemp_C_vt[0] if self.algorithm == 'simple': # Use the "Simple" algorithm. # We need temperature in Kelvin. outTemp_K = weewx.units.CtoK(outTemp_C) # Now we can use the formula. Results will be in mmHg. Create a ValueTuple out of it: p_vt = ValueTuple(math.exp(20.386 - 5132.0 / outTemp_K), 'mmHg', 'group_pressure') elif self.algorithm == 'tetens': # Use Teten's algorithm. # Use the formula. Results will be in kPa: p_kPa = 0.61078 * math.exp(17.27 * outTemp_C_vt[0] / (outTemp_C_vt[0] + 237.3)) # Form a ValueTuple p_vt = ValueTuple(p_kPa, 'kPa', 'group_pressure') else: # Don't recognize the exception. Fail hard: raise ValueError(self.algorithm) # We have the vapor pressure as a ValueTuple. Convert it back to the units used by # the incoming record and return it return weewx.units.convertStd(p_vt, record['usUnits'])
def get_aggregate(self, obs_type, timespan, aggregate_type, db_manager, **option_dict): if obs_type is None: raise weewx.UnknownType("obs_type is None") # time offset of local mean time (LMT) if obs_type == 'utcoffsetLMT': return weewx.units.ValueTuple( self.lmt_tz.utcoffset(None).total_seconds(), 'second', 'group_deltatime') # energy_integral can be calculated for group_radiation observation # types like 'radiation' and 'maxSolarRad' if aggregate_type == 'energy_integral': if obs_type in weewx.units.obs_group_dict and weewx.units.obs_group_dict[ obs_type] == 'group_radiation': return self.calc_radiation_integral(obs_type, timespan, db_manager) # growing degree days == Wachstumsgradtage # https://de.wikipedia.org/wiki/Wachstumsgradtag # https://en.wikipedia.org/wiki/Growing_degree-day if aggregate_type in ['growdeg', 'GDD']: # growing degree day can only be calculated for a temperature if weewx.units.obs_group_dict.get(obs_type, '') != 'group_temperature': raise weewx.CannotCalculate( "%s is not temperature for aggregation %s" % (obs_type, aggregate_type)) # if the base value is defined in skin.conf or weewx.conf, get # it for default units_dict = option_dict.get('skin_dict', {}).get('Units', {}) dd_dict = units_dict.get('DegreeDays', {}) base_vt = dd_dict.get( 'growing_base', weewx.xtypes.AggregateHeatCool.default_growbase) # if parameters are specified get them val = option_dict.get('val') #loginf("%s" % type(val)) #loginf(val) if val: # GDD with parameters try: # dict method = val.get('method', 'integral') base_vt = val.get('base', base_vt) limit_vt = val.get('limit', self.GDD_LIMIT_VT) stop_vt = val.get('stop') except TypeError: # tuple used as base temperature base_vt = weewx.units.ValueTuple(float(val[0]), val[1], 'group_temperature') limit_vt = None stop_vt = None method = 'integral' else: # GDD alone: use defaults method = 'integral' limit_vt = self.GDD_LIMIT_VT stop_vt = None # Convert to a ValueTuple in the same unit system as the database __base = weewx.units.convertStd( (float(base_vt[0]), base_vt[1], 'group_temperature'), db_manager.std_unit_system)[0] if limit_vt: try: __limit = weewx.units.convertStd( (float(limit_vt[0]), limit_vt[1], 'group_temperature'), db_manager.std_unit_system)[0] except IndexError: if limit_vt.lower() == 'none': __limit = None else: __limit = None if stop_vt: try: __stop = weewx.units.convertStd( (float(stop_vt[0]), stop_vt[1], 'group_temperature'), db_manager.std_unit_system)[0] except IndexError: if stop_vt.lower() == 'none': __stop = None else: __stop = None #loginf("method %s" % method) #loginf(base_vt) #loginf(limit_vt) # calculate GDD sum if method == 'integral': # integral over timespan return self.calc_GDD_integral(obs_type, timespan, db_manager, __base, __limit, __stop) if method in ['hiloavgA', 'hiloavgB', 'dayavg']: # based on daily average or average of high and low. # Check if day border should be based on Local Mean Time # or local timezone time __lmt_tz = option_dict.get('LMT', {}).get('timezone') if __lmt_tz is None: __lmt_tz = option_dict.get('dayboundary', {}).get('timezone') return self.calc_GDD_avg(obs_type, timespan, db_manager, method, __base, __limit, __stop, __lmt_tz) if method == 'weewx' and obs_type == 'outTemp': # call builtin method of WeeWX for outTemp return weewx.xtypes.get_aggregate('growdeg', timespan, 'sum', db_manager, **option_dict) raise weewx.CannotCalculate("GDD %s: unknown method" % method) # accumulated growing degree days if obs_type == 'yearGDD' or obs_type == 'seasonGDD': #loginf("GDD %s" % option_dict) #loginf("GDD %s" % aggregate_type) if aggregate_type.lower() == 'avg': if timespan.start > time.time() or ( timespan.start + timespan.stop) / 2 > time.time() + 90000: return weewx.units.ValueTuple(None, 'degree_C_day', 'group_degree_days') return self.get_scalar( obs_type, {'dateTime': (timespan.start + timespan.stop) / 2}, db_manager, **option_dict) if aggregate_type.lower() == 'last': return self.get_scalar(obs_type, {'dateTime': timespan.stop}, db_manager, **option_dict) raise weewx.UnknownAggregation("%s undefinded aggregation %s" % (obs_type, aggregation_type)) # This function handles 'GTS' and 'GTSdate'. if obs_type != 'GTS' and obs_type != 'GTSdate': raise weewx.UnknownType(obs_type) # aggregation types that are defined for those values if aggregate_type not in [ 'avg', 'max', 'min', 'last', 'maxtime', 'mintime', 'lasttime' ]: raise weewx.UnknownAggregation("%s undefinded aggregation %s" % (obs_type, aggregation_type)) if timespan is None: raise weewx.CannotCalculate("%s %s no timespan" % (obs_type, aggregate_type)) if db_manager is None: if self.db_manager_ok: logerr("%s: no database reference" % obs_type) self.db_manager_ok = False raise weewx.CannotCalculate("%s: no database reference" % obs_type) # needed timestamps _soya_ts = startOfYearTZ(timespan.start + 1, self.lmt_tz) _soye_ts = startOfYearTZ(timespan.stop, self.lmt_tz) # calculate GTS values for the years included in timespan # (if time span is within the current year, the # value is calculated up to the current day (today)) __max = 0 __maxtime = None __min = 10000000 __mintime = None __ts = _soya_ts # Even if the time span starts after May 31st, the end value # is needed for some aggregations. So we have to calculate # that year, too. while __ts <= _soye_ts: # calculate GTS values for the year self.calc_gts(__ts, db_manager) # update minimum and maximum if __ts in self.gts_values: for __i, __val in enumerate(self.gts_values[__ts]): if __val is not None and __val > __max: __max = __val __maxtime = __ts + __i * 86400 if __val is not None and __val < __min: __min = __val __mintime = __ts + __i * 86400 # next year __ts = startOfYearTZ(__ts + 31708800, self.lmt_tz) if obs_type == 'GTS': if aggregate_type == 'avg': # 1 day is 86400s, but once a year it is 90000s or 82800s # when the daylight savings time is switched on or off. if timespan.stop - timespan.start <= 90000: __a = startOfDayTZ(timespan.start, _soya_ts) __b = startOfDayTZ(timespan.stop, _soye_ts) if __a != __b: # begin and end of timespan are different days # according to timezone self.lmt_tz # timespan.start <= __b <= timespan.stop if __b - timespan.start > timespan.stop - __b: __b = __a _soye_ts = _soya_ts if __b >= _soye_ts + 13046400: __x = weewx.units.ValueTuple(None, 'degree_C_day', 'group_degree_day') else: __x = self.get_gts(obs_type, __b, _soye_ts) elif _soya_ts == _soye_ts and _soya_ts in self.gts_values: # timespan within the same year but more than one day # (not much use, but calculated anyway) __a = dayOfGTSYear(timespan.start, _soya_ts) __b = dayOfGTSYear(timespan.stop, _soye_ts) if __a == __b: __x = self.gts_values[_soya_ts][__a] else: __x = 0 for __i in xrange(__a, __b): if self.gts_values[_soya_ts][__i] is not None: __x += self.gts_values[_soya_ts][__i] __x /= __b - __a else: raise weewx.CannotCalculate( "%s %s invalid timespan %s %s" % (obs_type, aggregate_type, timespan.stop - timespan.start, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timespan.start)))) elif aggregate_type == 'lasttime': if timespan.stop >= self.last_gts_date: # today or in future __ts = self.last_gts_date else: # before today if _soye_ts not in self.gts_values: raise weewx.CannotCalculate("%s %s" % (obs_type, aggregate_type)) __ts = dayOfGTSYear(timespan.stop, _soye_ts) for __i, __v in reversed( enumerate(self.gts_values[_soye_ts])): if __v is not None and __i <= __ts: __ts = _soye_ts + 86400 * __i break else: __ts = _soye_ts __x = weewx.units.ValueTuple(__ts, 'unix_epoch', 'group_time') elif aggregate_type == 'last': if timespan.stop >= _soye_ts + 13046400: # after May 31st __ts = _soye_ts + 13046400 - 86400 else: # between Jan 1st and May 31st __ts = startOfDayTZ(timespan.stop, _soye_ts) # startOfDay() returns for 24:00 the start of the # next day. So we need to look for the day before. if __ts == timespan.stop: __ts -= 86400 # for today there is no value so far if __ts == startOfDayTZ(time.time(), _soye_ts): __ts -= 86400 __x = self.get_gts(obs_type, __ts, _soye_ts) elif aggregate_type == 'max': __x = weewx.units.ValueTuple(__max, 'degree_C_day', 'group_degree_day') elif aggregate_type == 'maxtime': __x = weewx.units.ValueTuple(__maxtime, 'unix_epoch', 'group_time') elif aggregate_type == 'min': __x = weewx.units.ValueTuple(__min, 'degree_C_day', 'group_degree_day') elif aggregate_type == 'mintime': __x = weewx.units.ValueTuple(__mintime, 'unix_epoch', 'group_time') else: raise weewx.CannotCalculate("%s %s" % (obs_type, aggregate_type)) """ try: a=str(__x[0]) except: logerr("get_aggregate 0") a="" try: b=str(__x[1]) except: logerr("get_aggregate 1") b="" try: c=str(__x[2]) except: logerr("get_aggregate 2") c="" loginf("get_aggregate %s,%s,%s" % (a,b,c)) """ return __x if obs_type == 'GTSdate': if aggregate_type == 'last' or aggregate_type == 'max': if _soye_ts in self.gts_date and self.gts_date[ _soye_ts] is not None and timespan.stop >= self.gts_date[ _soye_ts]: __x = self.gts_date[_soye_ts] else: __x = None return weewx.units.ValueTuple(__x, 'unix_epoch', 'group_time') raise weewx.CannotCalculate("%s %s" % (obs_type, aggregate_type))
def get_scalar(self, obs_type, record, db_manager, **option_dict): """ mandatory function to be defined for XType extensions """ if obs_type is None: raise weewx.UnknownType("obs_type is None") # time offset of local mean time (LMT) if obs_type == 'utcoffsetLMT': return weewx.units.ValueTuple( self.lmt_tz.utcoffset(None).total_seconds(), 'second', 'group_deltatime') # dateTime as string in local mean time if obs_type == 'LMTtime': if record is None: raise weewx.UnknownType("%s: no record" % obs_type) return weewx.units.ValueTuple( datetime.datetime.fromtimestamp( record['dateTime'], self.lmt_tz).strftime("%H:%M:%S"), 'unix_epoch', 'group_time') # This functions handles 'GTS' and 'GTSdate'. if obs_type not in [ 'GTS', 'GTSdate', 'dayET', 'ET24', 'yearGDD', 'seasonGDD' ]: raise weewx.UnknownType(obs_type) #if record is None: # if self.record_ok: # logerr("%s: no record (logged only once)" % obs_type) # self.record_ok=False # raise weewx.CannotCalculate("%s: no record" % obs_type) if db_manager is None: if self.db_manager_ok: logerr("%s: db_manager is None" & obs_type) self.db_manager_ok = False raise weewx.CannotCalculate("%s: no database reference" % obs_type) #logdbg("obs_type=%s" % obs_type) # needed timestamps if record is not None and 'dateTime' in record: _time_ts = record['dateTime'] else: # that should never happen but does due to a bug in # Belchertown skin if self.record_ok: logerr("%s: no record (logged only once)" % obs_type) self.record_ok = False # to do something we deliver the last available value _time_ts = time.time() if obs_type == 'dayET': # dayET should be comparable to dayRain, so use the same # time span: not local mean time but archive time try: # startOfArchiveDay() considers midnight belonging # to the previous day. So the time span would be # always greater than 0. __x = weeutil.weeutil.startOfArchiveDay(_time_ts) __x = weeutil.weeutil.TimeSpan(__x, _time_ts) except (ValueError, TypeError, IndexError): raise weewx.CannotCalculate("dayET: invalid time") return weewx.xtypes.get_aggregate('ET', __x, 'sum', db_manager) if obs_type == 'ET24': try: __x = weeutil.weeutil.TimeSpan(_time_ts - 86400, _time_ts) except: raise weewx.CannotCalculate("ET24: invalid time") return weewx.xtypes.get_aggregate('ET', __x, 'sum', db_manager) _soy_ts = startOfYearTZ(_time_ts, self.lmt_tz) _sod_ts = startOfDayTZ(_time_ts, _soy_ts) # start of day # If the start of the year in question is before the first # record in the database, no value can be calculated. The # same applies if the given timestamp is in future. #if _soy_ts<db_manager.first_timestamp or _sod_ts>db_manager.last_timestamp: # raise weewx.CannotCalculate(obs_type) # growing degree days == Wachstumsgradtage # https://de.wikipedia.org/wiki/Wachstumsgradtag # https://en.wikipedia.org/wiki/Growing_degree-day if obs_type in ['yearGDD']: try: # calculate from the beginning of the year up to the # end of the current day __timespan = TimeSpan(_soy_ts, _sod_ts + 86400) return self.get_aggregate('outTemp', __timespan, 'GDD', db_manager, **option_dict) except (ValueError, TypeError, IndexError, KeyError): raise weewx.CannotCalculate("%s" % obs_type) # calculate GTS values for the given year # (if record['dateTime'] is within the current year, the # value is calculated up to the current day (today)) self.calc_gts(_soy_ts, db_manager) # growing degree days == Wachstumsgradtage # https://de.wikipedia.org/wiki/Wachstumsgradtag # https://en.wikipedia.org/wiki/Growing_degree-day if obs_type in ['seasonGDD']: try: # calculate from the beginning of the year up to the # end of the current day __start_ts = self.gts_date[_soy_ts] if __start_ts and _sod_ts >= __start_ts and _sod_ts < _soy_ts + 26179200: __timespan = TimeSpan(__start_ts, _sod_ts + 86400) return self.get_aggregate('outTemp', __timespan, 'GDD', db_manager, **option_dict) except (ValueError, TypeError, IndexError, KeyError): #raise weewx.CannotCalculate("%s" % obs_type) pass return weewx.units.ValueTuple(None, 'degree_C_day', 'group_degree_day') # check if the requested timestamp record['dateTime'] is within # the current day (today) # Note: After self.calc_gts() is run, self.last_gts_date # points to the beginning of the current day, if # record['dateTime'] is within the current year. # if record['dateTime'] is _not_ within the current # year, self.last_gts_date _may_ be None. if record is None: # record is not provided, we assume the actual time # Note: That should not happen but does due to a bug in # Belchertown skin if _sod_ts != self.last_gts_date: raise weewx.CannotCalculate("%s: no record" % obs_type) __today = True elif self.last_gts_date is None or self.gts_value is None: # The current year is not calculated so far, that means, # record['dateTime'] cannot be within the current day (today). __today = False elif _time_ts <= self.last_gts_date: # record['dateTime'] is before self.last_gts_date. # As self.last_gts_date points to the beginning of # the current day, that means, record['dateTime'] is not # the current day (today). __today = False else: # record['dateTime'] is after the beginning of the # current day. If it is additionally before # self.last_gts_date+86400 (1d after), it is within # the current day (today). __today = _time_ts <= self.last_gts_date + 86400 # get the result if __today: # current value if obs_type == 'GTS': # current GTS value __x = weewx.units.ValueTuple(self.gts_value, 'degree_C_day', 'group_degree_day') elif obs_type == 'GTSdate': # current GTSdate value or None, if GTS<200 if _soy_ts in self.gts_date: __x = self.gts_date[_soy_ts] else: __x = None __x = weewx.units.ValueTuple(__x, 'unix_epoch', 'group_time') else: # should not occure raise weewx.CannotCalculate(obs_type) else: # value from memory __x = self.get_gts(obs_type, _sod_ts, _soy_ts) """ try: a=str(__x[0]) except: logerr("get_scalar 0") a="" try: b=str(__x[1]) except: logerr("get_scalar 1") b="" try: c=str(__x[2]) except: logerr("get_scalar 2") c="" loginf("get_scalar %s,%s,%s" % (a,b,c)) """ if record is None: return __x return weewx.units.convertStd(__x, record['usUnits'])