11import logging
22from typing import Dict , Optional , TypeVar , Generic , Callable , Union
33
4+ from helpermodules import timecheck
45from helpermodules .pub import Pub
56from modules .common import store
67from modules .common .abstract_io import AbstractIoDevice
@@ -19,23 +20,47 @@ def __init__(self,
1920 config : T_IO_CONFIG ,
2021 component_reader : Callable [[], IoState ],
2122 component_writer : Callable [[Dict [int , Union [float , int ]]], Optional [IoState ]],
22- initializer : Callable = lambda : None ) -> None :
23+ initializer : Callable = lambda : None ,
24+ error_handler : Callable = lambda : None ) -> None :
2325 self .config = config
26+ self .__error_handler = error_handler
2427 self .fault_state = FaultState (ComponentInfo (self .config .id , self .config .name ,
2528 ComponentType .IO .value ))
2629 self .store = store .get_io_value_store (self .config .id )
2730 self .set_manual : Dict = {"analog_output" : {}, "digital_output" : {}}
31+ self .error_timestamp = None
2832 with SingleComponentUpdateContext (self .fault_state ):
2933 self .component_reader = component_reader
3034 self .component_writer = component_writer
3135 initializer ()
3236
37+ def error_handler (self ) -> None :
38+ error_timestamp_topic = f"openWB/set/system/device/{ self .config .id } /error_timestamp"
39+ if self .error_timestamp is None :
40+ self .error_timestamp = timecheck .create_timestamp ()
41+ Pub ().pub (error_timestamp_topic , self .error_timestamp )
42+ log .debug (
43+ f"Fehler bei Gerät { self .config .name } aufgetreten, Fehlerzeitstempel: { self .error_timestamp } " )
44+ if timecheck .check_timestamp (self .error_timestamp , 60 ) is False :
45+ try :
46+ self .__error_handler ()
47+ except Exception :
48+ log .exception (f"Fehlerbehandlung für Gerät { self .config .name } fehlgeschlagen" )
49+ else :
50+ log .debug (f"Fehlerbehandlung für Gerät { self .config .name } wurde durchgeführt." )
51+
52+ self .error_timestamp = None
53+ Pub ().pub (error_timestamp_topic , self .error_timestamp )
54+
3355 def read (self ):
3456 if hasattr (self , "component_reader" ):
3557 # Wenn beim Initialisieren etwas schief gelaufen ist, ursprüngliche Fehlermeldung beibehalten
36- with SingleComponentUpdateContext (self .fault_state ):
37- io_state = self .component_reader ()
38- self .store .set (io_state )
58+ try :
59+ with SingleComponentUpdateContext (self .fault_state , reraise = True ):
60+ io_state = self .component_reader ()
61+ self .store .set (io_state )
62+ except Exception :
63+ self .error_handler ()
3964
4065 def update_manual_output (self , manual : Dict [str , bool ], output : Dict [str , bool ], string : str , topic_suffix : str ):
4166 if len (manual ) > 0 :
@@ -48,12 +73,16 @@ def update_manual_output(self, manual: Dict[str, bool], output: Dict[str, bool],
4873 def write (self , analog_output , digital_output ):
4974 if hasattr (self , "component_writer" ):
5075 # Wenn beim Initialisieren etwas schief gelaufen ist, ursprüngliche Fehlermeldung beibehalten
51- with SingleComponentUpdateContext (self .fault_state ):
52- self .update_manual_output (self .set_manual ["analog_output" ], analog_output , "analoge" , "analog_output" )
53- self .update_manual_output (self .set_manual ["digital_output" ],
54- digital_output , "digitale" , "digital_output" )
55- if ((analog_output and self .store .delegate .state .analog_output != analog_output ) or
56- (digital_output and self .store .delegate .state .digital_output != digital_output )):
57- io_state = self .component_writer (analog_output , digital_output )
58- if io_state is not None :
59- self .store .set (io_state )
76+ try :
77+ with SingleComponentUpdateContext (self .fault_state , update_always = False , reraise = True ):
78+ self .update_manual_output (self .set_manual ["analog_output" ],
79+ analog_output , "analoge" , "analog_output" )
80+ self .update_manual_output (self .set_manual ["digital_output" ],
81+ digital_output , "digitale" , "digital_output" )
82+ if ((analog_output and self .store .delegate .state .analog_output != analog_output ) or
83+ (digital_output and self .store .delegate .state .digital_output != digital_output )):
84+ io_state = self .component_writer (analog_output , digital_output )
85+ if io_state is not None :
86+ self .store .set (io_state )
87+ except Exception :
88+ self .error_handler ()
0 commit comments