diff --git a/helpers b/helpers index 1819df7..43e0d55 160000 --- a/helpers +++ b/helpers @@ -1 +1 @@ -Subproject commit 1819df790c0784473480dffe9aca8ca774d46343 +Subproject commit 43e0d556d1bbe6fed06bf5a90fa1bea8a8b2c81e diff --git a/rpi_envsens b/rpi_envsens index 5ffef82..a0bfadc 160000 --- a/rpi_envsens +++ b/rpi_envsens @@ -1 +1 @@ -Subproject commit 5ffef8254a0a035bc11ccefbd19497dd3969ac10 +Subproject commit a0bfadcce811fcf2190d830dddb717dabc07875e diff --git a/smarthome.py b/smarthome.py index afe690d..0e7c57b 100644 --- a/smarthome.py +++ b/smarthome.py @@ -5,6 +5,7 @@ import config from rpi_envsens.dht import dht_22 from rpi_envsens.bmp import bmp_180 +import helpers import garage_protocol import gui import logging @@ -54,13 +55,21 @@ class WetationFrameProt(gui.Wetation): PROT_ID_IN: [ { 'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST, - 'data_id': wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA, + 'data_id': wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT, + }, + { + 'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST, + 'data_id': wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP, }, ], PROT_ID_OUT: [ { 'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST, - 'data_id': wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA, + 'data_id': wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT, + }, + { + 'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST, + 'data_id': wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP, }, ], } @@ -141,8 +150,28 @@ class WetationFrameProt(gui.Wetation): if data is True: rv = True elif prot_id in [self.PROT_ID_IN, self.PROT_ID_OUT]: - if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA: - rv = isinstance(data.get(dht_22.KEY_TEMPERATURE), numbers.Number) and isinstance(data.get(dht_22.KEY_HUMIDITY), numbers.Number) and isinstance(data.get(bmp_180.KEY_PRESSURE), numbers.Number) + if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP: + rv = True + for main_key in [bmp_180.KEY_PRESSURE, bmp_180.KEY_TEMPERATURE, bmp_180.KEY_TIME]: + if main_key not in data: + rv = False + break + else: + for sub_key in ['mean', 'min_val', 'max_val', 'quantifier']: + if not isinstance(data[main_key].get(sub_key), numbers.Number): + rv = False + break + elif service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT: + rv = True + for main_key in [dht_22.KEY_HUMIDITY, dht_22.KEY_TEMPERATURE, dht_22.KEY_TIME]: + if main_key not in data: + rv = False + break + else: + for sub_key in ['mean', 'min_val', 'max_val', 'quantifier']: + if not isinstance(data[main_key].get(sub_key), numbers.Number): + rv = False + break if rv is False: logger.warning("Validation failed for message: prot_id=%s, service_id=%s, data_id=%s, data=%s", repr(prot_id), repr(service_id), repr(data_id), repr(data)) return rv @@ -172,19 +201,25 @@ class WetationFrameProt(gui.Wetation): elif service_id == garage_protocol.my_base_protocol_tcp.SID_EXECUTE_RESPONSE and data_id == garage_protocol.my_base_protocol_tcp.OPEN_CLOSE_GATE: return elif prot_id in [self.PROT_ID_IN, self.PROT_ID_OUT]: - if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA: + if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP: + logger.debug('Resetting GUI for prot_id %d, service_id=%d, data_id=%d', prot_id, service_id, data_id) + txt_pressure = '- hPa' + if prot_id == self.PROT_ID_IN: + self.in_pressure.SetLabel(txt_pressure) + else: + self.out_pressure.SetLabel(txt_pressure) + self.Layout() + return + elif service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT: logger.debug('Resetting GUI for prot_id %d, service_id=%d, data_id=%d', prot_id, service_id, data_id) txt_temperature = '-.- °C' txt_humidity = '-.- %' - txt_pressure = '- hPa' if prot_id == self.PROT_ID_IN: self.in_temperature.SetLabel(txt_temperature) self.in_humidity.SetLabel(txt_humidity) - self.in_pressure.SetLabel(txt_pressure) else: self.out_temperature.SetLabel(txt_temperature) self.out_humidity.SetLabel(txt_humidity) - self.out_pressure.SetLabel(txt_pressure) self.Layout() return logger.warning("Unknown response with no valid data for prot_id %d, service_id=%d, data_id=%d", prot_id, service_id, data_id) @@ -199,35 +234,49 @@ class WetationFrameProt(gui.Wetation): self.gate_close.Show(True) self.gate_position.SetValue(int(data * 100)) self.Layout() - return garage_protocol.my_base_protocol_tcp.STATUS_OKAY, None + return elif service_id == garage_protocol.my_base_protocol_tcp.SID_EXECUTE_RESPONSE and data_id == garage_protocol.my_base_protocol_tcp.OPEN_CLOSE_GATE: - return garage_protocol.my_base_protocol_tcp.STATUS_OKAY, None + return elif prot_id in [self.PROT_ID_IN, self.PROT_ID_OUT]: - if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA: - temp = data[dht_22.KEY_TEMPERATURE] + if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP: + data = helpers.continues_statistic_multivalue(**data) + # + # Current environmental data + if prot_id == self.PROT_ID_IN: + wx.CallAfter(self.update_current_bmp_env_data, data, self.in_pressure) + else: + wx.CallAfter(self.update_current_bmp_env_data, data, self.out_pressure) + return + elif service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT: + data = helpers.continues_statistic_multivalue(**data) + # + # Current environmental data + temp = data[dht_22.KEY_TEMPERATURE].mean if prot_id == self.PROT_ID_IN: if self.__max_temp_in__ is None or temp > self.__max_temp_in__: self.__max_temp_in__ = temp if self.__min_temp_in__ is None or temp < self.__min_temp_in__: self.__min_temp_in__ = temp - wx.CallAfter(self.update_current_env_data, data, self.in_temperature, self.in_humidity, self.in_pressure, self.in_temperature_min, self.in_temperature_max, self.__min_temp_in__, self.__max_temp_in__) + wx.CallAfter(self.update_current_dht_env_data, data, self.in_temperature, self.in_humidity, self.in_temperature_min, self.in_temperature_max, self.__min_temp_in__, self.__max_temp_in__) else: if self.__max_temp_out__ is None or temp > self.__max_temp_out__: self.__max_temp_out__ = temp if self.__min_temp_out__ is None or temp < self.__min_temp_out__: self.__min_temp_out__ = temp - wx.CallAfter(self.update_current_env_data, data, self.out_temperature, self.out_humidity, self.out_pressure, self.out_temperature_min, self.out_temperature_max, self.__min_temp_out__, self.__max_temp_out__) - return wetation_protocol.my_base_protocol_tcp.STATUS_OKAY, None + wx.CallAfter(self.update_current_dht_env_data, data, self.out_temperature, self.out_humidity, self.out_pressure, self.out_temperature_min, self.out_temperature_max, self.__min_temp_out__, self.__max_temp_out__) + return logger.warning("Unknown response with valid data for prot_id %d, service_id=%d, data_id=%d", prot_id, service_id, data_id) - return wetation_protocol.my_base_protocol_tcp.STATUS_SERVICE_OR_DATA_UNKNOWN, None - def update_current_env_data(self, env_data, temperature, humidity, pressure, temperature_min, temperature_max, value_min, value_max): + def update_current_bmp_env_data(self, env_data, pressure): + pressure.SetLabel('%.0f hPa' % env_data[bmp_180.KEY_PRESSURE].mean) + self.Layout() + + def update_current_dht_env_data(self, env_data, temperature, humidity, pressure, temperature_min, temperature_max, value_min, value_max): if isinstance(value_min, numbers.Number) and isinstance(value_max, numbers.Number): temperature_min.SetLabel('%.1f' % value_min) temperature_max.SetLabel('%.1f' % value_max) - temperature.SetLabel('%.1f °C' % env_data[dht_22.KEY_TEMPERATURE]) - humidity.SetLabel('%.1f %%' % env_data[dht_22.KEY_HUMIDITY]) - pressure.SetLabel('%.0f hPa' % env_data[bmp_180.KEY_PRESSURE]) + temperature.SetLabel('%.1f °C' % env_data[dht_22.KEY_TEMPERATURE].mean) + humidity.SetLabel('%.1f %%' % env_data[dht_22.KEY_HUMIDITY].mean) self.Layout() def update_time(self): @@ -236,8 +285,15 @@ class WetationFrameProt(gui.Wetation): self.Layout() def gate_oc_evt(self, event): - logger.debug("Gate open/close request") - self.__prot__[self.PROT_ID_GARAGE].send(garage_protocol.my_base_protocol_tcp.SID_EXECUTE_REQUEST, garage_protocol.my_base_protocol_tcp.OPEN_CLOSE_GATE, None) + r = wx.MessageDialog( + self, + "Soll das Garagentor betätigt werden?", + "Garage", + wx.YES_NO | wx.NO_DEFAULT | wx.ICON_WARNING + ).ShowModal() + if r == wx.ID_YES: + logger.debug("Gate open/close request") + self.__prot__[self.PROT_ID_GARAGE].send(garage_protocol.my_base_protocol_tcp.SID_EXECUTE_REQUEST, garage_protocol.my_base_protocol_tcp.OPEN_CLOSE_GATE, None) event.Skip() def reset_in_temp_minmax_evt(self, event): @@ -284,7 +340,7 @@ class MyApp(wx.App): if __name__ == "__main__": - report.appLoggingConfigure(os.path.dirname(__file__), config.LOGTARGET, config.loggers) + report.appLoggingConfigure(os.path.dirname(__file__), config.LOGTARGET, config.loggers, fmt=config.formatter) # app = MyApp(0) app.frame.run() diff --git a/wetation_protocol b/wetation_protocol index bc4808b..e9c6321 160000 --- a/wetation_protocol +++ b/wetation_protocol @@ -1 +1 @@ -Subproject commit bc4808b313ecebba6511b82c801eeadd95e8a503 +Subproject commit e9c6321772df731317b5398b624e10ff509d489b