#!/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, ] SLOW_PROT_IDS = [PROT_ID_IN, PROT_ID_OUT, ] FAST_PROT_IDS = [PROT_ID_GARAGE, ] 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_1s__ = task.periodic(1, self.__task_1s_callback__) self.__task_10s__ = task.periodic(10, self.__task_10s_callback__) self.__task_60s__ = task.periodic(60, self.__task_60s_callback__) 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 __task_1s_callback__(self, rt): # request data from fast prot ids self.__initiate_data_request__(rt, self.FAST_PROT_IDS) # set date and time wx.CallAfter(self.update_time) def __task_10s_callback__(self, rt): # request data from slow prot ids self.__initiate_data_request__(rt, self.SLOW_PROT_IDS) def __task_60s_callback__(self, rt): # reconnect prots if needed for prot_id in self.ALL_PROT_IDS: if not self.__prot__[prot_id].is_connected(): logger.debug("Trying to reconnect prot_id %d", prot_id) self.__prot__[prot_id].reconnect() def __initiate_data_request__(self, rt, prot_ids): for prot_id in 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) 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. 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 run(self): self.__task_1s__.run() self.__task_10s__.run() self.__task_60s__.run() def close(self): self.__task_1s__.stop() self.__task_1s__.join() self.__task_10s__.stop() self.__task_10s__.join() self.__task_60s__.stop() self.__task_60s__.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()