Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Amazon Thermostat reports incorrect temperature #1890

Open
Angelos59 opened this issue Mar 24, 2023 · 56 comments
Open

Amazon Thermostat reports incorrect temperature #1890

Angelos59 opened this issue Mar 24, 2023 · 56 comments
Labels
alexapy Issue relates to the API bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed todo 🗒️

Comments

@Angelos59
Copy link

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
Copy link

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
Copy link

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 alandtse added bug Something isn't working help wanted Extra attention is needed good first issue Good for newcomers alexapy Issue relates to the API labels Apr 9, 2023
@alandtse
Copy link
Owner

alandtse commented Apr 9, 2023

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
Copy link

AlexEr89 commented Apr 9, 2023 via email

@github-actions github-actions bot removed the help wanted Extra attention is needed label Apr 10, 2023
@github-actions
Copy link

github-actions bot commented May 1, 2023

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 github-actions bot added the help wanted Extra attention is needed label May 1, 2023
@pravardhanreddy
Copy link

This issue is still present. Any fix please?

@github-actions github-actions bot removed the help wanted Extra attention is needed label Jun 23, 2023
@github-actions
Copy link

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 github-actions bot added the help wanted Extra attention is needed label Jul 14, 2023
@Angelos59
Copy link
Author

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

@github-actions github-actions bot removed the help wanted Extra attention is needed label Jul 15, 2023
@github-actions
Copy link

github-actions bot commented Aug 6, 2023

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 github-actions bot added the help wanted Extra attention is needed label Aug 6, 2023
@pravardhanreddy
Copy link

Issue is still present

@github-actions github-actions bot removed the help wanted Extra attention is needed label Aug 7, 2023
@github-actions
Copy link

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 github-actions bot added the help wanted Extra attention is needed label Aug 29, 2023
@github-actions
Copy link

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

@github-actions github-actions bot added no-issue-activity and removed help wanted Extra attention is needed no-issue-activity labels Oct 29, 2023
Copy link

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 github-actions bot added the help wanted Extra attention is needed label Nov 21, 2023
Copy link

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

@danielbrunt57
Copy link
Collaborator

danielbrunt57 commented Sep 5, 2024

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...

@github-actions github-actions bot removed the help wanted Extra attention is needed label Sep 6, 2024
@danielbrunt57
Copy link
Collaborator

danielbrunt57 commented Sep 6, 2024

@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
Copy link
Collaborator

danielbrunt57 commented Sep 6, 2024

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...

@danielbrunt57 danielbrunt57 added the help wanted Extra attention is needed label Sep 6, 2024
@inger147
Copy link

inger147 commented Sep 6, 2024

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.

@github-actions github-actions bot removed the help wanted Extra attention is needed label Sep 7, 2024
@danielbrunt57
Copy link
Collaborator

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
Copy link

inger147 commented Sep 13, 2024

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
Copy link
Collaborator

danielbrunt57 commented Sep 13, 2024

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
Copy link

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
Copy link
Collaborator

danielbrunt57 commented Sep 15, 2024

'{"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
Copy link
Collaborator

danielbrunt57 commented Sep 15, 2024

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
Copy link
Collaborator

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
Copy link
Collaborator

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
Copy link

inger147 commented Sep 15, 2024

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
Copy link

inger147 commented Sep 15, 2024

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
Copy link
Collaborator

danielbrunt57 commented Sep 16, 2024

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
Copy link

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
Copy link
Collaborator

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
Copy link
Collaborator

danielbrunt57 commented Sep 16, 2024

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...

@danielbrunt57
Copy link
Collaborator

I can also try faking the Fahrenheit value...

@inger147
Copy link

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.

Sorry, yes, I just replaced that line. This time I replaced the whole TemperatureSensor class with your code, but I still got the same result; everything ends in .0 except preciseTemperature.

@danielbrunt57
Copy link
Collaborator

danielbrunt57 commented Sep 17, 2024

So, I overrode my value and scale yet I still saw Celsius in the UI with one decimal precision.
But that's because HA's global units is Metric so the UI is converting whatever {unit, scale} to Celsius. I changed my Setting -> System -> General from Metric to US Customary:

image

and I now see the temperature in Fahrenheit:

image

image

    @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 = "2"
        _LOGGER.debug(
            "Coordinator update: %s: %s %s",
            self._attr_name,
            self._attr_native_value,
            self._attr_native_unit_of_measurement,
        )
        super()._handle_coordinator_update()

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

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

First, doublecheck that you do not have legacy settings in your configuration.yaml regarding this.


#  name: Norton Court
#  latitude: 49.175855483923094
#  longitude: -122.97057420015338
#  elevation: 6
#  unit_system: metric
#  currency: CAD
#  country: Canada
#  time_zone: "America/Vancouer"

homeassistant:
  allowlist_external_dirs:
    - /config/www

Then as per this post,
try changing your global setting from US Customary to Metric selecting Update the unit of all sensors and see what the logs and the frontend are showing you then.
image

Then change it back from Metric to US Customary selecting Update all and see what the logs and the frontend show then.

@inger147
Copy link

I checked my configuration.yaml and I did have an entry for unit_system: imperial, so I commented that out. Then I changed my Unit System from Fahrenheit to Celsius and back again, each time updating the sensors. There were still no changes that I noticed afterwards - all of the logged Fahrenheit temperatures were still rounded except preciseTemperature.

Note that before doing the above steps, I had updated to the latest AMP version, but after I updated it, I re-copied your TemperatureSensor class from a few posts back into my sensor.py file.

@danielbrunt57
Copy link
Collaborator

Damn! I'm not sure where to look now...

Copy link

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 github-actions bot added the help wanted Extra attention is needed label Oct 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
alexapy Issue relates to the API bug Something isn't working good first issue Good for newcomers help wanted Extra attention is needed todo 🗒️
Projects
None yet
Development

No branches or pull requests

8 participants