alandtse / alexa_media_player

This is a custom component to allow control of Amazon Alexa devices in Home Assistant using the unofficial Alexa API.
Apache License 2.0
1.5k stars 287 forks source link

Amazon Thermostat reports incorrect temperature #1890

Open Angelos59 opened 1 year ago

Angelos59 commented 1 year ago

I am able to see echo temperature entities correctly. In the process of updating the integration to do this via checking the box to include devices connected via echo, I also got entity temperatures for the amazon thermostats. This was unexpected but good, the issue is that the temperature is reported incorrectly. I have five of these thermostats and they all do the same. All the echos, I have four report temperature correctly.

Is your feature request related to a problem? Please describe. This is not a request to report a problem but if possible to enhance the integration to report the correct temperature for the amazon thermostats.

Describe alternatives you've considered I have multiple temperature sensors zigbee, echo, etc.

If you are able to do this also consider exposing the humidity reading on the amazon thermostat, if possible.

Thanks very much

argpravardhan commented 1 year ago

I have observed this as well. It looks like it is converting the temperature from Celcius to Fahrenheit even though it is already in Fahrenheit.

AlexEr89 commented 1 year ago

I have the same problem. i got aqara thermostat and alexa covert my Celcius temperature in Fahrenheit . I dont know why. With old thermostat worked all well.

alandtse commented 1 year ago

Thanks, looks like we'll need a PR to address this use case. It can't be tied to a locale setting or I think HA may have changed the default temperature scale.

AlexEr89 commented 1 year ago

Hello, Thanks for an answer. Do you need something from me ? Protocols or something else ? Thanks


From: Alan Tse @.> Sent: Sunday, April 9, 2023 10:43:58 AM To: custom-components/alexa_media_player @.> Cc: AlexEr89 @.>; Comment @.> Subject: Re: [custom-components/alexa_media_player] Amazon Thermostat reports incorrect temperature (Issue #1890)

Thanks, looks like we'll need a PR to address this use case. It can't be tied to a locale setting or I think HA may have changed the default temperature scale.

— Reply to this email directly, view it on GitHubhttps://github.com/custom-components/alexa_media_player/issues/1890#issuecomment-1501077517, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AYDICPMFOPVBZ7TY4YZ5CI3XAJZE5ANCNFSM6AAAAAAWF4CJPI. You are receiving this because you commented.Message ID: @.***>

github-actions[bot] commented 1 year ago

This bug report has been labelled as help wanted since there has been no activity in the last 3 weeks. It will not be closed automatically.

pravardhanreddy commented 1 year ago

This issue is still present. Any fix please?

github-actions[bot] commented 1 year ago

This bug report has been labelled as help wanted since there has been no activity in the last 3 weeks. It will not be closed automatically.

Angelos59 commented 1 year ago

The integration still reports the incorrect temperature for Amazon thermostats. It reports kelvin when Fahrenheit is checked.

github-actions[bot] commented 1 year ago

This bug report has been labelled as help wanted since there has been no activity in the last 3 weeks. It will not be closed automatically.

pravardhanreddy commented 1 year ago

Issue is still present

github-actions[bot] commented 1 year ago

This bug report has been labelled as help wanted since there has been no activity in the last 3 weeks. It will not be closed automatically.

github-actions[bot] commented 12 months ago

The issue has received no activity for 60 days and will be closed in a week.

github-actions[bot] commented 11 months ago

This bug report has been labelled as help wanted since there has been no activity in the last 3 weeks. It will not be closed automatically.

github-actions[bot] commented 9 months ago

The issue has received no activity for 60 days and will be closed in a week.

inger147 commented 9 months ago

I just wanted to chime in and say that this is happening to me as well. I'm in the US, and as such all of my Alexa devices and Amazon Thermostat are all set to use Fahrenheit. However, the Thermostat Temperature being reported through the Alexa Media Player shows as C, even though the temperature number is clearly in Fahrenheit. Furnace Thermostat Temperature - showing F as C

inger147 commented 9 months ago

In addition to showing a Fahrenheit temperature as Celsius, I have also noticed that the temperature from my Amazon Thermostat is being rounded down to the nearest whole number, despite setting the temperature's display precision to use decimal places. In my above screenshot, you can see the temperature is shown as 64.0, but the temperature of the Echo in the same room is 64.8. No matter what temperature it is in my home, the thermostat temperature always shows .0 for the decimal precision, i.e., the actual temperature could be anywhere between 64.1 and 64.9, and the thermostat temperature will always show as 0 decimal precision (64.0) in Home Assistant. This makes it difficult to create precise automations based on the thermostat temperature.

github-actions[bot] commented 8 months ago

This bug report has been labelled as help wanted since there has been no activity in the last 3 weeks. It will not be closed automatically.

github-actions[bot] commented 6 months ago

The issue has received no activity for 60 days and will be closed in a week.

inger147 commented 6 months ago

This issue has not been fixed yet - please do not close it.

github-actions[bot] commented 5 months ago

This bug report has been labelled as help wanted since there has been no activity in the last 3 weeks. It will not be closed automatically.

github-actions[bot] commented 3 months ago

The issue has received no activity for 60 days and will be closed in a week.

inger147 commented 3 months ago

This issue has not been fixed yet, please do not close it.

danielbrunt57 commented 3 months ago

@inger147 Are you able to change the unit of measurement from C to F by clicking on the sensor and editing settings? If you do that does it then display 147.2 F??

image

image

image

image

image

image

danielbrunt57 commented 3 months ago

If it then displays a C to F converted value, I am initially thinking that Amazon is providing incorrect/different device settings info for that sensor from other sensors. It appears the the integration is simply setting up all temperature sensors based on info Amazon provides to the query and to somehow override for this device type likely won't be a trivial task. Unfortunately, I only have Echo's to test and play around with the code with. An HA debug log entry for that sensor being retrieved from Amazon as well as one for a sensor that's correct might help me see if something could somehow be coded to compensate.

async def create_temperature_sensors(account_dict, temperature_entities):
    """Create temperature sensors."""
    devices = []
    coordinator = account_dict["coordinator"]
    for temp in temperature_entities:
        _LOGGER.debug(
            "Creating entity %s for a temperature sensor with name %s",
            temp["id"],
            temp["name"],
        )
        serial = temp["device_serial"]
        device_info = lookup_device_info(account_dict, serial)
        sensor = TemperatureSensor(coordinator, temp["id"], temp["name"], device_info)
        account_dict["entities"]["sensor"].setdefault(serial, {})
        account_dict["entities"]["sensor"][serial]["Temperature"] = sensor
        devices.append(sensor)
    return devices
Morpheus2018 commented 3 months ago

The temperature sensor in home assistant "Alexa Media Player" has been unavailable for several days.

inger147 commented 2 months ago

@inger147 Are you able to change the unit of measurement from C to F by clicking on the sensor and editing settings? If you do that does it then display 147.2 F??

It is 77 degrees F this morning in my house; the Amazon thermostat temperature shows 77 C in Home Assistant. When I changed it to F in the settings, it showed 170.6 F until I changed it back. (My automations were not happy with that value - I started getting notifications that my house was on fire :))

inger147 commented 2 months ago

The temperature sensor in home assistant "Alexa Media Player" has been unavailable for several days.

I noticed this too - to fix this I went to Settings/Integrations/Alexa Media Player/Configure, and check the box for "Include devices connected via Echo". I think one of the recent updates to Alexa Media Player caused this setting to become unchecked by default.

inger147 commented 2 months ago

Unfortunately, I only have Echo's to test and play around with the code with.

I got my Amazon Thermostat essentially for free, because after I bought mine and installed it, I was able to get a rebate back from my gas/electric company that fully covered the cost I paid for it. YMMV, as I'm not sure if all utility companies offer this, but it might be worth looking into if you don't already have a smart thermostat.

danielbrunt57 commented 2 months ago

I strongly suspect this is an Amazon related issue and I'm struggling to see how the integration is going to second guess what Amazon is telling it. If the native unit of measurement is in C (like my Nest thermostat is) but it can display that native measurement converted internally to F and it does not disclose that fact clearly to a connecting integration then we are SOL. All of this is compounded by the host device's native UOM vs displayed UOM. The integration can only assume that the connected device internal UOM matches the host device's internal UOM. If you are confused by now, you should be, I know I am! If the host device is reporting a value with internal UOM in C then the integration can only assume the connected device is as well.

I can rewrite the code segment above to log more debug info a little later like this but I don't know if it'll shed any light or not:

async def create_temperature_sensors(account_dict, temperature_entities):
    """Create temperature sensors."""
    devices = []
    coordinator = account_dict["coordinator"]
    for temp in temperature_entities:
        serial = temp["device_serial"]
        device_info = lookup_device_info(account_dict, serial)
        _LOGGER.debug(
            "Serial %s - Creating entity %s for temperature sensor %s; device_info: %s",
            serial,
            temp["id"],
            temp["name"],
            device_info
        )
        sensor = TemperatureSensor(coordinator, temp["id"], temp["name"], device_info)
        account_dict["entities"]["sensor"].setdefault(serial, {})
        account_dict["entities"]["sensor"][serial]["Temperature"] = sensor
        devices.append(sensor)
    return devices
danielbrunt57 commented 2 months ago

It is 77 degrees F this morning in my house; the Amazon thermostat temperature shows 77 C in Home Assistant. When I changed it to F in the settings, it showed 170.6 F until I changed it back. (My automations were not happy with that value - I started getting notifications that my house was on fire :))

Can you try changing the Echo device from F to C and advise what the connected thermostat then shows? Change Temperature Unit on Your Echo Dot with clock ..

inger147 commented 2 months ago

Can you try changing the Echo device from F to C and advise what the connected thermostat then shows? Change Temperature Unit on Your Echo Dot with clock ..

Sure. I just set my Amazon Thermostat to Celsius instead of Fahrenheit, and the thermostat now reads "26.0" instead of "79", and after reloading the AMP integration in HA, the thermostat now there shows 26.5 C, instead of 79 C when my thermostat was set to Fahrenheit.

So, it looks like this conversion display issue only exists for people who want to use the thermostat with a Fahrenheit setting. Also, it looks like Celsius gets one decimal point precision both on the thermostat's display and in HA, while Fahrenheit is rounded to the nearest whole number in both places - the latter of which is bad for accuracy of automations that depend on this value :(

danielbrunt57 commented 2 months ago

The temperature sensor in home assistant "Alexa Media Player" has been unavailable for several days.

Your issue is unrelated to this issue and should be resolved now.

As for the issue at hand, I would need to purchase & install this thermostat and figure out how to debug alexapy so I can see exactly what the API is getting from Amazon...

danielbrunt57 commented 1 month ago

Sure. I just set my Amazon Thermostat to Celsius instead of Fahrenheit, and the thermostat now reads "26.0" instead of "79", and after reloading the AMP integration in HA, the thermostat now there shows 26.5 C, instead of 79 C when my thermostat was set to Fahrenheit.

So, it looks like this conversion display issue only exists for people who want to use the thermostat with a Fahrenheit setting. Also, it looks like Celsius gets one decimal point precision both on the thermostat's display and in HA, while Fahrenheit is rounded to the nearest whole number in both places - the latter of which is bad for accuracy of automations that depend on this value :(

Last night while working on something else, I happened to notice what I believe to be the reason for Fahrenheit not working correctly for you. The sensor's native unit of measurement appears to be hardcoded to CELSIUS in alexa_media/sensor.py:

class TemperatureSensor(SensorEntity, CoordinatorEntity):
    """A temperature sensor reported by an Echo."""

    def __init__(self, coordinator, entity_id, name, media_player_device_id):
        """Initialize temperature sensor."""
        super().__init__(coordinator)
        self.alexa_entity_id = entity_id
        self._attr_name = name + " Temperature"
        self._attr_device_class = SensorDeviceClass.TEMPERATURE
        self._attr_state_class = SensorStateClass.MEASUREMENT
        self._attr_native_value: Optional[datetime.datetime] = (
            parse_temperature_from_coordinator(coordinator, entity_id)
        )
        self._attr_native_unit_of_measurement: Optional[str] = UnitOfTemperature.CELSIUS
        # This includes "_temperature" because the Alexa entityId is for a physical device
        # A single physical device could have multiple HA entities
        self._attr_unique_id = entity_id + "_temperature"
        self._attr_device_info = (
            {
                "identifiers": {media_player_device_id},
                "via_device": media_player_device_id,
            }
            if media_player_device_id
            else None
        )

What I don't know at this point is whether the sensor's native unit of measurement is provided by Amazon in the JSON data they send to AMP when it's being initialized...

danielbrunt57 commented 1 month ago

@inger147 , @Angelos59 I don't know how to troubleshoot this for you. I am in Canada and Amazon.ca does not sell it for me to get one to troubleshoot. I would have to order one from Amazon.com and have it sent to my CMR address in Blaine, WA. Then it's almost an hour round trip from Richmond, BC to go pick it up. Amazon returns are easy except when I try to take it back down across the border to the States to return it, plus it's another almost 1 hour endeavour.

Can you scan your alexa_media DEBUG logs looking for any info regarding that device? Specifically 'unitOfMeasure':?

danielbrunt57 commented 1 month ago

Or perhaps a 'unit': 'Fahrenheit'?

from homeassistant.const import (
    STATE_UNKNOWN, STATE_OFF, STATE_ON, TEMP_CELSIUS, TEMP_FAHRENHEIT, 
)

CLIMATE_IP_PROPERTIES = []
CLIMATE_IP_STATUS_GETTER = []

PROPERTY_TYPE_MODE = 'modes'
PROPERTY_TYPE_SWITCH = 'switch'
PROPERTY_TYPE_NUMBER = 'number'
PROPERTY_TYPE_TEMP = 'temperature'
STATUS_GETTER_JSON = 'json_status'

UNIT_MAP = {
    'C': TEMP_CELSIUS,
    'c': TEMP_CELSIUS,
    'Celsius': TEMP_CELSIUS,
    'F': TEMP_FAHRENHEIT,
    'f': TEMP_FAHRENHEIT,
    'Fahrenheit': TEMP_FAHRENHEIT,
    TEMP_CELSIUS: TEMP_CELSIUS,
    TEMP_FAHRENHEIT: TEMP_FAHRENHEIT,
}

test_json = {'Devices':[{'Alarms':[{'alarmType':'Device','code':'FilterAlarm','id':'0','triggeredTime':'2019-02-25T08:46:01'}],'ConfigurationLink':{'href':'/devices/0/configuration'},'Diagnosis':{'diagnosisStart':'Ready'},'EnergyConsumption':{'saveLocation':'/files/usage.db'},'InformationLink':{'href':'/devices/0/information'},'Mode':{'modes':['Auto'],'options':['Comode_Off','Sleep_0','Autoclean_Off','Spi_Off','FilterCleanAlarm_0','OutdoorTemp_63','CoolCapa_35','WarmCapa_40','UsagesDB_254','FilterTime_10000','OptionCode_54458','UpdateAllow_0','FilterAlarmTime_500','Function_15','Volume_100'],'supportedModes':['Cool','Dry','Wind','Auto']},'Operation':{'power':'Off'},'Temperatures':[{'current':22.0,'desired':25.0,'id':'0','maximum':30,'minimum':16,'unit':'Celsius'}],'Wind':{'direction':'Fix','maxSpeedLevel':4,'speedLevel':0},'connected':True,'description':'TP6X_RAC_16K','id':'0','name':'RAC','resources':['Alarms','Configuration','Diagnosis','EnergyConsumption','Information','Mode','Operation','Temperatures','Wind'],'type':'Air_Conditioner','uuid':'C0972729-EB73-0000-0000-000000000000'}]}

def register_property(dev_prop):
    """Decorate a function to register a propery."""
    CLIMATE_IP_PROPERTIES.append(dev_prop)
    return dev_prop

def register_status_getter(getter):

homeassistant/util/const.py:

class UnitOfTemperature(StrEnum):
    """Temperature units."""

    CELSIUS = "°C"
    FAHRENHEIT = "°F"
    KELVIN = "K"

We need something in a JSON string from Amazon for that device for us to be able to determine if it's reported value is in "°C" or "°F" so we can correctly set the native unit of measurement...

inger147 commented 1 month ago

How do I access the Debug logs? also, I don't see a homeassistant/util/const.py file, only homeassistant/const.py (no util folder that I can see in the Studio Code Server navigation bar).

I do see the line in alexa_media/sensor.py/TemperatureSensor where the self._attr_native_unit_of_measurement value is being hardcoded to UnitOfTemperature.CELSIUS.

danielbrunt57 commented 1 month ago

After quite a bit of research and digging, I've just finished modifying code which looks promising. I only have one temperature sensor on an Echo but the debug statements in my changes show that I'm accessing the correct native scale for this sensor

'{"namespace":"Alexa.TemperatureSensor","name":"temperature","value":{"value":27.0,"scale":"CELSIUS"},"timeOfSample":"2024-09-12T21:44:44.045Z"}',

Can you replace these two files in `config/custom_components/alexa_media/ and see it it resolves the issue for you?

fix_temperature_sensor_unit_of_measurement.zip

alexa_entity.py previously was only returning the value but my code change now returns the value and the scale:

def parse_temperature_from_coordinator(
    coordinator: DataUpdateCoordinator, entity_id: str
) -> Optional[str]:
    """Get the temperature of an entity from the coordinator data."""
    value = parse_value_from_coordinator(
        coordinator, entity_id, "Alexa.TemperatureSensor", "temperature"
    )
    _LOGGER.debug("parse_temperature_from_coordinator: %s", value)
    return value

Then in sensor.py I'm using both value and scale:

class TemperatureSensor(SensorEntity, CoordinatorEntity):
    """A temperature sensor reported by an Echo."""

    def __init__(self, coordinator, entity_id, name, media_player_device_id, ):
        """Initialize temperature sensor."""
        super().__init__(coordinator)
        self.alexa_entity_id = entity_id
        # Need to append "_temperature" because the Alexa entityId is for a physical device
        # and a single physical device can have multiple HA entities
        self._attr_unique_id = entity_id + "_temperature"
        self._attr_name = name + " Temperature"
        self._attr_device_class = SensorDeviceClass.TEMPERATURE
        self._attr_state_class = SensorStateClass.MEASUREMENT
        value_and_scale: Optional[datetime.datetime] = (
            parse_temperature_from_coordinator(coordinator, entity_id)
        )
        self._attr_native_value = self._get_temperature_value(value_and_scale)
        _LOGGER.debug(
            "%s native_value: %s", 
            self._attr_name, 
            self._attr_native_value,
        )
        self._attr_native_unit_of_measurement = self._get_temperature_scale(value_and_scale)
        _LOGGER.debug(
            "%s native_unit_of_measurement: %s", 
            self._attr_name,
            self._attr_native_unit_of_measurement,
        )
        self._attr_device_info = (
            {
                "identifiers": {media_player_device_id},
                "via_device": media_player_device_id,
            }
            if media_player_device_id
            else None
        )

    @callback
    def _handle_coordinator_update(self) -> None:
        """Handle updated data from the coordinator."""
        value_and_scale = parse_temperature_from_coordinator(
            self.coordinator, self.alexa_entity_id
        )
        self._attr_native_value = self._get_temperature_value(value_and_scale)
        _LOGGER.debug(
            "%s native_value: %s", 
            self._attr_name,
            self._attr_native_value,
        )
        self._attr_native_unit_of_measurement = self._get_temperature_scale(value_and_scale)
        _LOGGER.debug(
            "%s native_unit_of_measurement: %s", 
            self._attr_name,
            self._attr_native_unit_of_measurement,
        )
        super()._handle_coordinator_update()

    def _get_temperature_value(self, value):
        if value and "value" in value:
            _LOGGER.debug("TemperatureSensor _get_temperature_value: %s", value.get("value"))
            return value.get("value")
        return None

    def _get_temperature_scale(self, value):
        if value and "scale" in value:
            _LOGGER.debug("TemperatureSensor _get_temperature_scale: %s", value.get("scale"))
            if value.get("scale") == "CELSIUS":
                return UnitOfTemperature.CELSIUS
            if value.get("scale") == "FAHRENHEIT":
                return UnitOfTemperature.FAHRENHEIT
            if value.get("scale") == "KELVIN":
                return UnitOfTemperature.KELVIN
        return None

So if your temp sensor is returning for example:

'{"namespace":"Alexa.TemperatureSensor","name":"temperature","value":{"value":72.4,"scale":"FAHRENHEIT"},"timeOfSample":"2024-09-12T21:44:44.045Z"}',

the HA entity native_unit_of_measurement should now be correct (°F)!

inger147 commented 1 month ago

I replaced those two files with the ones in your zip, and it looks like your changes worked! Thanks for this!

image

The displayed unit of measurement is displaying correctly for me now, but the Fahrenheit value is still being rounded to the nearest whole number in Home Assistant, i.e. it's only showing all zeroes after the value regardless of what I change the precision to in the Thermostat value settings in HA. I'm not sure if anything can be done about that from within HA, or if that fix would need to be made on Amazon's end.

danielbrunt57 commented 1 month ago

The displayed unit of measurement is displaying correctly for me now, but the Fahrenheit value is still being rounded to the nearest whole number in Home Assistant, i.e. it's only showing all zeroes after the value regardless of what I change the precision to in the Thermostat value settings in HA. I'm not sure if anything can be done about that from within HA, or if that fix would need to be made on Amazon's end.

There should be log entries from alexa_media.alexa_entity with parse_temperature_from_coordinator. The first one is the device initialization and contains no data. The second one though is the information refresh from Amazon and shows the JSON strings issued from Amazon:

2024-09-13 08:22:57.077 DEBUG (MainThread) [custom_components.alexa_media.alexa_entity] parse_temperature_from_coordinator: None
2024-09-13 08:22:57.298 DEBUG (MainThread) [custom_components.alexa_media.alexa_entity] parse_temperature_from_coordinator: {'value': 23.3, 'scale': 'CELSIUS'}

Then there are log entries from alexa_media.sensor The first ones are initialization:

2024-09-13 08:22:57.077 DEBUG (MainThread) [custom_components.alexa_media.sensor] Echo Temperature native_value: None
2024-09-13 08:22:57.077 DEBUG (MainThread) [custom_components.alexa_media.sensor] Echo Temperature native_unit_of_measurement: None

Followed later by data refresh from Amazon: These are from new def functions:

2024-09-13 13:43:17.445 DEBUG (MainThread) [custom_components.alexa_media.sensor] TemperatureSensor _get_temperature_value: 24.1
2024-09-13 13:43:17.445 DEBUG (MainThread) [custom_components.alexa_media.sensor] TemperatureSensor _get_temperature_scale: CELSIUS

And these are from the def _handle_coordinator_update which now uses those new functions:

2024-09-13 13:43:17.445 DEBUG (MainThread) [custom_components.alexa_media.sensor] Echo Temperature native_value: 24.1
2024-09-13 13:43:17.445 DEBUG (MainThread) [custom_components.alexa_media.sensor] Echo Temperature native_unit_of_measurement: °C

By adjusting your Search logs string you can narrow down the full log display. I.e. TemperatureSensor (with a trailing space) yields:

2024-09-13 13:43:17.445 DEBUG (MainThread) [custom_components.alexa_media.sensor] TemperatureSensor _get_temperature_value: 24.1
2024-09-13 13:43:17.445 DEBUG (MainThread) [custom_components.alexa_media.sensor] Echo Temperature native_value: 24.1
2024-09-13 13:43:17.445 DEBUG (MainThread) [custom_components.alexa_media.sensor] TemperatureSensor _get_temperature_scale: CELSIUS
2024-09-13 13:43:17.445 DEBUG (MainThread) [custom_components.alexa_media.sensor] Echo Temperature native_unit_of_measurement: °C

native_value:

2024-09-13 08:22:57.077 DEBUG (MainThread) [custom_components.alexa_media.sensor] Echo Temperature native_value: None
2024-09-13 08:22:57.298 DEBUG (MainThread) [custom_components.alexa_media.sensor] Echo Temperature native_value: 23.3

parse_temperature

2024-09-13 08:22:57.077 DEBUG (MainThread) [custom_components.alexa_media.alexa_entity] parse_temperature_from_coordinator: None
2024-09-13 08:22:57.298 DEBUG (MainThread) [custom_components.alexa_media.alexa_entity] parse_temperature_from_coordinator: {'value': 23.3, 'scale': 'CELSIUS'}
2024-09-13 08:24:02.543 DEBUG (MainThread) [custom_components.alexa_media.alexa_entity] parse_temperature_from_coordinator: {'value': 23.3, 'scale': 'CELSIUS'}

If the value is already rounded from Amazon then there's nothing we can do. But if your logs show otherwise, I can dig into the HA side...

inger147 commented 1 month ago

When I checked my debug log (I figured out how), all of the values you mentioned above showed 80.0, so those are all pre-rounded from Amazon.... however, in that same log I did find the below data as part of the "get_entity_state response" line, along with a lot of other details that are also specific to the thermostat:

'{"namespace":"Alexa.TemperatureSensor","name":"preciseTemperature","value":{"value":80.1640625,"scale":"FAHRENHEIT"},"timeOfSample":"2024-09-15T02:00:11.203Z"}'

Since this value is unrounded, it does seem that Amazon is sending it to HA in some form - is there a way that this "preciseTemperature" value might possibly be used as the value that shows up in HA, instead of the pre-rounded value that's currently displayed for Fahrenheit temperatures?

danielbrunt57 commented 1 month ago

'{"namespace":"Alexa.TemperatureSensor","name":"preciseTemperature","value":{"value":80.1640625,"scale":"FAHRENHEIT"},"timeOfSample":"2024-09-15T02:00:11.203Z"}'

Since this value is unrounded, it does seem that Amazon is sending it to HA in some form - is there a way that this "preciseTemperature" value might possibly be used as the value that shows up in HA, instead of the pre-rounded value that's currently displayed for Fahrenheit temperatures?

Very interesting!
The code is extracting from ,"value":{"value":80.1640625,"scale":"FAHRENHEIT"}, I.e. value.value for the temp and value.scale for the unit. I'm not sure why my 23.9 CELSIUS is correct but your 80.1640625 FAHRENHEIT becomes 80.0. It has to be in the coordinator, somewhere. I'll have another look...

BTW, I wish we still had temps of 26.7578125 CELSIUS here!!!

danielbrunt57 commented 1 month ago

What do you see in logs for parse_temperature_from_coordinator?

def parse_temperature_from_coordinator(
    coordinator: DataUpdateCoordinator, entity_id: str
) -> Optional[str]:
    """Get the temperature of an entity from the coordinator data."""
    temperature = parse_value_from_coordinator(
        coordinator, entity_id, "Alexa.TemperatureSensor", "temperature"
    )
    _LOGGER.debug("parse_temperature_from_coordinator: %s", temperature)
    return temperature

In alexa_entity.py ~line 438, can you add the following _LOGGER.debug command, restart and check your logs for the debug logs for "parse_value_from_coordinator"?

def parse_value_from_coordinator(
    coordinator: DataUpdateCoordinator,
    entity_id: str,
    namespace: str,
    name: str,
    since: Optional[datetime] = None,
    instance: str = None,
) -> Any:
    """Parse out values from coordinator for Alexa Entities."""
    if coordinator.data and entity_id in coordinator.data:
        for cap_state in coordinator.data[entity_id]:
            if (
                cap_state.get("namespace") == namespace
                and cap_state.get("name") == name
                and (cap_state.get("instance") == instance or instance is None)
            ):
                if is_cap_state_still_acceptable(cap_state, since):
                    _LOGGER.debug("parse_value_from_coordinator cap_state: %s", cap_state.get("value"))  # Insert this line
                    return cap_state.get("value")
                _LOGGER.debug(
                    "Coordinator data for %s is too old to be returned.",
                    hide_serial(entity_id),
                )
                return None
    else:
        _LOGGER.debug("Coordinator has no data for %s", hide_serial(entity_id))
    return None
danielbrunt57 commented 1 month ago

I've been digging and I see this in Core: image

Not sure yet what should be changed but the question I have is why is 23.9 C displayed as 23.9 C but 80.1640625 F is displayed as 80.0 F...

danielbrunt57 commented 1 month ago

You can try adding self._attr_suggested_display_precision: 1 in alexa_media/sensor.py ~line 269 but I'm not sure it will fix the issue:

    def __init__(self, coordinator, entity_id, name, media_player_device_id):
        """Initialize temperature sensor."""
        super().__init__(coordinator)
        self.alexa_entity_id = entity_id
        # Need to append "+temperature" because the Alexa entityId is for a physical device
        # and a single physical device can have multiple HA entities
        self._attr_unique_id = entity_id + "_temperature"
        self._attr_name = name + " Temperature"
        self._attr_device_class = SensorDeviceClass.TEMPERATURE
        self._attr_state_class = SensorStateClass.MEASUREMENT
        value_and_scale: Optional[datetime.datetime] = (
            parse_temperature_from_coordinator(coordinator, entity_id)
        )
        self._attr_native_value = self._get_temperature_value(value_and_scale)
        self._attr_native_unit_of_measurement = self._get_temperature_scale(value_and_scale)
        self._attr_suggested_display_precision: 1
        _LOGGER.debug(
            "Coordinator init: %s: %s %s precision: %s", 
            self._attr_name,
            self._attr_native_value,
            self._attr_native_unit_of_measurement,
            self._attr_suggested_display_precision,
        )
        self._attr_device_info = (
            {
                "identifiers": {media_player_device_id},
                "via_device": media_player_device_id,
            }
            if media_player_device_id
            else None
        )
inger147 commented 1 month ago

In alexa_entity.py ~line 438, can you add the following _LOGGER.debug command, restart and check your logs for the debug logs for "parse_value_from_coordinator"?

Sure, this morning after I added that debug line here's what I'm getting:

2024-09-15 08:50:22.495 DEBUG (MainThread) [custom_components.alexa_media.alexa_entity] parse_value_from_coordinator cap_state: {'value': 74.0, 'scale': 'FAHRENHEIT'}

And here's the preciseTemperature value from the same log this morning:

'{"namespace":"Alexa.TemperatureSensor","name":"preciseTemperature","value":{"value":74.34375,"scale":"FAHRENHEIT"},"timeOfSample":"2024-09-15T12:50:14.818Z"}'

inger147 commented 1 month ago

You can try adding self._attr_suggested_display_precision: 1 in alexa_media/sensor.py ~line 269 but I'm not sure it will fix the issue:

I made this change, but after restarting HA the UI still shows 74.0, and in a new debug log, the preciseTemperature entry is still the only "74." value that isn't 74.0.

'{"namespace":"Alexa.TemperatureSensor","name":"preciseTemperature","value":{"value":74.4453125,"scale":"FAHRENHEIT"},"timeOfSample":"2024-09-15T13:19:01.194Z"}'

danielbrunt57 commented 1 month ago

That code change I posted actually generated a weird error (__attr.suggested_display_precision doesn't exist) on my system that I initially did not see. (Note the double _ in front of attr) Try this instead:

class TemperatureSensor(SensorEntity, CoordinatorEntity):
    """A temperature sensor reported by an Echo."""

    def __init__(self, coordinator, entity_id, name, media_player_device_id):
        """Initialize temperature sensor."""
        super().__init__(coordinator)
        self.alexa_entity_id = entity_id
        # Need to append "+temperature" because the Alexa entityId is for a physical device
        # and a single physical device can have multiple HA entities
        self._attr_unique_id = entity_id + "_temperature"
        self._attr_name = name + " Temperature"
        self._attr_device_class = SensorDeviceClass.TEMPERATURE
        self._attr_state_class = SensorStateClass.MEASUREMENT
        self._attr_device_info = (
            {
                "identifiers": {media_player_device_id},
                "via_device": media_player_device_id,
            }
            if media_player_device_id
            else None
        )

    @callback
    def _handle_coordinator_update(self) -> None:
        """Handle updated data from the coordinator."""
        value_and_scale = parse_temperature_from_coordinator(
            self.coordinator, self.alexa_entity_id
        )
        self._attr_native_value = self._get_temperature_value(value_and_scale)
        self._attr_native_unit_of_measurement = self._get_temperature_scale(value_and_scale)
        self._attr_suggested_display_precision = "1"
        _LOGGER.debug(
            "Coordinator update: %s: %s %s precision: %s", 
            self._attr_name,
            self._attr_native_value,
            self._attr_native_unit_of_measurement,
            self._attr_suggested_display_precision,
        )
        super()._handle_coordinator_update()

    def _get_temperature_value(self, value) -> float: 
        if value and "value" in value:
            _LOGGER.debug("TemperatureSensor value: %s", value.get("value"))
            return value.get("value")
        return None

    def _get_temperature_scale(self, value) -> str:
        if value and "scale" in value:
            _LOGGER.debug("TemperatureSensor scale: %s", value.get("scale"))
            if value.get("scale") == "CELSIUS":
                return UnitOfTemperature.CELSIUS
            if value.get("scale") == "FAHRENHEIT":
                return UnitOfTemperature.FAHRENHEIT
            if value.get("scale") == "KELVIN":
                return UnitOfTemperature.KELVIN
        return None
inger147 commented 1 month ago

I didn't get any errors the first time, but I did add the quotes around the "1", restarted with debug logging on, and there looks to be no change - the UI and all entries in the log still show 75.0 Fahrenheit, except for the preciseTemperature reading in the log which shows 75.34375.

danielbrunt57 commented 1 month ago

I didn't get any errors the first time, but I did add the quotes around the "1", restarted with debug logging on, and there looks to be no change - the UI and all entries in the log still show 75.0 Fahrenheit, except for the preciseTemperature reading in the log which shows 75.34375.

Did you simply edit that one line (self._attr_suggested_display_precision = "1") in what you already had? There are other changes in the class like def _get_temperature_value(self, value) -> float:, etc.

danielbrunt57 commented 1 month ago

In my Alexa Echo, I changed the temperature unit from °C to °F and in the Alexa app I see the temp in Fahrenheit in the app but Amazon is still sending the Celsius value to AMP. But I just had another idea on how I can test Fahrenheit on my end.
I'll change:

            if value.get("scale") == "CELSIUS":
                return UnitOfTemperature.CELSIUS

to:

            if value.get("scale") == "CELSIUS":
                return UnitOfTemperature.FAHREHEIT

and see what HA does with it...