|
@@ -2,6 +2,8 @@
|
2
|
2
|
# -*- coding: UTF-8 -*-
|
3
|
3
|
#
|
4
|
4
|
|
|
5
|
+#TODO: Zyklischer reconnect versuch (ggf. inkl. herstellen der Schnittstelle für ein reconnect beim tcp_client)
|
|
6
|
+
|
5
|
7
|
import config
|
6
|
8
|
import rpi_envsens as envsens
|
7
|
9
|
import garage_protocol
|
|
@@ -19,83 +21,181 @@ logger = logging.getLogger('APP')
|
19
|
21
|
|
20
|
22
|
|
21
|
23
|
class WetationFrameProt(gui.Wetation):
|
|
24
|
+ PROT_ID_GARAGE = 0
|
|
25
|
+ PROT_ID_IN = 1
|
|
26
|
+ PROT_ID_OUT = 2
|
|
27
|
+ ALL_PROT_IDS = [PROT_ID_GARAGE, PROT_ID_IN, PROT_ID_OUT]
|
|
28
|
+
|
|
29
|
+ REQUEST_MSGS = {
|
|
30
|
+ PROT_ID_GARAGE: [
|
|
31
|
+ {
|
|
32
|
+ 'service_id': garage_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
|
33
|
+ 'data_id': garage_protocol.my_base_protocol_tcp.GATE_POSITION,
|
|
34
|
+ },
|
|
35
|
+ ],
|
|
36
|
+ PROT_ID_IN: [
|
|
37
|
+ {
|
|
38
|
+ 'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
|
39
|
+ 'data_id': wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA,
|
|
40
|
+ },
|
|
41
|
+ ],
|
|
42
|
+ PROT_ID_OUT: [
|
|
43
|
+ {
|
|
44
|
+ 'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
|
45
|
+ 'data_id': wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA,
|
|
46
|
+ },
|
|
47
|
+ ],
|
|
48
|
+ }
|
|
49
|
+
|
|
50
|
+
|
22
|
51
|
def __init__(self, *args, **kwds):
|
|
52
|
+ self.__prot__ = {}
|
|
53
|
+ self.no_data = {
|
|
54
|
+ self.PROT_ID_GARAGE: self.update_gate_position,
|
|
55
|
+ self.PROT_ID_IN: self.update_current_env_data_in,
|
|
56
|
+ self.PROT_ID_OUT: self.update_current_env_data_out,
|
|
57
|
+ }
|
23
|
58
|
gui.Wetation.__init__(self, *args, **kwds)
|
|
59
|
+ self.ShowFullScreen(config.FULL_SCREEN)
|
|
60
|
+
|
|
61
|
+ self.__init_communication__()
|
24
|
62
|
self.__task_data_request__ = task.periodic(10, self.__initiate_data_request__)
|
25
|
|
- self.__init__communication__()
|
26
|
63
|
|
27
|
|
- def __init__communication__(self):
|
|
64
|
+ def __init_protocol__(self, prot_id, ip, port, prot_class, secret):
|
|
65
|
+ c_tcp = tcp_socket.tcp_client_stp(ip, port, rx_log_lvl=logging.DEBUG)
|
|
66
|
+ self.__prot__[prot_id] = prot_class(c_tcp, secret)
|
|
67
|
+ if config.server_garage_secret is not None:
|
|
68
|
+ self.__prot__[prot_id].authentificate()
|
|
69
|
+
|
|
70
|
+ def __init_communication__(self):
|
28
|
71
|
#
|
29
|
72
|
# Start TCP-Clients
|
30
|
|
- c_tcp = tcp_socket.tcp_client_stp(config.server_out_ip, config.server_out_port, rx_log_lvl=logging.DEBUG)
|
31
|
|
- self.prot_out = wetation_protocol.my_base_protocol_tcp(c_tcp, config.server_out_secret)
|
32
|
|
- self.prot_out.register_callback(wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA, self.update_current_env_data_out)
|
33
|
|
- if config.server_out_secret is not None:
|
34
|
|
- self.prot_out.authentificate()
|
35
|
|
-
|
36
|
|
- c_tcp = tcp_socket.tcp_client_stp(config.server_in_ip, config.server_in_port, rx_log_lvl=logging.DEBUG)
|
37
|
|
- self.prot_in = wetation_protocol.my_base_protocol_tcp(c_tcp, config.server_in_secret)
|
38
|
|
- self.prot_in.register_callback(wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA, self.update_current_env_data_in)
|
39
|
|
- if config.server_in_secret is not None:
|
40
|
|
- self.prot_in.authentificate()
|
41
|
|
-
|
42
|
|
- c_tcp = tcp_socket.tcp_client_stp(config.server_garage_ip, config.server_garage_port, rx_log_lvl=logging.DEBUG)
|
43
|
|
- self.prot_garage = garage_protocol.my_base_protocol_tcp(c_tcp, config.server_garage_secret)
|
44
|
|
- self.prot_garage.register_callback(garage_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, garage_protocol.my_base_protocol_tcp.GATE_POSITION, self.update_gate_position)
|
45
|
|
- if config.server_garage_secret is not None:
|
46
|
|
- self.prot_garage.authentificate()
|
|
73
|
+ self.__init_protocol__(
|
|
74
|
+ self.PROT_ID_GARAGE,
|
|
75
|
+ config.server_garage_ip,
|
|
76
|
+ config.server_garage_port,
|
|
77
|
+ garage_protocol.my_base_protocol_tcp,
|
|
78
|
+ config.server_garage_secret
|
|
79
|
+ )
|
|
80
|
+ self.__prot__[self.PROT_ID_GARAGE].register_callback(garage_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, None, self.__garage_data__)
|
|
81
|
+
|
|
82
|
+ self.__init_protocol__(
|
|
83
|
+ self.PROT_ID_IN,
|
|
84
|
+ config.server_in_ip,
|
|
85
|
+ config.server_in_port,
|
|
86
|
+ wetation_protocol.my_base_protocol_tcp,
|
|
87
|
+ config.server_in_secret
|
|
88
|
+ )
|
|
89
|
+ self.__prot__[self.PROT_ID_IN].register_callback(wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, None, self.__in_data__)
|
|
90
|
+
|
|
91
|
+ self.__init_protocol__(
|
|
92
|
+ self.PROT_ID_OUT,
|
|
93
|
+ config.server_out_ip,
|
|
94
|
+ config.server_out_port,
|
|
95
|
+ wetation_protocol.my_base_protocol_tcp,
|
|
96
|
+ config.server_out_secret
|
|
97
|
+ )
|
|
98
|
+ self.__prot__[self.PROT_ID_OUT].register_callback(wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, None, self.__out_data__)
|
47
|
99
|
|
48
|
|
- def __update_current_envdata__(self, msg, temperature, humidity, pressure):
|
|
100
|
+ def __initiate_data_request__(self, rt):
|
|
101
|
+ for prot_id in self.ALL_PROT_IDS:
|
|
102
|
+ if self.__prot__[prot_id].is_connected():
|
|
103
|
+ for request_msg in self.REQUEST_MSGS.get(prot_id, []):
|
|
104
|
+ service_id = request_msg['service_id']
|
|
105
|
+ data_id = request_msg['data_id']
|
|
106
|
+ logger.debug('Sending data request for prot_id %d, service_id %d and data_id %d', prot_id, service_id, data_id)
|
|
107
|
+ self.__prot__[prot_id].send(service_id, data_id, None)
|
|
108
|
+ else:
|
|
109
|
+ logger.debug('Resetting GUI for prot_id %d', prot_id)
|
|
110
|
+ wx.CallAfter(self.no_data[prot_id], None)
|
|
111
|
+
|
|
112
|
+ # TODO: Move the following three lines to the wx idle task
|
|
113
|
+ wx.CallAfter(self.update_time)
|
|
114
|
+
|
|
115
|
+ def __in_data__(self, msg):
|
|
116
|
+ return self.__env_data__(msg, self.PROT_ID_IN)
|
|
117
|
+
|
|
118
|
+ def __out_data__(self, msg):
|
|
119
|
+ return self.__env_data__(msg, self.PROT_ID_OUT)
|
|
120
|
+
|
|
121
|
+ def __env_data__(self, msg, prot_id):
|
|
122
|
+ logger.debug('Received data for prot_id %d, service_id %d, data_id %d', prot_id, msg.get_service_id(), msg.get_data_id())
|
49
|
123
|
if msg.get_status() == wetation_protocol.my_base_protocol_tcp.STATUS_OKAY:
|
50
|
|
- env_data = msg.get_data()
|
51
|
|
- wx.CallAfter(temperature.SetLabel, "%.1f °C" % env_data[envsens.KEY_TEMPERATURE])
|
52
|
|
- wx.CallAfter(humidity.SetLabel, "%.1f %%" % env_data[envsens.KEY_HUMIDITY])
|
53
|
|
- wx.CallAfter(pressure.SetLabel, "%.0f mbar" % env_data[envsens.KEY_PRESSURE])
|
54
|
|
- wx.CallAfter(self.Layout)
|
|
124
|
+ if msg.get_data_id() == wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA:
|
|
125
|
+ if prot_id == self.PROT_ID_IN:
|
|
126
|
+ wx.CallAfter(self.update_current_env_data_in, msg)
|
|
127
|
+ else:
|
|
128
|
+ wx.CallAfter(self.update_current_env_data_out, msg)
|
|
129
|
+ return wetation_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
130
|
+ else:
|
|
131
|
+ logger.warning('Received unknown data for prot_id %d, service_id %d, data_id %d', self.PROT_ID_GARAGE, msg.get_service_id(), msg.get_data_id())
|
55
|
132
|
return wetation_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
56
|
133
|
else:
|
57
|
|
- logger.error('No environmental data received! MSG_STATUS was %s', wetation_protocol.my_base_protocol_tcp.STATUS_NAMES.get(msg.get_status(), repr(msg.get_status())))
|
|
134
|
+ logger.error('Error, receiving environmental data! MSG_STATUS was %s with PROT_ID %d', garage_protocol.my_base_protocol_tcp.STATUS_NAMES.get(msg.get_status(), repr(msg.get_status())), prot_id)
|
58
|
135
|
return wetation_protocol.my_base_protocol_tcp.STATUS_SERVICE_OR_DATA_UNKNOWN, None
|
59
|
136
|
|
60
|
|
- def update_current_env_data_out(self, msg):
|
61
|
|
- return self.__update_current_envdata__(msg, self.out_temperature, self.out_humidity, self.out_pressure)
|
|
137
|
+ def __garage_data__(self, msg):
|
|
138
|
+ logger.debug('Received data for prot_id %d, service_id %d, data_id %d', self.PROT_ID_GARAGE, msg.get_service_id(), msg.get_data_id())
|
|
139
|
+ if msg.get_status() == garage_protocol.my_base_protocol_tcp.STATUS_OKAY:
|
|
140
|
+ if msg.get_data_id() == garage_protocol.my_base_protocol_tcp.GATE_POSITION:
|
|
141
|
+ wx.CallAfter(self.update_gate_position, msg)
|
|
142
|
+ return garage_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
143
|
+ else:
|
|
144
|
+ logger.warning('Received unknown data for prot_id %d, service_id %d, data_id %d', self.PROT_ID_GARAGE, msg.get_service_id(), msg.get_data_id())
|
|
145
|
+ else:
|
|
146
|
+ logger.error('Error, receiving garage data! MSG_STATUS was %s', garage_protocol.my_base_protocol_tcp.STATUS_NAMES.get(msg.get_status(), repr(msg.get_status())))
|
|
147
|
+ return garage_protocol.my_base_protocol_tcp.STATUS_SERVICE_OR_DATA_UNKNOWN, None
|
|
148
|
+
|
62
|
149
|
|
63
|
150
|
def update_current_env_data_in(self, msg):
|
64
|
|
- return self.__update_current_envdata__(msg, self.in_temperature, self.in_humidity, self.in_pressure)
|
|
151
|
+ if msg is None:
|
|
152
|
+ temperature = '-.-'
|
|
153
|
+ humidity = '-.-'
|
|
154
|
+ pressure = '-'
|
|
155
|
+ else:
|
|
156
|
+ env_data = msg.get_data()
|
|
157
|
+ temperature = '%.1f' % env_data[envsens.KEY_TEMPERATURE]
|
|
158
|
+ humidity = '%.1f' % env_data[envsens.KEY_HUMIDITY]
|
|
159
|
+ pressure = '%.0f' % env_data[envsens.KEY_PRESSURE]
|
|
160
|
+ self.in_temperature.SetLabel("%s °C" % temperature)
|
|
161
|
+ self.in_humidity.SetLabel("%s %%" % humidity)
|
|
162
|
+ self.in_pressure.SetLabel("%s hPa" % pressure)
|
|
163
|
+ self.Layout()
|
65
|
164
|
|
66
|
|
- def update_gate_position(self, msg):
|
67
|
|
- if msg.get_status() == garage_protocol.my_base_protocol_tcp.STATUS_OKAY:
|
68
|
|
- #
|
69
|
|
- # show gate section in GUI
|
70
|
|
- #
|
71
|
|
- self.heading_garage.Show(True)
|
72
|
|
- self.gate_oc.Show(True)
|
73
|
|
- self.gate_open.Show(True)
|
74
|
|
- self.gate_position.Show(True)
|
75
|
|
- self.gate_close.Show(True)
|
76
|
|
- #
|
77
|
|
- # update gate position
|
78
|
|
- #
|
79
|
|
- wx.CallAfter(self.gate_position.SetValue, msg.get_data() * 100)
|
80
|
|
- wx.CallAfter(self.Layout)
|
81
|
|
- return garage_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
165
|
+ def update_current_env_data_out(self, msg):
|
|
166
|
+ if msg is None:
|
|
167
|
+ temperature = '-.-'
|
|
168
|
+ humidity = '-.-'
|
|
169
|
+ pressure = '-'
|
82
|
170
|
else:
|
83
|
|
- logger.error('No gate position received! MSG_STATUS was %s', garage_protocol.my_base_protocol_tcp.STATUS_NAMES.get(msg.get_status(), repr(msg.get_status())))
|
84
|
|
- return garage_protocol.my_base_protocol_tcp.STATUS_SERVICE_OR_DATA_UNKNOWN, None
|
|
171
|
+ env_data = msg.get_data()
|
|
172
|
+ temperature = "%.1f" % env_data[envsens.KEY_TEMPERATURE]
|
|
173
|
+ humidity = "%.1f" % env_data[envsens.KEY_HUMIDITY]
|
|
174
|
+ pressure = "%.0f" % env_data[envsens.KEY_PRESSURE]
|
|
175
|
+ self.out_temperature.SetLabel("%s °C" % temperature)
|
|
176
|
+ self.out_humidity.SetLabel("%s %%" % humidity)
|
|
177
|
+ self.out_pressure.SetLabel("%s hPa" % pressure)
|
|
178
|
+ self.Layout()
|
85
|
179
|
|
86
|
|
- def garage_oc_evt(self, event): # wxGlade: Wetation.<event_handler>
|
|
180
|
+ def update_gate_position(self, msg):
|
|
181
|
+ self.heading_garage.Show(msg is not None)
|
|
182
|
+ self.gate_oc.Show(msg is not None)
|
|
183
|
+ self.gate_open.Show(msg is not None)
|
|
184
|
+ self.gate_position.Show(msg is not None)
|
|
185
|
+ self.gate_close.Show(msg is not None)
|
|
186
|
+ if msg is not None:
|
|
187
|
+ self.gate_position.SetValue(msg.get_data() * 100)
|
|
188
|
+ self.Layout()
|
|
189
|
+
|
|
190
|
+ def update_time(self):
|
|
191
|
+ self.time.SetLabel(time.strftime("%H:%M"))
|
|
192
|
+ self.date.SetLabel(time.strftime("%d.%m.%Y"))
|
|
193
|
+ self.Layout()
|
|
194
|
+
|
|
195
|
+ def gate_oc_evt(self, event): # wxGlade: Wetation.<event_handler>
|
87
|
196
|
self.prot_garage.send(garage_protocol.my_base_protocol_tcp.SID_EXECUTE_REQUEST, garage_protocol.my_base_protocol_tcp.OPEN_CLOSE_GATE, None)
|
88
|
197
|
event.Skip()
|
89
|
198
|
|
90
|
|
- def __initiate_data_request__(self, rt):
|
91
|
|
- self.prot_out.send(wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST, wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA, None)
|
92
|
|
- self.prot_in.send(wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST, wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA, None)
|
93
|
|
- self.prot_garage.send(garage_protocol.my_base_protocol_tcp.SID_READ_REQUEST, garage_protocol.my_base_protocol_tcp.GATE_POSITION, None)
|
94
|
|
- # TODO: Move the following three lines to the wx idle task
|
95
|
|
- wx.CallAfter(self.time.SetLabel, time.strftime("%H:%M"))
|
96
|
|
- wx.CallAfter(self.date.SetLabel, time.strftime("%d.%m.%Y"))
|
97
|
|
- wx.CallAfter(self.Layout)
|
98
|
|
-
|
99
|
199
|
def run(self):
|
100
|
200
|
self.__task_data_request__.run()
|
101
|
201
|
|