227 řádky
8.8 KiB
Python
227 řádky
8.8 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: UTF-8 -*-
|
|
#
|
|
|
|
#TODO: Zyklischer reconnect versuch (ggf. inkl. herstellen der Schnittstelle für ein reconnect beim tcp_client)
|
|
|
|
import config
|
|
import rpi_envsens as envsens
|
|
import garage_protocol
|
|
import gui
|
|
import logging
|
|
import os
|
|
import report
|
|
import task
|
|
import tcp_socket
|
|
import time
|
|
import wetation_protocol
|
|
import wx
|
|
|
|
logger = logging.getLogger('APP')
|
|
|
|
|
|
class WetationFrameProt(gui.Wetation):
|
|
PROT_ID_GARAGE = 0
|
|
PROT_ID_IN = 1
|
|
PROT_ID_OUT = 2
|
|
ALL_PROT_IDS = [PROT_ID_GARAGE, PROT_ID_IN, PROT_ID_OUT]
|
|
|
|
REQUEST_MSGS = {
|
|
PROT_ID_GARAGE: [
|
|
{
|
|
'service_id': garage_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
|
'data_id': garage_protocol.my_base_protocol_tcp.GATE_POSITION,
|
|
},
|
|
],
|
|
PROT_ID_IN: [
|
|
{
|
|
'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
|
'data_id': wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA,
|
|
},
|
|
],
|
|
PROT_ID_OUT: [
|
|
{
|
|
'service_id': wetation_protocol.my_base_protocol_tcp.SID_READ_REQUEST,
|
|
'data_id': wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA,
|
|
},
|
|
],
|
|
}
|
|
|
|
|
|
def __init__(self, *args, **kwds):
|
|
self.__prot__ = {}
|
|
self.no_data = {
|
|
self.PROT_ID_GARAGE: self.update_gate_position,
|
|
self.PROT_ID_IN: self.update_current_env_data_in,
|
|
self.PROT_ID_OUT: self.update_current_env_data_out,
|
|
}
|
|
gui.Wetation.__init__(self, *args, **kwds)
|
|
self.ShowFullScreen(config.FULL_SCREEN)
|
|
|
|
self.__init_communication__()
|
|
self.__task_data_request__ = task.periodic(10, self.__initiate_data_request__)
|
|
|
|
def __init_protocol__(self, prot_id, ip, port, prot_class, secret):
|
|
c_tcp = tcp_socket.tcp_client_stp(ip, port, rx_log_lvl=logging.DEBUG)
|
|
self.__prot__[prot_id] = prot_class(c_tcp, secret)
|
|
if config.server_garage_secret is not None:
|
|
self.__prot__[prot_id].authentificate()
|
|
|
|
def __init_communication__(self):
|
|
#
|
|
# Start TCP-Clients
|
|
self.__init_protocol__(
|
|
self.PROT_ID_GARAGE,
|
|
config.server_garage_ip,
|
|
config.server_garage_port,
|
|
garage_protocol.my_base_protocol_tcp,
|
|
config.server_garage_secret
|
|
)
|
|
self.__prot__[self.PROT_ID_GARAGE].register_callback(garage_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, None, self.__garage_data__)
|
|
|
|
self.__init_protocol__(
|
|
self.PROT_ID_IN,
|
|
config.server_in_ip,
|
|
config.server_in_port,
|
|
wetation_protocol.my_base_protocol_tcp,
|
|
config.server_in_secret
|
|
)
|
|
self.__prot__[self.PROT_ID_IN].register_callback(wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, None, self.__in_data__)
|
|
|
|
self.__init_protocol__(
|
|
self.PROT_ID_OUT,
|
|
config.server_out_ip,
|
|
config.server_out_port,
|
|
wetation_protocol.my_base_protocol_tcp,
|
|
config.server_out_secret
|
|
)
|
|
self.__prot__[self.PROT_ID_OUT].register_callback(wetation_protocol.my_base_protocol_tcp.SID_READ_RESPONSE, None, self.__out_data__)
|
|
|
|
def __initiate_data_request__(self, rt):
|
|
for prot_id in self.ALL_PROT_IDS:
|
|
if self.__prot__[prot_id].is_connected():
|
|
for request_msg in self.REQUEST_MSGS.get(prot_id, []):
|
|
service_id = request_msg['service_id']
|
|
data_id = request_msg['data_id']
|
|
logger.debug('Sending data request for prot_id %d, service_id %d and data_id %d', prot_id, service_id, data_id)
|
|
self.__prot__[prot_id].send(service_id, data_id, None)
|
|
else:
|
|
logger.debug('Resetting GUI for prot_id %d', prot_id)
|
|
wx.CallAfter(self.no_data[prot_id], None)
|
|
|
|
# TODO: Move the following three lines to the wx idle task
|
|
wx.CallAfter(self.update_time)
|
|
|
|
def __in_data__(self, msg):
|
|
return self.__env_data__(msg, self.PROT_ID_IN)
|
|
|
|
def __out_data__(self, msg):
|
|
return self.__env_data__(msg, self.PROT_ID_OUT)
|
|
|
|
def __env_data__(self, msg, prot_id):
|
|
logger.debug('Received data for prot_id %d, service_id %d, data_id %d', prot_id, msg.get_service_id(), msg.get_data_id())
|
|
if msg.get_status() == wetation_protocol.my_base_protocol_tcp.STATUS_OKAY:
|
|
if msg.get_data_id() == wetation_protocol.my_base_protocol_tcp.CURRENT_ENVDATA:
|
|
if prot_id == self.PROT_ID_IN:
|
|
wx.CallAfter(self.update_current_env_data_in, msg)
|
|
else:
|
|
wx.CallAfter(self.update_current_env_data_out, msg)
|
|
return wetation_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
else:
|
|
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())
|
|
return wetation_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
else:
|
|
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)
|
|
return wetation_protocol.my_base_protocol_tcp.STATUS_SERVICE_OR_DATA_UNKNOWN, None
|
|
|
|
def __garage_data__(self, msg):
|
|
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())
|
|
if msg.get_status() == garage_protocol.my_base_protocol_tcp.STATUS_OKAY:
|
|
if msg.get_data_id() == garage_protocol.my_base_protocol_tcp.GATE_POSITION:
|
|
wx.CallAfter(self.update_gate_position, msg)
|
|
return garage_protocol.my_base_protocol_tcp.STATUS_OKAY, None
|
|
else:
|
|
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())
|
|
else:
|
|
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())))
|
|
return garage_protocol.my_base_protocol_tcp.STATUS_SERVICE_OR_DATA_UNKNOWN, None
|
|
|
|
|
|
def update_current_env_data_in(self, msg):
|
|
if msg is None:
|
|
temperature = '-.-'
|
|
humidity = '-.-'
|
|
pressure = '-'
|
|
else:
|
|
env_data = msg.get_data()
|
|
temperature = '%.1f' % env_data[envsens.KEY_TEMPERATURE]
|
|
humidity = '%.1f' % env_data[envsens.KEY_HUMIDITY]
|
|
pressure = '%.0f' % env_data[envsens.KEY_PRESSURE]
|
|
self.in_temperature.SetLabel("%s °C" % temperature)
|
|
self.in_humidity.SetLabel("%s %%" % humidity)
|
|
self.in_pressure.SetLabel("%s hPa" % pressure)
|
|
self.Layout()
|
|
|
|
def update_current_env_data_out(self, msg):
|
|
if msg is None:
|
|
temperature = '-.-'
|
|
humidity = '-.-'
|
|
pressure = '-'
|
|
else:
|
|
env_data = msg.get_data()
|
|
temperature = "%.1f" % env_data[envsens.KEY_TEMPERATURE]
|
|
humidity = "%.1f" % env_data[envsens.KEY_HUMIDITY]
|
|
pressure = "%.0f" % env_data[envsens.KEY_PRESSURE]
|
|
self.out_temperature.SetLabel("%s °C" % temperature)
|
|
self.out_humidity.SetLabel("%s %%" % humidity)
|
|
self.out_pressure.SetLabel("%s hPa" % pressure)
|
|
self.Layout()
|
|
|
|
def update_gate_position(self, msg):
|
|
self.heading_garage.Show(msg is not None)
|
|
self.gate_oc.Show(msg is not None)
|
|
self.gate_open.Show(msg is not None)
|
|
self.gate_position.Show(msg is not None)
|
|
self.gate_close.Show(msg is not None)
|
|
if msg is not None:
|
|
self.gate_position.SetValue(msg.get_data() * 100)
|
|
self.Layout()
|
|
|
|
def update_time(self):
|
|
self.time.SetLabel(time.strftime("%H:%M"))
|
|
self.date.SetLabel(time.strftime("%d.%m.%Y"))
|
|
self.Layout()
|
|
|
|
def gate_oc_evt(self, event): # wxGlade: Wetation.<event_handler>
|
|
self.prot_garage.send(garage_protocol.my_base_protocol_tcp.SID_EXECUTE_REQUEST, garage_protocol.my_base_protocol_tcp.OPEN_CLOSE_GATE, None)
|
|
event.Skip()
|
|
|
|
def run(self):
|
|
self.__task_data_request__.run()
|
|
|
|
def close(self):
|
|
self.__task_data_request__.stop()
|
|
self.__task_data_request__.join()
|
|
|
|
def __del__(self):
|
|
self.close()
|
|
|
|
|
|
class MyApp(wx.App):
|
|
def OnInit(self):
|
|
self.frame = WetationFrameProt(None, wx.ID_ANY, "")
|
|
self.SetTopWindow(self.frame)
|
|
self.frame.Show()
|
|
return True
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
report.appLoggingConfigure(os.path.dirname(__file__), config.LOGTARGET, config.loggers)
|
|
#
|
|
app = MyApp(0)
|
|
app.frame.run()
|
|
app.MainLoop()
|
|
app.frame.close()
|