_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Received MQTT message: {msg_json} for sensor {self.name}")
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Stored 'value2' as message: {self._value2} for sensor {self.name}")
# Extract the EVENT field
event=msg_json.get('event')
ifeventisNone:
_LOGGER.warning(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): No 'event' key in the MQTT message: {msg_json} for sensor {self.name}")
return
# Use the mapping to convert the event to the corresponding state
new_state=self._mapping.get(event,"None")# Default to "None" if no mapping found
ifnew_stateisnotNone:
_LOGGER.debug(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Mapped {event} to {new_state} for sensor {self.name}")
_LOGGER.debug(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Set state to 'None' due to timeout for sensor {self.name}")
"""Representation of a SAAS - Sleep As Android Stats sensor for Sound Events."""
def__init__(self,hass,name,mapping,entry_id):
"""Initialize the sensor."""
self._state=None
self._name=name
self._hass=hass
self._mapping=mapping
self.entry_id=entry_id
@property
defunique_id(self):
"""Return a unique ID."""
returnf"saas_sound_sensor_{self._name}"
@property
defname(self):
"""Return the name of the sensor."""
returnf"SAAS {self._name} Sound"
@property
defstate(self):
"""Return the state of the sensor."""
returnself._state
@property
defdevice_info(self):
"""Return information about the device."""
return{
"identifiers":{(DOMAIN,self._name)},
"name":self._name,
"manufacturer":INTEGRATION_NAME,
"model":MODEL,
}
asyncdefasync_added_to_hass(self):
"""Run when entity about to be added."""
awaitsuper().async_added_to_hass()
# Load the previous state from the state machine
state=awaitself.async_get_last_state()
ifstate:
self._state=state.state
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Loaded state: {self._state} for sensor {self.name}")
asyncdefmessage_received(msg):
"""Handle new MQTT messages."""
# Parse the incoming message
msg_json=json.loads(msg.payload)
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Received MQTT message: {msg_json} for sensor {self.name}")
# Extract the EVENT field
event=msg_json.get('event')
ifeventisNone:
_LOGGER.warning(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): No 'event' key in the MQTT message: {msg_json} for sensor {self.name}")
return
# Use the mapping to convert the event to the corresponding state
new_state=self._mapping.get(event,"None")# Default to "None" if no mapping found
ifnew_stateisnotNone:
_LOGGER.debug(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Mapped {event} to {new_state} for sensor {self.name}")
self._state=new_state
_LOGGER.debug(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Set state to {new_state} for sensor {self.name}")
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Saved state: {self._state} for sensor {self.name}")
classSAASSleepTrackingSensor(RestoreEntity):
"""Representation of a SAAS - Sleep As Android Stats sensor for Sleep Tracking."""
def__init__(self,hass,name,mapping,entry_id):
"""Initialize the sensor."""
self._state=None
self._name=name
self._hass=hass
self._mapping=mapping
self.entry_id=entry_id
@property
defunique_id(self):
"""Return a unique ID."""
returnf"saas_sleep_tracking_sensor_{self._name}"
@property
defname(self):
"""Return the name of the sensor."""
returnf"SAAS {self._name} Sleep Tracking"
@property
defstate(self):
"""Return the state of the sensor."""
returnself._state
@property
defdevice_info(self):
"""Return information about the device."""
return{
"identifiers":{(DOMAIN,self._name)},
"name":self._name,
"manufacturer":INTEGRATION_NAME,
"model":MODEL,
}
asyncdefasync_added_to_hass(self):
"""Run when entity about to be added."""
awaitsuper().async_added_to_hass()
# Load the previous state from the state machine
state=awaitself.async_get_last_state()
ifstate:
self._state=state.state
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Loaded state: {self._state} for sensor {self.name}")
asyncdefmessage_received(msg):
"""Handle new MQTT messages."""
# Parse the incoming message
msg_json=json.loads(msg.payload)
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Received MQTT message: {msg_json} for sensor {self.name}")
# Extract the EVENT field
event=msg_json.get('event')
ifeventisNone:
_LOGGER.warning(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): No 'event' key in the MQTT message: {msg_json} for sensor {self.name}")
return
# Use the mapping to convert the event to the corresponding state
new_state=self._mapping.get(event)# Removed default to "None"
ifnew_stateisnotNone:# Only update state if a mapping is found
self._state=new_state
_LOGGER.debug(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Set state to {new_state} for sensor {self.name}")
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Saved state: {self._state} for sensor {self.name}")
classSAASDisturbanceSensor(RestoreEntity):
"""Representation of a SAAS - Sleep As Android Stats sensor for Disturbance Events."""
def__init__(self,hass,name,mapping,entry_id):
"""Initialize the sensor."""
self._state=None
self._name=name
self._hass=hass
self._mapping=mapping
self.entry_id=entry_id
@property
defunique_id(self):
"""Return a unique ID."""
returnf"saas_disturbance_sensor_{self._name}"
@property
defname(self):
"""Return the name of the sensor."""
returnf"SAAS {self._name} Disturbance"
@property
defstate(self):
"""Return the state of the sensor."""
returnself._state
@property
defdevice_info(self):
"""Return information about the device."""
return{
"identifiers":{(DOMAIN,self._name)},
"name":self._name,
"manufacturer":INTEGRATION_NAME,
"model":MODEL,
}
asyncdefasync_added_to_hass(self):
"""Run when entity about to be added."""
awaitsuper().async_added_to_hass()
# Load the previous state from the state machine
state=awaitself.async_get_last_state()
ifstate:
self._state=state.state
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Loaded state: {self._state} for sensor {self.name}")
asyncdefmessage_received(msg):
"""Handle new MQTT messages."""
# Parse the incoming message
msg_json=json.loads(msg.payload)
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Received MQTT message: {msg_json} for sensor {self.name}")
# Extract the EVENT field
event=msg_json.get('event')
ifeventisNone:
_LOGGER.warning(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): No 'event' key in the MQTT message: {msg_json} for sensor {self.name}")
return
# Use the mapping to convert the event to the corresponding state
new_state=self._mapping.get(event,"None")# Default to "None" if no mapping found
self._state=new_state
_LOGGER.debug(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Set state to {new_state} for sensor {self.name}")
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Saved state: {self._state} for sensor {self.name}")
classSAASLullabySensor(RestoreEntity):
"""Representation of a SAAS - Sleep As Android Stats sensor for Lullaby."""
def__init__(self,hass,name,mapping,entry_id):
"""Initialize the sensor."""
self._state=None
self._name=name
self._hass=hass
self._mapping=mapping
self.entry_id=entry_id
@property
defunique_id(self):
"""Return a unique ID."""
returnf"saas_lullaby_sensor_{self._name}"
@property
defname(self):
"""Return the name of the sensor."""
returnf"SAAS {self._name} Lullaby"
@property
defstate(self):
"""Return the state of the sensor."""
returnself._state
@property
defdevice_info(self):
"""Return information about the device."""
return{
"identifiers":{(DOMAIN,self._name)},
"name":self._name,
"manufacturer":INTEGRATION_NAME,
"model":MODEL,
}
asyncdefasync_added_to_hass(self):
"""Run when entity about to be added."""
awaitsuper().async_added_to_hass()
# Load the previous state from the state machine
state=awaitself.async_get_last_state()
ifstate:
self._state=state.state
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Loaded state: {self._state} for sensor {self.name}")
asyncdefmessage_received(msg):
"""Handle new MQTT messages."""
# Parse the incoming message
msg_json=json.loads(msg.payload)
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Received MQTT message: {msg_json} for sensor {self.name}")
# Extract the EVENT field
event=msg_json.get('event')
ifeventisNone:
_LOGGER.warning(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): No 'event' key in the MQTT message: {msg_json} for sensor {self.name}")
return
# Use the mapping to convert the event to the corresponding state
new_state=self._mapping.get(event,"None")# Default to "None" if no mapping found
self._state=new_state
_LOGGER.debug(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Set state to {new_state} for sensor {self.name}")
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Saved state: {self._state} for sensor {self.name}")
classSAASSleepStage(RestoreEntity):
"""Representation of a SAAS - Sleep As Android Stats sensor for Sleep Stage."""
def__init__(self,hass,name,mapping,entry_id):
"""Initialize the sensor."""
self._state=None
self._name=name
self._hass=hass
self._mapping=mapping
self.entry_id=entry_id
@property
defunique_id(self):
"""Return a unique ID."""
returnf"saas_sleep_stage_sensor_{self._name}"
@property
defname(self):
"""Return the name of the sensor."""
returnf"SAAS {self._name} Sleep Stage"
@property
defstate(self):
"""Return the state of the sensor."""
returnself._state
@property
defdevice_info(self):
"""Return information about the device."""
return{
"identifiers":{(DOMAIN,self._name)},
"name":self._name,
"manufacturer":INTEGRATION_NAME,
"model":MODEL,
}
asyncdefasync_added_to_hass(self):
"""Run when entity about to be added."""
awaitsuper().async_added_to_hass()
# Load the previous state from the state machine
state=awaitself.async_get_last_state()
ifstate:
self._state=state.state
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Loaded state: {self._state} for sensor {self.name}")
asyncdefmessage_received(msg):
"""Handle new MQTT messages."""
# Parse the incoming message
msg_json=json.loads(msg.payload)
_LOGGER.info(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Received MQTT message: {msg_json} for sensor {self.name}")
# Extract the EVENT field
event=msg_json.get('event')
ifeventisNone:
_LOGGER.warning(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): No 'event' key in the MQTT message: {msg_json} for sensor {self.name}")
return
# Use the mapping to convert the event to the corresponding state
new_state=self._mapping.get(event,"None")# Default to "None" if no mapping found
self._state=new_state
_LOGGER.debug(f"{datetime.now().strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Set state to {new_state} for sensor {self.name}")
now=dt_util.utcnow()# Define 'now' before using it for logging
# Extract the 'event' from the incoming message
event=message.get('event')
_LOGGER.debug(f"{dt_util.as_local(now).strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Extracted Event {event} from message.")
# Map the event to a known state, or "Unknown" if the event is not recognized
mapped_value=STATE_MAPPING.get(event,"Unknown")
_LOGGER.debug(f"{dt_util.as_local(now).strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Mapped {event} to {mapped_value}.")
# If the event could not be mapped to a known state, set the sensor state to "Unknown"
ifmapped_value=="Unknown":
self._state="Unknown"
_LOGGER.debug(f"{dt_util.as_local(now).strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Event {event} could not be mapped to a known state. Setting sensor state to 'Unknown'.")
# If the mapped value is in the awake states, add it to the awake bucket and clear the sleep bucket
ifmapped_valueinself.awake_states:
self.awake_bucket.append((mapped_value,now))
self.sleep_bucket=[]
_LOGGER.debug(f"{dt_util.as_local(now).strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Mapped value {mapped_value} is in awake states. Adding to awake bucket and clearing sleep bucket.")
# If the mapped value is in the sleep states, add it to the sleep bucket and clear the awake bucket
elifmapped_valueinself.sleep_states:
self.sleep_bucket.append((mapped_value,now))
self.awake_bucket=[]
_LOGGER.debug(f"{dt_util.as_local(now).strftime('%H:%M:%S:%f')} (Line {inspect.currentframe().f_lineno}): Mapped value {mapped_value} is in sleep states. Adding to sleep bucket and clearing awake bucket.")
exceptExceptionase:
_LOGGER.error(f"Error processing message: {e}")
asyncdefasync_update(self,_=None):
"""Update the state."""
now=dt_util.utcnow()
# If any message in the awake bucket has reached the awake duration, set the state to "Awake"