@@ -110,7 +110,7 @@ async def _update_settings_from_device(hass: HomeAssistant, config_entry: Config
110110 "pm25_offset" : (CONF_PM25_OFFSET , int ),
111111 "pm10_offset" : (CONF_PM10_OFFSET , int ),
112112 "noise_offset" : (CONF_NOISE_OFFSET , int ),
113- "tvoc_offset " : (CONF_TVOC_OFFSET , int ),
113+ "tvoc_zoom " : (CONF_TVOC_OFFSET , lambda x : round ( x / 10 , 1 ) ),
114114 "tvoc_index_offset" : (CONF_TVOC_INDEX_OFFSET , int ),
115115 # CGDN1 specific settings
116116 "power_off_time" : (CONF_POWER_OFF_TIME , int ),
@@ -219,19 +219,31 @@ async def async_update_data():
219219 def message_received (message ):
220220 """Handle new MQTT messages."""
221221 try :
222+ _LOGGER .warning ("=== MQTT MESSAGE RECEIVED === Topic: %s" , message .topic )
223+
222224 payload = json .loads (message .payload )
225+ _LOGGER .warning ("Payload type: %s" , type (payload ))
226+
223227 if not isinstance (payload , dict ):
224228 _LOGGER .error ("Payload is not a dictionary" )
225229 return
226230
231+ # Check message type first - type 28 (settings) messages don't include MAC
232+ message_type = payload .get ("type" )
233+
234+ # For messages with MAC, verify it matches
227235 received_mac = payload .get ("mac" , "" ).replace (":" , "" ).upper ()
228236 expected_mac = mac .replace (":" , "" ).upper ()
229237
230- if received_mac != expected_mac :
238+ _LOGGER .warning ("Received MAC: %s, Expected MAC: %s, Type: %s" , received_mac , expected_mac , message_type )
239+
240+ # Skip MAC check for type 28 (settings) messages as they don't include MAC
241+ # We're subscribed to this device's specific topic, so we know it's for us
242+ if received_mac and received_mac != expected_mac :
231243 _LOGGER .debug ("Received message for a different device. Expected: %s, Got: %s" , expected_mac , received_mac )
232244 return
233245
234- _LOGGER .debug ("Processing MQTT message for device %s" , mac )
246+ _LOGGER .warning ("Processing MQTT message for device %s" , mac )
235247
236248 # Update timestamp first - any message from device means it's online
237249 current_timestamp = int (time .time ())
@@ -247,25 +259,26 @@ def message_received(message):
247259 if device_type is not None :
248260 if type_sensor .hass :
249261 type_sensor .update_type (device_type )
250-
251- # Log all message types for debugging
252- message_type = payload .get ("type" )
253- _LOGGER .info ("Received MQTT message type: %s" , message_type )
254262
255263 mac_address = payload .get ("mac" )
256264 if mac_address is not None :
257265 if mac_sensor .hass :
258266 mac_sensor .update_mac (mac_address )
259267
260- # Handle type 28 messages (device settings update)
261- message_type = payload .get ("type" )
268+ # Handle type 28 messages (device settings update) - Check BEFORE sensorData
269+ _LOGGER .warning ("=== MESSAGE TYPE: %s ===" , message_type )
270+
262271 if message_type == 28 or message_type == "28" :
263- _LOGGER .info ("Received type 28 settings update from device" )
272+ _LOGGER .error ("!!! TYPE 28 SETTINGS UPDATE DETECTED !!!" )
273+ _LOGGER .error ("Full payload: %s" , json .dumps (payload , indent = 2 ))
264274 settings = payload .get ("setting" , {})
265- _LOGGER .info ("Settings in payload : %s" , settings )
275+ _LOGGER .error ("Settings extracted : %s" , settings )
266276 if settings :
277+ _LOGGER .error ("!!! CREATING TASK TO UPDATE SETTINGS !!!" )
267278 hass .async_create_task (_update_settings_from_device (hass , config_entry , settings , model ))
268- return
279+ else :
280+ _LOGGER .error ("!!! TYPE 28 HAS NO SETTINGS DICT !!!" )
281+ return # Don't process as sensor data
269282
270283 sensor_data = payload .get ("sensorData" )
271284 if not isinstance (sensor_data , list ) or not sensor_data :
@@ -322,36 +335,41 @@ def message_received(message):
322335 await mqtt .async_subscribe (
323336 hass , f"{ MQTT_TOPIC_PREFIX } /{ mac } /up" , message_received , 1
324337 )
338+ _LOGGER .warning ("=== SUBSCRIBED TO: %s/%s/up ===" , MQTT_TOPIC_PREFIX , mac )
339+
340+
341+
342+
343+
344+
345+
325346
326- # CGDN1-specific: Subscribe to any message for this device to detect when it comes online
327- # CGDN1 doesn't always send full sensor data on power-on like CGS1/CGS2
328- if model == "CGDN1" :
329- @callback
330- def device_alive_check (message ):
331- """Detect any MQTT activity from CGDN1 device."""
332- try :
333- _LOGGER .debug ("CGDN1 device activity detected on topic: %s" , message .topic )
334- # Any MQTT activity from this device means it's alive
335- if status_sensor .hass :
336- current_time = int (time .time ())
337- if status_sensor ._last_timestamp == 0 or (current_time - status_sensor ._last_timestamp ) > 60 :
338- _LOGGER .info ("CGDN1 device %s appears to be online, updating status" , mac )
339- status_sensor .update_timestamp (current_time )
340- # Trigger a config publish to get fresh data
341- asyncio .create_task (sensors [5 ].publish_config ())
342- except Exception as e :
343- _LOGGER .error ("Error in CGDN1 device alive check: %s" , str (e ))
344-
345- await mqtt .async_subscribe (
346- hass , f"{ MQTT_TOPIC_PREFIX } /{ mac } /#" , device_alive_check , 1
347- )
347+
348+
349+
350+
351+
352+
353+
354+
355+
356+
357+
358+
359+
360+
361+
362+
363+
364+
365+
366+ # Note: CGDN1 devices are handled the same as other models
367+ # Status is determined solely by received MQTT messages, not by config publishes
348368
349369 # Set up timer for periodic publishing
350370 async def publish_config_wrapper (* args ):
351371 if await ensure_mqtt_connected (hass ):
352- # Force status to online when we publish config
353- if status_sensor .hass :
354- status_sensor .update_timestamp (int (time .time ()))
372+ # Don't force status to online - let actual device messages determine status
355373 await sensors [5 ].publish_config ()
356374 else :
357375 _LOGGER .error ("Failed to connect to MQTT for periodic config publish" )
@@ -426,6 +444,8 @@ async def _publish_config_on_status_change(self):
426444 """Publish config when status changes from offline to online."""
427445 if not self .hass :
428446 return
447+ # Add a small delay to let the device fully come online
448+ await asyncio .sleep (2 )
429449 sensors = self .hass .data [DOMAIN ][self ._config_entry .entry_id ].get ("sensors" , [])
430450 for sensor in sensors :
431451 if isinstance (sensor , QingpingCGSxSensor ):
0 commit comments