Skip to content

New feature: adding scores for the last trip and ratio ev_distance / distance for statistics#160

Open
julesxxl wants to merge 12 commits into
pytoyoda:mainfrom
julesxxl:main
Open

New feature: adding scores for the last trip and ratio ev_distance / distance for statistics#160
julesxxl wants to merge 12 commits into
pytoyoda:mainfrom
julesxxl:main

Conversation

@julesxxl
Copy link
Copy Markdown

Must be merged AFTER the corresponding PR in pytoyoda repo. That will add the scores for the last trip as a sensor (global score as global value and sub-scores as properties). Global score, acceleration score, braking score, advice score and constant speed score.

Plus: ev_distance / distance percentage for each statistics sensor (interesting if your insurance is based on this value, so that you can get a lower price the next year).

(All checks passed here.)

ev_percentage score (yaris_none because I hadn't specified the name in the .json)

@julesxxl julesxxl mentioned this pull request Sep 11, 2025
@julesxxl
Copy link
Copy Markdown
Author

OK, The fist workflow failed because I had already put the new version of pytoyoda... which is required before this PR can be merged.

@CM000n
Copy link
Copy Markdown
Member

CM000n commented Oct 2, 2025

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new feature to display driving scores from the last trip and an EV distance percentage in statistics. The changes are well-structured and cover documentation, translations, and the core logic. I've identified a few issues, mainly related to sensor configuration, missing capability checks, and minor bugs in calculations that could lead to incorrect data or errors. My review includes suggestions to fix these issues to ensure the new feature is robust and correctly integrated.

Comment on lines +102 to +114
SCORES_ENTITY_DESCRIPTION = ToyotaScoresEntityDescription(
key="score",
translation_key="score",
icon="mdi:car-info",
entity_category=EntityCategory.DIAGNOSTIC,
device_class=SensorDeviceClass.ENUM,
state_class=None,
value_fn=lambda vehicle: vehicle.last_trip.score,
attributes_fn=lambda vehicle: format_scores_attributes(
vehicle.last_trip,
vehicle._vehicle_info, # noqa : SLF001
),
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The SCORES_ENTITY_DESCRIPTION is misconfigured for a sensor that reports a numeric score.

  • device_class is SensorDeviceClass.ENUM, which is for sensors with a fixed set of string states. For a numeric score (0-100), this is incorrect. It should be None.
  • state_class should be SensorStateClass.MEASUREMENT to indicate the value is a measurement.

These changes are needed for the sensor to be represented correctly in Home Assistant. Additionally, in create_sensor_configurations at lines 267-268, you should set the units for the score sensor to PERCENTAGE, as it is currently None.

Suggested change
SCORES_ENTITY_DESCRIPTION = ToyotaScoresEntityDescription(
key="score",
translation_key="score",
icon="mdi:car-info",
entity_category=EntityCategory.DIAGNOSTIC,
device_class=SensorDeviceClass.ENUM,
state_class=None,
value_fn=lambda vehicle: vehicle.last_trip.score,
attributes_fn=lambda vehicle: format_scores_attributes(
vehicle.last_trip,
vehicle._vehicle_info, # noqa : SLF001
),
)
SCORES_ENTITY_DESCRIPTION = ToyotaScoresEntityDescription(
key="score",
translation_key="score",
icon="mdi:car-info",
entity_category=EntityCategory.DIAGNOSTIC,
device_class=None,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda vehicle: vehicle.last_trip.score,
attributes_fn=lambda vehicle: format_scores_attributes(
vehicle.last_trip,
vehicle._vehicle_info, # noqa : SLF001
),
)

Comment on lines +123 to +125
"EV_percentage": int((statistics.ev_distance / statistics.distance) * 100)
if statistics.ev_distance and statistics.distance
else None,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The calculation for EV_percentage has a subtle bug. If statistics.ev_distance is 0, the condition if statistics.ev_distance and statistics.distance will be false, and the attribute will be None. However, the percentage should be 0. The check should be changed to handle this case correctly and be more explicit to avoid division by zero.

Suggested change
"EV_percentage": int((statistics.ev_distance / statistics.distance) * 100)
if statistics.ev_distance and statistics.distance
else None,
"EV_percentage": int((statistics.ev_distance / statistics.distance) * 100)
if statistics.distance and statistics.ev_distance is not None
else None,

Comment on lines +149 to +160
return {
"score_acceleration": last_trip.score_acceleration
if last_trip.score_acceleration
else None,
"score_braking": last_trip.score_braking
if last_trip.score_braking
else None,
"score_advice": last_trip.score_advice if last_trip.score_advice else None,
"score_constant_speed": last_trip.score_constant_speed
if last_trip.score_constant_speed
else None,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The logic for formatting score attributes is buggy. A truthiness check on the score value (e.g., if last_trip.score_acceleration) will incorrectly treat a valid score of 0 as a falsy value, causing it to be replaced with None. This can be simplified and corrected by directly returning the score attributes, as None is an acceptable value if the score is not available.

        return {
            "score_acceleration": last_trip.score_acceleration,
            "score_braking": last_trip.score_braking,
            "score_advice": last_trip.score_advice,
            "score_constant_speed": last_trip.score_constant_speed,
        }

Comment thread README.md
@@ -118,9 +122,23 @@ All values will show `None` if no data is available for the period.
| `Average_fuel_consumed` | The average fuel consumption in the respective period (can be l/100km or mpg). |
| `EV_distance` | The driving distiance in EV mode in the respective period . |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's a small typo in the description. It should be "distance" instead of "distiance".

Suggested change
| `EV_distance` | The driving distiance in EV mode in the respective period . |
| `EV_distance` | The driving distance in EV mode in the respective period . |



class ScoresData(TypedDict):
"""Representing Vehicle data."""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The docstring for ScoresData appears to be a copy-paste from VehicleData. It would be clearer if it specifically mentioned scores.

Suggested change
"""Representing Vehicle data."""
"""Representing Scores data."""

native_unit: PERCENTAGE,
suggested_unit: PERCENTAGE,
) -> None:
"""Initialise the ToyotaStatisticsSensor class."""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This docstring seems to be a copy-paste from ToyotaStatisticsSensor. It should refer to ToyotaScoresSensor.

Suggested change
"""Initialise the ToyotaStatisticsSensor class."""
"""Initialise the ToyotaScoresSensor class."""

@pytoyoda pytoyoda deleted a comment from gemini-code-assist Bot Oct 2, 2025
Comment thread pyproject.toml Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please bump the pytoyoda version accordingly to the manifest.json value.

Comment thread custom_components/toyota/manifest.json Outdated
"issue_tracker": "https://github.com/pytoyoda/ha_toyota/issues",
"requirements": ["pytoyoda>=4.0.1,<5.0", "arrow"],
"version": "v2.0.16"
"requirements": ["pytoyoda>=4.0.2,<5.0", "arrow"],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please bump the pytoyoda version to 4.1.0 instead of 4.0.2

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's done! 😊

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhmm, wierd. I stille see 4.0.2 instead of 4.1.0 here ^^

@CM000n CM000n linked an issue Oct 2, 2025 that may be closed by this pull request
@CM000n CM000n assigned CM000n and julesxxl and unassigned CM000n Oct 2, 2025
@CM000n
Copy link
Copy Markdown
Member

CM000n commented Oct 6, 2025

Hey @julesxxl, do you need any assistance in finalizing the PR? 😊

@julesxxl
Copy link
Copy Markdown
Author

julesxxl commented Oct 6, 2025

Hey @julesxxl, do you need any assistance in finalizing the PR? 😊

@CM000n : I think it's ok

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hybrid score

2 participants