def read(self): data_def = self.E2PROM.read(E2PROM_START_ADDRESS, E2PROM_OFFSET) if data_def is None: self.logger.warning("read: data_def is None, returning None") return None fixed_data = util.parse_data_def(data_def) if fixed_data is None: self.logger.warning("read: wrong fixed data, length: %d, [0]: %x [1]: %x, returning None", len(data_def), data_def[0], data_def[1]) return None if ((fixed_data['state']['current_pos'] > E2PROM_END_ADDRESS) or (fixed_data['state']['current_pos'] < E2PROM_START_VARIABLE) or (fixed_data['state']['current_pos'] % E2PROM_CHUNK_HALF != 0)): self.logger.warning("read: wrong cursor value %d, returning None", fixed_data['state']['current_pos']) self.logger.warning("read: previous cursor value %d", self.fixedPar['state']['current_pos']) return None if self.fixedPar['state']['current_pos'] != fixed_data['state']['current_pos']: old_pos = self.fixedPar['state']['current_pos'] self.dataDef = data_def self.fixedPar = fixed_data if ((fixed_data['state']['current_pos'] - old_pos > E2PROM_CHUNK_HALF) or (fixed_data['state']['current_pos'] == E2PROM_START_VARIABLE and old_pos != E2PROM_END_ADDRESS - E2PROM_CHUNK_HALF)): self.logger.warning('New pos (%d) distance not correct, previous pos (%d)', fixed_data['state']['current_pos'], self.fixedPar['state']['current_pos']) return None cursor = self.fixedPar['state']['current_pos'] if cursor < (E2PROM_END_ADDRESS - E2PROM_CHUNK_HALF): buf1, buf2 = self._get(cursor) if buf1 is None or buf2 is None: self.logger.warning("read: _get (1) returned None, cursor: %d, returning None", cursor) return None rec = util.parse_ws_record(buf1) else: cursor -= E2PROM_CHUNK_HALF self.logger.info('get_current_record: buffer end (%d)', cursor) buf1, buf2 = self._get(cursor) if buf1 is None or buf2 is None: self.logger.warning("read: _get (2) returned None, cursor: %d, returning None", cursor) return None rec = util.parse_ws_record(buf2) ts = datetime.now() rec['time_str'] = ts.isoformat() rec['time'] = util.msecs(ts) rec['cursor'] = cursor return rec
def sync(self): try: rec = self.ws.read() if rec is None: self.logger.warning("Sync, rec is none! Skipping...") return if rec['rain_total'] < self.init_rain: self.logger.warning("Sync, bad rain_total: %d, init_rain: %d", rec['rain_total'], self.init_rain) return if self.cl_min.count() == 0: # Collection is empty, first time usage self.logger.info("Update Total rain in ini file: from %.1f to %.1f" % (self.init_rain, rec['rain_total'])) self.init_rain = rec['rain_total'] # Update init vector and write for ini-file self.init["Init"]["Total rain"] = self.init_rain json.dump(self.init, open("ws.ini", "w"), indent=4) # init_rain is total accumulated rain since weather station reset, calculate the diff rec['rain_total'] = rec['rain_total'] - self.init_rain rec['rain'] = rec['rain_total'] - self.prev_rain self.prev_rain = rec['rain_total'] if not rec_ok(rec): self.logger.warning("Sync, bad rec! Skipping...") self.logger.warning("%s", json.dumps(rec, indent=4, separators=(',', ': '))) self.logger.warning("Sync, init_rain: %d prev_rain: %d", self.init_rain, self.prev_rain) return rec = init_rec(rec) self.cl_min.insert_one(rec) base_time = datetime.now() hour_stamp = base_time.replace(minute=0, second=0, microsecond=0) ts = util.msecs(hour_stamp) src_posts = self.cl_min.find({'time': {"$gte": ts}}) sum_post = posts_to_sum_post(src_posts, hour_stamp) self.cl_hourly.replace_one({'time': ts}, sum_post, upsert=True) day_stamp = base_time.replace(hour=0, minute=0, second=0, microsecond=0) ts = util.msecs(day_stamp) src_posts = self.cl_hourly.find({'time': {"$gte": ts}}) sum_post = posts_to_sum_post(src_posts, day_stamp) self.cl_daily.replace_one({'time': ts}, sum_post, upsert=True) month_stamp = base_time.replace(day=1, hour=0, minute=0, second=0, microsecond=0) ts = util.msecs(month_stamp) src_posts = self.cl_daily.find({'time': {"$gte": ts}}) sum_post = posts_to_sum_post(src_posts, month_stamp) self.cl_monthly.replace_one({'time': ts}, sum_post, upsert=True) year_stamp = base_time.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0) ts = util.msecs(year_stamp) src_posts = self.cl_monthly.find({'time': {"$gte": ts}}) sum_post = posts_to_sum_post(src_posts, year_stamp) self.cl_yearly.replace_one({'time': ts}, sum_post, upsert=True) # Remove old records self.cl_min.remove({'time': {"$lt": util.msecs(base_time) - ONE_HOUR}}) except errors.ServerSelectionTimeoutError, e: self.logger.warning("Mongo DB error in sync: %s" % e)
def posts_to_sum_post(posts, time_stamp): hum_in = [] hum_out = [] temp_in = [] temp_out = [] rain = [] rain_total = [] wind_dir = [] ave_wind_speed = [] gust_wind_speed = [] abs_pressure = [] for rec in posts: hum_in.append(rec['indoor_humidity']) hum_out.append(rec['outdoor_humidity']) temp_in.append(rec['indoor_temp']) temp_out.append(rec['outdoor_temp']) rain.append(rec['rain']) rain_total.append(rec['rain_total']) wind_dir.append(rec['wind_dir']) ave_wind_speed.append(rec['ave_wind_speed']) gust_wind_speed.append(rec['gust_wind_speed']) abs_pressure.append(rec['abs_pressure']) return { 'indoor_humidity': sum(hum_in) / len(hum_in), 'indoor_humidity_min': min(hum_in), 'indoor_humidity_max': max(hum_in), 'outdoor_humidity': sum(hum_out) / len(hum_out), 'outdoor_humidity_min': min(hum_out), 'outdoor_humidity_max': max(hum_out), 'indoor_temp': sum(temp_in) / len(temp_in), 'indoor_temp_min': min(temp_in), 'indoor_temp_max': max(temp_in), 'rain': sum(rain), 'rain_ave': sum(rain) / len(rain), 'rain_min': min(rain), 'rain_max': max(rain), 'rain_total': rain_total[-1], 'wind_dir': sum(wind_dir) / len(wind_dir), 'ave_wind_speed': sum(ave_wind_speed) / len(ave_wind_speed), 'ave_wind_speed_min': min(ave_wind_speed), 'ave_wind_speed_max': max(ave_wind_speed), 'gust_wind_speed': sum(gust_wind_speed) / len(gust_wind_speed), 'gust_wind_speed_min': min(gust_wind_speed), 'gust_wind_speed_max': max(gust_wind_speed), 'abs_pressure': sum(abs_pressure) / len(abs_pressure), 'abs_pressure_min': min(abs_pressure), 'abs_pressure_max': max(abs_pressure), 'time': util.msecs(time_stamp), 'time_str': time_stamp.isoformat(), 'latest_update': datetime.now().isoformat(), 'outdoor_temp': sum(temp_out) / len(temp_out), 'outdoor_temp_min': min(temp_out), 'outdoor_temp_max': max(temp_out) }
def read(self): data_def = self.E2PROM.read(E2PROM_START_ADDRESS, E2PROM_OFFSET) if data_def is None: self.logger.warning("read: data_def is None, returning None") return None fixed_data = util.parse_data_def(data_def) if fixed_data is None: self.logger.warning( "read: wrong fixed data, length: %d, [0]: %x [1]: %x, returning None", len(data_def), data_def[0], data_def[1]) return None if ((fixed_data['state']['current_pos'] > E2PROM_END_ADDRESS) or (fixed_data['state']['current_pos'] < E2PROM_START_VARIABLE) or (fixed_data['state']['current_pos'] % E2PROM_CHUNK_HALF != 0)): self.logger.warning("read: wrong cursor value %d, returning None", fixed_data['state']['current_pos']) self.logger.warning("read: previous cursor value %d", self.fixedPar['state']['current_pos']) return None if self.fixedPar['state']['current_pos'] != fixed_data['state'][ 'current_pos']: old_pos = self.fixedPar['state']['current_pos'] self.dataDef = data_def self.fixedPar = fixed_data if ((fixed_data['state']['current_pos'] - old_pos > E2PROM_CHUNK_HALF) or (fixed_data['state']['current_pos'] == E2PROM_START_VARIABLE and old_pos != E2PROM_END_ADDRESS - E2PROM_CHUNK_HALF)): self.logger.warning( 'New pos (%d) distance not correct, previous pos (%d)', fixed_data['state']['current_pos'], self.fixedPar['state']['current_pos']) return None cursor = self.fixedPar['state']['current_pos'] if cursor < (E2PROM_END_ADDRESS - E2PROM_CHUNK_HALF): buf1, buf2 = self._get(cursor) if buf1 is None or buf2 is None: self.logger.warning( "read: _get (1) returned None, cursor: %d, returning None", cursor) return None rec = util.parse_ws_record(buf1) else: cursor -= E2PROM_CHUNK_HALF self.logger.info('get_current_record: buffer end (%d)', cursor) buf1, buf2 = self._get(cursor) if buf1 is None or buf2 is None: self.logger.warning( "read: _get (2) returned None, cursor: %d, returning None", cursor) return None rec = util.parse_ws_record(buf2) ts = datetime.now() rec['time_str'] = ts.isoformat() rec['time'] = util.msecs(ts) rec['cursor'] = cursor return rec