@@ -115,6 +115,24 @@ def _handle_local_data_loaded(self, event: Any) -> None:
115115 return
116116 self .modbus_data_updated ()
117117
118+ def _parse_time_string (self , time_val : str ) -> datetime_time | None :
119+ """Parse common time string formats into a datetime.time object."""
120+ time_val = time_val .strip ()
121+ if not time_val :
122+ _LOGGER .debug (f"{ self ._platform_name } : empty time string for { self ._key } " )
123+ return None
124+
125+ for fmt in ["%H:%M" , "%H:%M:%S" , "%H:%M:%S.%f" ]:
126+ try :
127+ parsed = datetime .strptime (time_val , fmt )
128+ _LOGGER .debug (f"{ self ._platform_name } : parsed { self ._key } as { fmt } : { parsed .time ()} " )
129+ return parsed .time ()
130+ except ValueError :
131+ continue
132+
133+ _LOGGER .debug (f"{ self ._platform_name } : unrecognized time format for { self ._key } : { time_val } " )
134+ return None
135+
118136 def _parse_time_value (self ) -> datetime_time | None :
119137 """Parse the time value from hub.data and return a datetime.time object.
120138
@@ -136,57 +154,17 @@ def _parse_time_value(self) -> datetime_time | None:
136154
137155 # Handle string time values in hh:mm format
138156 if isinstance (time_val , str ):
139- # Strip whitespace and handle empty strings
140- time_val = time_val .strip ()
141- if not time_val :
142- _LOGGER .debug (f"{ self ._platform_name } : empty time string for { self ._key } " )
143- return None
144- # Common time formats
145- for fmt in ["%H:%M" , "%H:%M:%S" , "%H:%M:%S.%f" ]:
146- try :
147- parsed = datetime .strptime (time_val , fmt )
148- _LOGGER .debug (f"{ self ._platform_name } : parsed { self ._key } as { fmt } : { parsed .time ()} " )
149- return parsed .time ()
150- except ValueError :
151- continue
152- # Try parsing as HH:MM:SS with seconds (8 chars like 05:25:30)
153- if len (time_val ) == 8 and time_val [2 ] == ":" and time_val [5 ] == ":" :
154- try :
155- parsed = datetime .strptime (time_val , "%H:%M:%S" )
156- _LOGGER .debug (f"{ self ._platform_name } : parsed { self ._key } as HH:MM:SS: { parsed .time ()} " )
157- return parsed .time ()
158- except ValueError :
159- pass
160- # Try parsing as HH:MM (5 chars like 05:25)
161- if len (time_val ) == 5 and time_val [2 ] == ":" :
162- try :
163- parsed = datetime .strptime (time_val , "%H:%M" )
164- _LOGGER .debug (f"{ self ._platform_name } : parsed { self ._key } as HH:MM: { parsed .time ()} " )
165- return parsed .time ()
166- except ValueError :
167- pass
168- # If we get here, the string format was not recognized
169- _LOGGER .debug (f"{ self ._platform_name } : unrecognized time format for { self ._key } : { time_val } " )
170- return None
157+ return self ._parse_time_string (time_val )
171158
172- # Handle numeric values (e.g., from value_function_gen4time or value_function_gen23time)
159+ # Handle raw Modbus payloads by translating through the descriptor's option table.
173160 if isinstance (time_val , (int , float )):
174- # Try to convert to string and parse
175- time_str = str (time_val )
176- if len (time_str ) == 5 and time_str [2 ] == ":" :
177- try :
178- parsed = datetime .strptime (time_str , "%H:%M" )
179- _LOGGER .debug (f"{ self ._platform_name } : parsed numeric { self ._key } as HH:MM: { parsed .time ()} " )
180- return parsed .time ()
181- except ValueError :
182- pass
183- if len (time_str ) == 8 and time_str [2 ] == ":" and time_str [5 ] == ":" :
184- try :
185- parsed = datetime .strptime (time_str , "%H:%M:%S" )
186- _LOGGER .debug (f"{ self ._platform_name } : parsed numeric { self ._key } as HH:MM:SS: { parsed .time ()} " )
187- return parsed .time ()
188- except ValueError :
189- pass
161+ payload = int (time_val )
162+ if self ._option_dict is not None :
163+ mapped_value = self ._option_dict .get (payload )
164+ if mapped_value is not None :
165+ return self ._parse_time_string (mapped_value )
166+ _LOGGER .debug (f"{ self ._platform_name } : no time option mapping for { self ._key } payload { payload } " )
167+ return None
190168
191169 _LOGGER .debug (f"{ self ._platform_name } : time value for { self ._key } is not a string or datetime: { type (time_val )} " )
192170 return None
@@ -225,7 +203,7 @@ async def async_set_value(self, value: datetime_time | None) -> None:
225203
226204 # Find the corresponding payload from option_dict
227205 payload = None
228- for key , time_val in self ._option_dict .items ():
206+ for key , time_val in ( self ._option_dict or {}) .items ():
229207 if time_val == time_str :
230208 payload = key
231209 break
@@ -259,7 +237,9 @@ async def async_set_value(self, value: datetime_time | None) -> None:
259237 elif self ._write_method == WRITE_DATA_LOCAL :
260238 _LOGGER .info (f"*** local data written { self ._key } : { time_str } " )
261239 self ._hub .localsUpdated = True # mark to save permanently
262- self ._hub .data [self ._key ] = time_str
240+
241+ self ._hub .data [self ._key ] = time_str
242+ self ._attr_native_value = value
263243
264244 self .async_write_ha_state ()
265245
0 commit comments