|
@@ -5,6 +5,7 @@
|
5
|
5
|
import config
|
6
|
6
|
from rpi_envsens.dht import dht_22
|
7
|
7
|
from rpi_envsens.bmp import bmp_180
|
|
8
|
+import helpers
|
8
|
9
|
import garage_protocol
|
9
|
10
|
import gui
|
10
|
11
|
import logging
|
|
@@ -54,13 +55,21 @@ class WetationFrameProt(gui.Wetation):
|
54
|
55
|
PROT_ID_IN: [
|
55
|
56
|
{
|
56
|
57
|
'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
57
|
|
- 'data_id': wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA,
|
|
58
|
+ 'data_id': wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT,
|
|
59
|
+ },
|
|
60
|
+ {
|
|
61
|
+ 'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
|
62
|
+ 'data_id': wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP,
|
58
|
63
|
},
|
59
|
64
|
],
|
60
|
65
|
PROT_ID_OUT: [
|
61
|
66
|
{
|
62
|
67
|
'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
63
|
|
- 'data_id': wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA,
|
|
68
|
+ 'data_id': wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT,
|
|
69
|
+ },
|
|
70
|
+ {
|
|
71
|
+ 'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
|
72
|
+ 'data_id': wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP,
|
64
|
73
|
},
|
65
|
74
|
],
|
66
|
75
|
}
|
|
@@ -141,8 +150,28 @@ class WetationFrameProt(gui.Wetation):
|
141
|
150
|
if data is True:
|
142
|
151
|
rv = True
|
143
|
152
|
elif prot_id in [self.PROT_ID_IN, self.PROT_ID_OUT]:
|
144
|
|
- if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA:
|
145
|
|
- 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)
|
|
153
|
+ if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP:
|
|
154
|
+ rv = True
|
|
155
|
+ for main_key in [bmp_180.KEY_PRESSURE, bmp_180.KEY_TEMPERATURE, bmp_180.KEY_TIME]:
|
|
156
|
+ if main_key not in data:
|
|
157
|
+ rv = False
|
|
158
|
+ break
|
|
159
|
+ else:
|
|
160
|
+ for sub_key in ['mean', 'min_val', 'max_val', 'quantifier']:
|
|
161
|
+ if not isinstance(data[main_key].get(sub_key), numbers.Number):
|
|
162
|
+ rv = False
|
|
163
|
+ break
|
|
164
|
+ elif service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT:
|
|
165
|
+ rv = True
|
|
166
|
+ for main_key in [dht_22.KEY_HUMIDITY, dht_22.KEY_TEMPERATURE, dht_22.KEY_TIME]:
|
|
167
|
+ if main_key not in data:
|
|
168
|
+ rv = False
|
|
169
|
+ break
|
|
170
|
+ else:
|
|
171
|
+ for sub_key in ['mean', 'min_val', 'max_val', 'quantifier']:
|
|
172
|
+ if not isinstance(data[main_key].get(sub_key), numbers.Number):
|
|
173
|
+ rv = False
|
|
174
|
+ break
|
146
|
175
|
if rv is False:
|
147
|
176
|
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))
|
148
|
177
|
return rv
|
|
@@ -172,19 +201,25 @@ class WetationFrameProt(gui.Wetation):
|
172
|
201
|
elif service_id == garage_protocol.my_base_protocol_tcp.SID_EXECUTE_RESPONSE and data_id == garage_protocol.my_base_protocol_tcp.OPEN_CLOSE_GATE:
|
173
|
202
|
return
|
174
|
203
|
elif prot_id in [self.PROT_ID_IN, self.PROT_ID_OUT]:
|
175
|
|
- if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA:
|
|
204
|
+ if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP:
|
|
205
|
+ logger.debug('Resetting GUI for prot_id %d, service_id=%d, data_id=%d', prot_id, service_id, data_id)
|
|
206
|
+ txt_pressure = '- hPa'
|
|
207
|
+ if prot_id == self.PROT_ID_IN:
|
|
208
|
+ self.in_pressure.SetLabel(txt_pressure)
|
|
209
|
+ else:
|
|
210
|
+ self.out_pressure.SetLabel(txt_pressure)
|
|
211
|
+ self.Layout()
|
|
212
|
+ return
|
|
213
|
+ elif service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT:
|
176
|
214
|
logger.debug('Resetting GUI for prot_id %d, service_id=%d, data_id=%d', prot_id, service_id, data_id)
|
177
|
215
|
txt_temperature = '-.- °C'
|
178
|
216
|
txt_humidity = '-.- %'
|
179
|
|
- txt_pressure = '- hPa'
|
180
|
217
|
if prot_id == self.PROT_ID_IN:
|
181
|
218
|
self.in_temperature.SetLabel(txt_temperature)
|
182
|
219
|
self.in_humidity.SetLabel(txt_humidity)
|
183
|
|
- self.in_pressure.SetLabel(txt_pressure)
|
184
|
220
|
else:
|
185
|
221
|
self.out_temperature.SetLabel(txt_temperature)
|
186
|
222
|
self.out_humidity.SetLabel(txt_humidity)
|
187
|
|
- self.out_pressure.SetLabel(txt_pressure)
|
188
|
223
|
self.Layout()
|
189
|
224
|
return
|
190
|
225
|
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):
|
199
|
234
|
self.gate_close.Show(True)
|
200
|
235
|
self.gate_position.SetValue(int(data * 100))
|
201
|
236
|
self.Layout()
|
202
|
|
- return garage_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
237
|
+ return
|
203
|
238
|
elif service_id == garage_protocol.my_base_protocol_tcp.SID_EXECUTE_RESPONSE and data_id == garage_protocol.my_base_protocol_tcp.OPEN_CLOSE_GATE:
|
204
|
|
- return garage_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
239
|
+ return
|
205
|
240
|
elif prot_id in [self.PROT_ID_IN, self.PROT_ID_OUT]:
|
206
|
|
- if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA:
|
207
|
|
- temp = data[dht_22.KEY_TEMPERATURE]
|
|
241
|
+ if service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_BMP:
|
|
242
|
+ data = helpers.continues_statistic_multivalue(**data)
|
|
243
|
+ #
|
|
244
|
+ # Current environmental data
|
|
245
|
+ if prot_id == self.PROT_ID_IN:
|
|
246
|
+ wx.CallAfter(self.update_current_bmp_env_data, data, self.in_pressure)
|
|
247
|
+ else:
|
|
248
|
+ wx.CallAfter(self.update_current_bmp_env_data, data, self.out_pressure)
|
|
249
|
+ return
|
|
250
|
+ elif service_id == wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE and data_id == wetation_protocol.my_base_protocol_tcp.ENVDATA_STATISTIC_DHT:
|
|
251
|
+ data = helpers.continues_statistic_multivalue(**data)
|
|
252
|
+ #
|
|
253
|
+ # Current environmental data
|
|
254
|
+ temp = data[dht_22.KEY_TEMPERATURE].mean
|
208
|
255
|
if prot_id == self.PROT_ID_IN:
|
209
|
256
|
if self.__max_temp_in__ is None or temp > self.__max_temp_in__:
|
210
|
257
|
self.__max_temp_in__ = temp
|
211
|
258
|
if self.__min_temp_in__ is None or temp < self.__min_temp_in__:
|
212
|
259
|
self.__min_temp_in__ = temp
|
213
|
|
- 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__)
|
|
260
|
+ 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__)
|
214
|
261
|
else:
|
215
|
262
|
if self.__max_temp_out__ is None or temp > self.__max_temp_out__:
|
216
|
263
|
self.__max_temp_out__ = temp
|
217
|
264
|
if self.__min_temp_out__ is None or temp < self.__min_temp_out__:
|
218
|
265
|
self.__min_temp_out__ = temp
|
219
|
|
- 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__)
|
220
|
|
- return wetation_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
266
|
+ 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__)
|
|
267
|
+ return
|
221
|
268
|
logger.warning("Unknown response with valid data for prot_id %d, service_id=%d, data_id=%d", prot_id, service_id, data_id)
|
222
|
|
- return wetation_protocol.my_base_protocol_tcp.STATUS_SERVICE_OR_DATA_UNKNOWN, None
|
223
|
269
|
|
224
|
|
- def update_current_env_data(self, env_data, temperature, humidity, pressure, temperature_min, temperature_max, value_min, value_max):
|
|
270
|
+ def update_current_bmp_env_data(self, env_data, pressure):
|
|
271
|
+ pressure.SetLabel('%.0f hPa' % env_data[bmp_180.KEY_PRESSURE].mean)
|
|
272
|
+ self.Layout()
|
|
273
|
+
|
|
274
|
+ def update_current_dht_env_data(self, env_data, temperature, humidity, pressure, temperature_min, temperature_max, value_min, value_max):
|
225
|
275
|
if isinstance(value_min, numbers.Number) and isinstance(value_max, numbers.Number):
|
226
|
276
|
temperature_min.SetLabel('%.1f' % value_min)
|
227
|
277
|
temperature_max.SetLabel('%.1f' % value_max)
|
228
|
|
- temperature.SetLabel('%.1f °C' % env_data[dht_22.KEY_TEMPERATURE])
|
229
|
|
- humidity.SetLabel('%.1f %%' % env_data[dht_22.KEY_HUMIDITY])
|
230
|
|
- pressure.SetLabel('%.0f hPa' % env_data[bmp_180.KEY_PRESSURE])
|
|
278
|
+ temperature.SetLabel('%.1f °C' % env_data[dht_22.KEY_TEMPERATURE].mean)
|
|
279
|
+ humidity.SetLabel('%.1f %%' % env_data[dht_22.KEY_HUMIDITY].mean)
|
231
|
280
|
self.Layout()
|
232
|
281
|
|
233
|
282
|
def update_time(self):
|
|
@@ -236,8 +285,15 @@ class WetationFrameProt(gui.Wetation):
|
236
|
285
|
self.Layout()
|
237
|
286
|
|
238
|
287
|
def gate_oc_evt(self, event):
|
239
|
|
- logger.debug("Gate open/close request")
|
240
|
|
- 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)
|
|
288
|
+ r = wx.MessageDialog(
|
|
289
|
+ self,
|
|
290
|
+ "Soll das Garagentor betätigt werden?",
|
|
291
|
+ "Garage",
|
|
292
|
+ wx.YES_NO | wx.NO_DEFAULT | wx.ICON_WARNING
|
|
293
|
+ ).ShowModal()
|
|
294
|
+ if r == wx.ID_YES:
|
|
295
|
+ logger.debug("Gate open/close request")
|
|
296
|
+ 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)
|
241
|
297
|
event.Skip()
|
242
|
298
|
|
243
|
299
|
def reset_in_temp_minmax_evt(self, event):
|
|
@@ -284,7 +340,7 @@ class MyApp(wx.App):
|
284
|
340
|
|
285
|
341
|
|
286
|
342
|
if __name__ == "__main__":
|
287
|
|
- report.appLoggingConfigure(os.path.dirname(__file__), config.LOGTARGET, config.loggers)
|
|
343
|
+ report.appLoggingConfigure(os.path.dirname(__file__), config.LOGTARGET, config.loggers, fmt=config.formatter)
|
288
|
344
|
#
|
289
|
345
|
app = MyApp(0)
|
290
|
346
|
app.frame.run()
|