2020-09-06 13:38:47 +02:00
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
2020-09-09 10:35:08 +02:00
#TODO: Zyklischer reconnect versuch (ggf. inkl. herstellen der Schnittstelle für ein reconnect beim tcp_client)
2020-09-06 13:38:47 +02:00
import config
2020-09-07 12:34:08 +02:00
import rpi_envsens as envsens
import garage_protocol
import gui
2020-09-06 13:38:47 +02:00
import logging
import os
import report
import task
2020-09-07 12:34:08 +02:00
import tcp_socket
import time
import wetation_protocol
import wx
2020-09-06 13:38:47 +02:00
2020-09-07 12:34:08 +02:00
logger = logging . getLogger ( ' APP ' )
2020-09-06 13:38:47 +02:00
2020-09-07 12:34:08 +02:00
class WetationFrameProt ( gui . Wetation ) :
2020-09-09 10:35:08 +02:00
PROT_ID_GARAGE = 0
PROT_ID_IN = 1
PROT_ID_OUT = 2
2020-09-10 08:56:42 +02:00
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 , ]
2020-09-09 10:35:08 +02:00
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 ,
} ,
] ,
}
2020-09-06 13:38:47 +02:00
def __init__ ( self , * args , * * kwds ) :
2020-09-09 10:35:08 +02:00
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 ,
}
2020-09-07 12:34:08 +02:00
gui . Wetation . __init__ ( self , * args , * * kwds )
2020-09-09 10:35:08 +02:00
self . ShowFullScreen ( config . FULL_SCREEN )
self . __init_communication__ ( )
2020-09-10 08:56:42 +02:00
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__ )
2020-09-06 13:38:47 +02:00
2020-09-09 10:35:08 +02:00
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 ) :
2020-09-06 13:38:47 +02:00
#
2020-09-07 12:34:08 +02:00
# Start TCP-Clients
2020-09-09 10:35:08 +02:00
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__ )
2020-09-07 12:34:08 +02:00
2020-09-10 08:56:42 +02:00
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
2020-09-09 10:35:08 +02:00
for prot_id in self . ALL_PROT_IDS :
2020-09-10 08:56:42 +02:00
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 :
2020-09-09 10:35:08 +02:00
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 ( ) )
2020-09-07 12:34:08 +02:00
if msg . get_status ( ) == wetation_protocol . my_base_protocol_tcp . STATUS_OKAY :
2020-09-09 10:35:08 +02:00
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 ( ) )
2020-09-07 12:34:08 +02:00
return wetation_protocol . my_base_protocol_tcp . STATUS_OKAY , None
else :
2020-09-09 10:35:08 +02:00
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 )
2020-09-07 12:34:08 +02:00
return wetation_protocol . my_base_protocol_tcp . STATUS_SERVICE_OR_DATA_UNKNOWN , None
2020-09-09 10:35:08 +02:00
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
2020-09-07 12:34:08 +02:00
def update_current_env_data_in ( self , msg ) :
2020-09-09 10:35:08 +02:00
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 ( )
2020-09-07 12:34:08 +02:00
2020-09-09 10:35:08 +02:00
def update_current_env_data_out ( self , msg ) :
if msg is None :
temperature = ' -.- '
humidity = ' -.- '
pressure = ' - '
2020-09-07 12:34:08 +02:00
else :
2020-09-09 10:35:08 +02:00
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 ( )
2020-09-06 13:38:47 +02:00
2020-09-09 10:35:08 +02:00
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>
2020-09-10 08:56:42 +02:00
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 )
2020-09-06 13:38:47 +02:00
event . Skip ( )
2020-09-07 12:34:08 +02:00
def run ( self ) :
2020-09-10 08:56:42 +02:00
self . __task_1s__ . run ( )
self . __task_10s__ . run ( )
self . __task_60s__ . run ( )
2020-09-07 12:34:08 +02:00
def close ( self ) :
2020-09-10 08:56:42 +02:00
self . __task_1s__ . stop ( )
self . __task_1s__ . join ( )
self . __task_10s__ . stop ( )
self . __task_10s__ . join ( )
self . __task_60s__ . stop ( )
self . __task_60s__ . join ( )
2020-09-07 12:34:08 +02:00
def __del__ ( self ) :
self . close ( )
2020-09-06 13:38:47 +02:00
class MyApp ( wx . App ) :
def OnInit ( self ) :
2020-09-07 12:34:08 +02:00
self . frame = WetationFrameProt ( None , wx . ID_ANY , " " )
2020-09-06 13:38:47 +02:00
self . SetTopWindow ( self . frame )
self . frame . Show ( )
return True
if __name__ == " __main__ " :
2020-09-06 14:44:03 +02:00
report . appLoggingConfigure ( os . path . dirname ( __file__ ) , config . LOGTARGET , config . loggers )
2020-09-06 13:38:47 +02:00
#
app = MyApp ( 0 )
2020-09-07 12:34:08 +02:00
app . frame . run ( )
2020-09-06 13:38:47 +02:00
app . MainLoop ( )
2020-09-07 12:34:08 +02:00
app . frame . close ( )