Skip to content

Add mower progress to StatsEvent - #1771

Open
monsivar wants to merge 5 commits into
DeebotUniverse:devfrom
monsivar:feature/mower-stats-progress
Open

monsivar wants to merge 5 commits into
DeebotUniverse:devfrom
monsivar:feature/mower-stats-progress

Conversation

@monsivar

@monsivar monsivar commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add support for mowing job progress statistics reported by GOAT mowers, with the behavior enabled explicitly for the GOAT O1200 LiDAR (2i0fns).

For the O1200, observed stats semantics are:

  • area: planned total mowing area
  • mowedArea: area mowed so far
  • time: estimated total mowing duration

This change preserves compatibility for existing devices while exposing the additional data needed by consumers to calculate mowing progress.

Changes

  • Add optional keyword-only StatsEvent.mowed_area
  • Parse mowedArea from onStats
  • Parse mowedArea from GetStats
  • Add CapabilityStats.mowing_job_progress, defaulting to False
  • Enable mowing_job_progress only for hardware class 2i0fns
  • Keep existing mower models such as 5xu9h3 on their current stats semantics
  • Add focused command/message and hardware capability tests

Consumers can derive progress for devices with mowing_job_progress=True as:

mowed_area / area * 100

Verification

Observed on a GOAT O1200 LiDAR during a mowing job:

  • area=492475 -> 49.2475 m² planned area
  • mowedArea=28699 -> 2.8699 m² mowed
  • progress ≈ 5.83%, shown as 6% in the Ecovacs app
  • time=2304 -> 38m24s estimated total mowing duration

Relevant stats and hardware tests pass locally.

@codecov

codecov Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.31%. Comparing base (5453eba) to head (95c4491).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1771      +/-   ##
==========================================
+ Coverage   96.26%   96.31%   +0.04%     
==========================================
  Files         161      161              
  Lines        6399     6401       +2     
  Branches      368      368              
==========================================
+ Hits         6160     6165       +5     
+ Misses        172      169       -3     
  Partials       67       67              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed

codspeed Bot commented Aug 21, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 226 untouched benchmarks


Comparing monsivar:feature/mower-stats-progress (95c4491) with dev (5453eba)

Open in CodSpeed

@monsivar

Copy link
Copy Markdown
Contributor Author

Downstream Home Assistant implementation is now available as a draft PR for visibility and dependency tracking: home-assistant/core#180054

It intentionally remains in draft until this PR is merged and included in a published deebot-client release. At that point the HA branch can bump the dependency, run final validation against the released client version, and be marked ready for review.

@@ -30,6 +30,7 @@ def _handle_body_data_dict(
area=data.get("area"),

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.

Suggested change
area=data.get("area"),
area=data.get("area", data.get("mowedArea")),

I expect area is not there if mowedArea is there. So this one would be just falling back the mowedArea when area is not available

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

On the O1200 both fields are present in the same onStats payload. In the capture used for this PR, area=492475 is the planned total area, while mowedArea=28699 is the area completed so far. So mowedArea is not a fallback for area on this device; they represent different values. That's why I kept them separate. I can add the captured payload shape to the test if that would make the distinction clearer.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants