Skip to content
This repository has been archived by the owner on Jun 15, 2023. It is now read-only.

"Battery state error" when integration is used with G30 Edge #6

Open
p4mr opened this issue May 8, 2021 · 22 comments
Open

"Battery state error" when integration is used with G30 Edge #6

p4mr opened this issue May 8, 2021 · 22 comments

Comments

@p4mr
Copy link

p4mr commented May 8, 2021

The below error is generated every 20 seconds when used with a Eufy G30 Edge RoboVac (model T2251)

Logger: homeassistant
Source: custom_components/eufy_vacuum/property.py:36
Integration: Integration to Eufy Vacuum (documentation, issues)
First occurred: 17:41:09 (1 occurrences)
Last logged: 17:41:09

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 673, in _update_entity_states
    await asyncio.gather(*tasks)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 321, in async_update_ha_state
    self._async_write_ha_state()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 370, in _async_write_ha_state
    attr.update(self.state_attributes or {})
  File "/usr/src/homeassistant/homeassistant/components/vacuum/__init__.py", line 279, in state_attributes
    data = super().state_attributes
  File "/usr/src/homeassistant/homeassistant/components/vacuum/__init__.py", line 179, in state_attributes
    data[ATTR_BATTERY_ICON] = self.battery_icon
  File "/usr/src/homeassistant/homeassistant/components/vacuum/__init__.py", line 269, in battery_icon
    if self.status is not None:
  File "/config/custom_components/eufy_vacuum/vacuum.py", line 116, in status
    if self.robovac.error_code != robovac.ErrorCode.NO_ERROR:
  File "/config/custom_components/eufy_vacuum/property.py", line 36, in __get__
    value = self.type_cast(value)
  File "/usr/local/lib/python3.8/enum.py", line 339, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/lib/python3.8/enum.py", line 662, in __new__
    raise ve_exc
ValueError: 0 is not a valid ErrorCode

The outcome (failure to read the battery state) can be seen from the entity when added to Lovelace (vacuum is named Lilo in this example)

image

@pbulteel
Copy link
Owner

Right, so that error is due to it not being able to get the proper status off the battery. I'll look at it. Might have you try a modified file so I can see what data is being returned.

@gmac0612
Copy link

Hi,

I have a regular G30 model (T2250) giving essentially the same log output.

Commands all work, but does not report battery or current status.

More than willing to subject it to a little experimentation.

@gmac0612
Copy link

I've done a little experimenting.

in vacuum.py, Commenting out lines 116 & 117 and then changing 118 from an elif to an if will sort of make it work. It's basically just bypassing the error handler. I now have battery status but the condition returned is incorrect. It shows as "returning" when in reality it is idle and fully charged in the dock.

It looks like it is just a matter of getting all the right workstatus parts matched up, but I am unsure how to go about reading them directly as the machine changes state.

@gmac0612
Copy link

More uneducated blind tweaking:

Instead of the above, commenting out lines 116-119 inclusive & changing 120 from elif to if in vacuum.py results in the correct status being returned. Tested with cleaning, idle, returning and docked. Commands work, fan modes return & are selectable without error and the battery reports with no issue.

This works enough for me now, but will watch this issue and help with testing where possible in order to have it fixed properly.

@techguydave
Copy link

techguydave commented Jun 5, 2021

Thanks for the comment, gmac! Your instructions worked and now I have full functionality with my G30. Hopefully a full fix gets implemented. I'd be happy to help test any new releases.

image

@p4mr
Copy link
Author

p4mr commented Jun 5, 2021

Have tested the same as above, and can confirm it works with the 2 x G30 Edge devices as well.

@pbulteel Does this look like a suitable fix, or does the removal of the earlier lines of code cause issues with other models ?

@gmac0612
Copy link

gmac0612 commented Jun 6, 2021

Have tested the same as above, and can confirm it works with the 2 x G30 Edge devices as well.

@pbulteel Does this look like a suitable fix, or does the removal of the earlier lines of code cause issues with other models ?

Hey - glad to see my poking around has had some use!

I am sure there is a more elegant way to fix this than simply gutting problematic sections of the code though. We'd need Patrick or another person properly versed in Python to take a look.

@pbulteel
Copy link
Owner

Hi guys,

Life got a little busy so I wasn't able to look into all of these, though I knew I had things waiting on me. I'll go through the code and see if @gmac0612's work can be used with all the other models.

Meanwhile, hang tight as I start looking into this. I also was doing quite a bit of research on this while looking into Tuya's integration, etc.

@pbulteel
Copy link
Owner

I looked at the changes you did, at the code and I see an issue with doing this. I will need to look into it deeper, but the change will need to be done in multiple places (tuya.py and robovac.py as well) to account for this. I may send you some debug versions of these to try to capture the proper values - so that I can then take them into account and properly implement this.

@gmac0612
Copy link

Figured as much,

More than happy to guinea pig any changes 🙂

@p4mr
Copy link
Author

p4mr commented Jun 15, 2021

Ditto - Always happy to test changes

@tri94
Copy link

tri94 commented Aug 8, 2021

Hi i have the same issue. as the others above happy to test any fixes

Thanks

@xBourner
Copy link

xBourner commented Sep 2, 2021

@gmac0612 this helped me to get the correct state but my battery state is not okay.
it only shows % and state is null. im not sure if this worked before when i first set up the integration but i think so.

Is there any way to fix this or is this maybe a caching problem?

i have a 15C Max and everything works but not battery state

EDIT: for some kind of reason everything works now. Maybe it takes some runs to get the correct battery state.
Thanks for this component!

@ilikecaterpillars
Copy link

Just to add to this, I've also added the changes that @gmac0612 mentioned and it all works for me, status-wise. I've got a g30 Edge and also a 30c, both of which seem to be doing what they're supposed to with these changes. I'll give it a full test over the weekend though, just to make sure.

@lennartgrunau
Copy link

Made the changes to vacuum.py as proposed by @gmac0612 and it seems to be working for my 15C.
Wi-Fi Version: 1.1.5
MCU Version: 1.1.4
Thanks!

@gmac0612
Copy link

Good to see a few more people getting this to work.

Strongly suggest not updating any components of the vac. Mine is blocked from 'net access and continues to work locally as it should.

@harphere
Copy link

@gmac0612 , thanks a lot! Just tried your suggestion with my new G30 and all looks great now.

@glassbox-sco
Copy link

More uneducated blind tweaking:

Instead of the above, commenting out lines 116-119 inclusive & changing 120 from elif to if in vacuum.py results in the correct status being returned. Tested with cleaning, idle, returning and docked. Commands work, fan modes return & are selectable without error and the battery reports with no issue.

This works enough for me now, but will watch this issue and help with testing where possible in order to have it fixed properly.

Thank you for this, have now got my G30 Edge running fine and all info seems to be getting reported back. Hopefully this can be implemented into the code and cleaned up.
Thanks to everyone involved in getting the Eufy robovacs working.

@DuPunk
Copy link

DuPunk commented Aug 13, 2022

I was able to get proper reporting from a X8 using the changes to the vacuum.py. not a perfect solution but makes the device look a little more integrated.

@h4nnes
Copy link

h4nnes commented Sep 14, 2022

More uneducated blind tweaking:

Instead of the above, commenting out lines 116-119 inclusive & changing 120 from elif to if in vacuum.py results in the correct status being returned. Tested with cleaning, idle, returning and docked. Commands work, fan modes return & are selectable without error and the battery reports with no issue.

This works enough for me now, but will watch this issue and help with testing where possible in order to have it fixed properly.

Thanks for this. With this my G10 is working. I have only a few errors in the log (althoug heverything is working fine):
[custom_components.eufy_vacuum.tuya] 'utf-8' codec can't decode byte 0x86 in position 3: invalid start byte [custom_components.eufy_vacuum.tuya] Failed to decrypt message from xxx
Any idea how to fix this?

@garettharnish
Copy link

garettharnish commented Nov 4, 2022

To fix the correctly, my guess is we just have to change how ErrorCode enum is done.

My G30 (T2250) returns:
{'1': True, '2': False, '5': 'Nosweep', '15': 'completed', '101': True, '102': 'Standard', '104': 100, '106': 0, '107': False, '109': 0, '110': 0, '111': 4, '122': 'Nosweep', '128': 'default', '130': 'No_suction', '131': False, '132': 1522, '133': 22, '134': 1, '135': True, '137': 0, '140': 'serial#'}

1 is POWER so I assume True means it is charging?
2 is PLAY_PAUSE so False likely means it isn't paused (which is isnt')
5 is WORK_MODE and Nosweep matches class WorkMode
15 is WORK_STATUS, completed is valid according to class WorkStatus
101 is listed as GO_HOME. It's True, which it is home so that's good.
102 is CLEAN_SPEED. Standard looks right based on class CleanSpeed.
104 is BATTERY_LEVEL and my battery is at 100% so 100 makes sense. Not sure why we'd have an issue with the battery.
106 is ERROR_CODE and we have an issue here with integer v. expected string in class ErrorCode. This is the source of the error in the initial post. We likely have to do some kind of switch depending on model type, but the Robovac class doesn't really take the model info. The eufy support site lists the error codes for the G-Series vacuums. I notice the older C-line appears to use string descriptions.

I'm assuming 0 is NO_ERROR
1 - Front Bumper Stuck (== CRASH_BAR_STUCK)
2 - Wheel Stuck (==WHEEL_STUCK)
3 - Side bush Stuck (==S_BRUSH_STUCK)
4 - Rolling Brush Stuck (==R_BRUSH_STUCK)
5 - Device trapped (by obstruction) (==STUCK_5_MIN)
6 - Device trapped (off ground)
7 - Wheel suspended
8 - Low battery (==NOT_ENOUGH_POWER)
9 - Magnetic boundary strip detected
10 - Path Tracking Sensor needs cleaning (==SENSOR_DIRTY)
21 - Auto-Empty Station blocked
22 - The device is being picked up

It also lists the S codes which I'm fairly certain aren't passed as string so are likely different:
S1 - Battery Error
S2 - Wheel Module Error
S3 - Side Brush Error
S4 - Suction Fan Error
S5 - Rolling Brush Error

So we need a different ErrorCode enum for the G-Series. A quick patch might be to change the class ErrorCode (StringEnum) to

class ErrorCode(IntEnum):
    NO_ERROR = 0
    CRASH_BAR_STUCK = 1
    WHEEL_STUCK = 2
    S_BRUSH_STUCK = 3
    R_BRUSH_STUCK = 4
    STUCK_5_MIN = 5
    STUCK_OFF_GROUND = 6
    WHEEL_SUSPENDED = 7
    NOT_ENOUGH_POWER = 8
    MAG_BND_DETECTED = 9
    SENSOR_DIRTY = 10
    AUTO_EMPTY_BLOCKED = 21
    DEVICE_PICKED_UP = 22

It also requires adding this to the imports:

from enum import IntEnum

I also modified CleanSpeed to support Turbo

class CleanSpeed(StringEnum):
    NO_SUCTION = 'No_suction'
    STANDARD = 'Standard'
    BOOST_IQ = 'Boost_IQ'
    TURBO = 'Turbo'
    MAX = 'Max'

I also added an entry for T2250 in vacuum.py, but using T2118 will work (since I just replicated it) but I also wanted to add in the Turbo Fan speed:

FAN_SPEEDS_T2250 = {
    robovac.CleanSpeed.NO_SUCTION: FAN_SPEED_OFF,
    robovac.CleanSpeed.STANDARD: FAN_SPEED_STANDARD,
    robovac.CleanSpeed.TURBO: FAN_SPEED_TURBO,
    robovac.CleanSpeed.BOOST_IQ: FAN_SPEED_BOOST_IQ,
    robovac.CleanSpeed.MAX: FAN_SPEED_MAX,
}


...

MODEL_CONFIG = {
    'T2118': {
        'fan_speeds': FAN_SPEEDS,
        'support': SUPPORT_ROBOVAC_T2118
    },
    'T2250': {
        'fan_speeds': FAN_SPEEDS_T2250,
        'support': SUPPORT_ROBOVAC_T2118
    }
}

I also commented out

        elif self.robovac.go_home:
            return STATE_RETURNING

in def status because it seems to always be true and on mine, when I hit GO_HOME, it changes the work_mode to "RECHARGING", which sets the status to "RETURNING".

We do need to figure out how to switch the ENUM depending on model to keep the support for the non-G series.

@gmac0612
Copy link

gmac0612 commented Nov 4, 2022

I've since decoupled my vac from homeassistant, but it's nice to see some substantial activity here 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests