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

MiScale V2 - multiple sensor updates from one use of scale #617

Closed
borpin opened this issue Jan 9, 2022 · 28 comments
Closed

MiScale V2 - multiple sensor updates from one use of scale #617

borpin opened this issue Jan 9, 2022 · 28 comments
Labels
enhancement New feature or request fixed in beta This issue is fixed in the current beta release

Comments

@borpin
Copy link

borpin commented Jan 9, 2022

I am seeing the 2 sensors (weight and Impedance) being updated multiple times when the scale is used.

Can a 'delay' be introduced such that only one update is generated from each occurrence of the scale being used? Perhaps a configuration item for the 'dwell' period?

It would also be useful to have a 'combined' sensor as the weight and impedance are intrinsically linked. Perhaps a new sensor of scale_reading with the state of ok and the attributes of timestamp, weight, and impedance.

@Ernst79 Ernst79 added the enhancement New feature or request label Jan 9, 2022
@Ernst79
Copy link
Collaborator

Ernst79 commented Jan 28, 2022

I don’t understand it exactly, how would I have to select the measurement that you want. Normally, the weight sensor would show the stabilized load, isn’t that what you need?

and about the combined sensor, when would it have the state not ok?

@borpin
Copy link
Author

borpin commented Jan 30, 2022

It seems the scale reading (with the 2 sensors values) is returned twice within a short period.

I am requesting that the sensor only responds once within a shot period of time. A check could be made to see if the second reading is exactly the same as the first within a short period of time. I am currently doing this using Node-RED to prevent the second reading (which is causing me other issues).

It could simply be 'unavailable' unless there is a measurement to return.

Cheers

@borpin
Copy link
Author

borpin commented Feb 15, 2022

@Ernst79 this is still an issue. As you can see, the weight and impedance sensors were updated multiple times today. I combine them when both have been received once, for my own purposes.

image

image

A second reading from a second person returned a reading once a minute for 15 minutes.

I'm using Node-RED HA flows to detect when the state changes.

@borpin
Copy link
Author

borpin commented Mar 11, 2022

Hi @Ernst79, any chance you could look at this please? I am still getting lots of readings coming through.

Key issue is the Multiple sensor updates and the weight and impedance out of sync.

I also think adding a sensor that returns an OK and the weight and impedance as attributes would be a major enhancement.

Kind regards

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 11, 2022

Could you try the following, in sensor.py, change line 863-874 (only the def collect has changed). (Note, this only fixes the Weight sensor of course, but if it works, we can use it for the impedance sensor as well)

from

class WeightSensor(InstantUpdateSensor):
    """Representation of a Weight sensor."""

    def __init__(self, config, key, devtype, firmware, description, manufacturer=None):
        """Initialize the sensor."""
        super().__init__(config, key, devtype, firmware, description, manufacturer)

    def collect(self, data, period_cnt, batt_attr=None):
        """Measurements collector."""
        if self.enabled is False:
            self.pending_update = False
            return

to

class WeightSensor(InstantUpdateSensor):
    """Representation of a Weight sensor."""

    def __init__(self, config, key, devtype, firmware, description, manufacturer=None):
        """Initialize the sensor."""
        super().__init__(config, key, devtype, firmware, description, manufacturer)

    def collect(self, data, period_cnt, batt_attr=None):
        """Measurements collector."""
        state = self._state
        if self.enabled is False or state == data[self.entity_description.key]:
            self.pending_update = False
            return

@borpin
Copy link
Author

borpin commented Mar 11, 2022

Ok yes that is better.

I noticed the impedance is returned in the attributes of the weight sensor. However, it is the previous impedance value, not the new one.

I also notice that the impedance seems to be 6 seconds later than the weight update and also seems to wait for the 'weight_removed' to be true.

image

image

image

@borpin
Copy link
Author

borpin commented Mar 11, 2022

Thinking about this again, how about the weight_removed sensor having the weight and impedance added as attributes?

@borpin
Copy link
Author

borpin commented Mar 15, 2022

No sorry, that change is worse. Doesn't always report the weight now.

@borpin
Copy link
Author

borpin commented Mar 15, 2022

I have enabled debug - this is what I get in the logs (I have removed your change).

2022-03-15 07:04:49 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 84.95, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f013a00005e42', 'rssi': -59, 'data': True}
2022-03-15 07:04:49 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 84.95, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f013a00005e42', 'rssi': -59, 'data': True}
2022-03-15 07:04:49 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 85.35, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f013b0000ae42', 'rssi': -62, 'data': True}
2022-03-15 07:04:49 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 85.35, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f013b0000ae42', 'rssi': -62, 'data': True}
2022-03-15 07:04:49 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f013b00008642', 'rssi': -59, 'data': True}
2022-03-15 07:04:49 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f013b00008642', 'rssi': -59, 'data': True}
2022-03-15 07:04:50 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f020000008642', 'rssi': -60, 'data': True}
2022-03-15 07:04:50 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f020000008642', 'rssi': -60, 'data': True}
2022-03-15 07:04:51 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f020100008642', 'rssi': -61, 'data': True}
2022-03-15 07:04:51 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 0, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0204b20705040f020100008642', 'rssi': -61, 'data': True}
2022-03-15 07:04:52 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 1, 'weight': 85.15, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0224b20705040f020100008642', 'rssi': -62, 'data': True}
2022-03-15 07:04:52 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 1, 'weight': 85.15, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0224b20705040f020100008642', 'rssi': -62, 'data': True}
2022-03-15 07:04:54 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 1, 'weight': 85.15, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0224b20705040f0201feff8642', 'rssi': -62, 'data': True}
2022-03-15 07:04:54 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 1, 'weight': 85.15, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0224b20705040f0201feff8642', 'rssi': -62, 'data': True}
2022-03-15 07:04:57 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 1, 'weight': 85.15, 'impedance': 428, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0226b20705040f0201ac018642', 'rssi': -69, 'data': True}
2022-03-15 07:04:57 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 0, 'stabilized': 1, 'weight': 85.15, 'impedance': 428, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '0226b20705040f0201ac018642', 'rssi': -69, 'data': True}
2022-03-15 07:04:59 DEBUG (MainThread) [custom_components.ble_monitor.binary_sensor] Data binary sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 1, 'stabilized': 1, 'impedance': 428, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '02a6b20705040f0208ac018642', 'rssi': -59, 'data': True}
2022-03-15 07:04:59 DEBUG (MainThread) [custom_components.ble_monitor.sensor] Data measuring sensor received: {'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 1, 'stabilized': 1, 'impedance': 428, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '02a6b20705040f0208ac018642', 'rssi': -59, 'data': True}

This is what I see as state changes in Node-RED;

image

Looking at this it seems you want the reading when

  1. Stabilized = 1
  2. there is weight data
  3. there is impedance data

The person needs to wait for the white line to start flashing for the impedance data to be gathered (I think).

So, the weight appears first, then the impedance data.

The integration needs to wait until the weight is removed before reporting either.

If the weight is removed too soon, report weight and impedance is unavailable. If impedance data has been gathered report both (is my suggestion) :)

@borpin
Copy link
Author

borpin commented Mar 15, 2022

On the basis of the above comments, I suggest the following change -

if is_stabilized and not weight_removed:
result.update({"weight": weight})
if has_impedance:
result.update({"impedance": impedance})

    if is_stabilized and (weight_removed == 0) and has_impedance:
        result.update({"weight": weight})
        result.update({"impedance": impedance})

    # if is_stabilized and not weight_removed:
    #     result.update({"weight": weight})

    # if is_stabilized and has_impedance:
    #     result.update({"impedance": impedance})

This results in the impedance and weight sensors reporting once, almost simultaneously. If the scale is not allowed to complete the impedance calculation (indicated by flashing white bars), then the sensors do not report at all.

This might be undesireable from your perspective.

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 15, 2022

I have no objection, but I don't have this scale, so that's easy for me to say. I propose you test it yourself for a couple of days and if you think it works ok, we will make this change. I can't test it myself unfortunately, as I don't have the scale.

The only thing I want to ask you than is to clearly describe the old behavior and the new behavior, such that we can inform the users about the change.

@borpin
Copy link
Author

borpin commented Mar 15, 2022

Ok thanks.

I have tested this a couple of times and it has worked reliably. I have also tested stepping off before the impedance has been calculated which results in the other 2 sensors updating, but not the weight or impedance.

Can I suggest adding any stabilized weight received to the weight_removed sensor, thus the stabilized weight will be available if the impedance is not calculated? I'm not sure how this could be done as the data is not in the packets from the scale at that time.

How about this;

Old behavior

The scale reports multiple ble packets each time it is used and sends the stabilized weight before the impedance has been calculated. The scale also reports an impedance value (if calculated) when the weight is removed.

The integration reported on each ble data packet received (via different sensors). This resulted in the weight and impedance sensors being updated multiple times and at different times with the impedance attribute in the weight sensor to hold the old value initially.

New behavior

The person using the scale must wait until the white bars flash - this indicates the impedance has been calculated. If they do not wait, neither the weight sensor or impedance sensor will update.

The integration will report once per activation of the scale with a stabilized weight (weight sensor) and impedance (impedance sensor). These sensors will update almost simultaneously.

@borpin
Copy link
Author

borpin commented Mar 15, 2022

Ah, this needs to be for the V2 only!

@borpin borpin changed the title MiScale - multiple sensor updates from one use of scale MiScale V2 - multiple sensor updates from one use of scale Mar 15, 2022
@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 15, 2022

Regarding your request about adding an attribute to the "weight removed" binary sensor, we might be able to use something like this.

        if self.entity_description.key == "weight removed":
            if "stabilized" in data:
                if data["stabilized"] and data["weight removed"]:
                    self._extra_state_attributes["weight"] = data["non-stabilized weight"]
{'non-stabilized weight': 85.15, 'weight unit': 'kg', 'weight removed': 1, 'stabilized': 1, 'impedance': 428, 'type': 'Mi Scale V2', 'firmware': 'Mi Scale V2', 'mac': '5CCAD3755549', 'packet': '02a6b20705040f0208ac018642', 'rssi': -59, 'data': True}

Add the code behind this line, here

self._extra_state_attributes["number_of_sectors"] = data["number of sectors"]

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 15, 2022

Please check if 8.0.4-beta works for you. Weight attribute is added as described above.

@Ernst79 Ernst79 added the fixed in beta This issue is fixed in the current beta release label Mar 15, 2022
@borpin
Copy link
Author

borpin commented Mar 15, 2022

Please check if 8.0.4-beta works for you.

For weight and impedance sensors if the impedance is calculated, then yes.

If I step off the scale before the impedance is calculated - not quite.

The stabilized weight is set in the unstabilized_weight sensor, but the impedance is that of the previous reading. This should be removed from the attributes or set to unavailable

If I step off before the weight has stabilized, the unstabilized_weight sensor correctly shows an unstabilized weight and the stabilized attribute is false. Impedance value is still the last good reading.

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 15, 2022

So, we should make something that sets the impedance attribute (and weight attribute???) of the unstabilized weight sensor to unavailable when the scale is not stabilized, and update it when it is stabilized + weight removed from the scale? Right?

But what about the weight sensor and impedance sensor? Do these also have to go to unavailable? Or should these stick with the old values till they got updated with new values. Normally, I would say the last, to avoid gaps in the data, but that would mean that you can see an old impedance value that does not correspond to the weight. Or do you want something that the weight sensor isn't updated till the impedance sensor is calculated.

@borpin
Copy link
Author

borpin commented Mar 16, 2022

I think the attribute should be set to unavailable initially, then when the data appears, set to that new value. The fact the impedance data is reported is enough of a condition to add it to that sensor.

@borpin
Copy link
Author

borpin commented Mar 16, 2022

Ah, didn't read your edit. I think the unstabilized sensor can have all the data added to it as it arrives but be unavailable until it does for that scale session. As long as that is clear to the user.

@borpin
Copy link
Author

borpin commented Mar 16, 2022

But what about the weight sensor and impedance sensor? Do these also have to go to unavailable? Or should these stick with the old values till they got updated with new values.

As long as you do not update the sensors, they can stay unchanged internally. With these changes, I just see them both update when the good data has arrived so you never get weight updated without impedance being updated as well (which is what I was trying to achieve).

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 16, 2022

Ah, didn't read your edit. I think the unstabilized sensor can have all the data added to it as it arrives but be unavailable until it does for that scale session. As long as that is clear to the user.

Yes, I understand, But we need to figure out how to define "a new scale session", especially what is triggering a new session. But it might be sufficient to just set it to unavailable when the scale is not stabilized.

Could you try changing this lines

if self.entity_description.key == "non-stabilized weight":
self._extra_state_attributes["stabilized"] = bool(data["stabilized"])
if "weight removed" in data:
self._extra_state_attributes["weight removed"] = bool(
data["weight removed"]
)

to

        if self.entity_description.key == "non-stabilized weight":
            self._extra_state_attributes["stabilized"] = bool(data["stabilized"])
            if "weight removed" in data:
                self._extra_state_attributes["weight removed"] = bool(
                    data["weight removed"]
                )
            if data["stabilized"] == 0:
                self._extra_state_attributes["impedance"] = "unavailable"

@borpin
Copy link
Author

borpin commented Mar 16, 2022

But we need to figure out how to define "a new scale session"

On the basis of the messages captured above, the first message is Stabilized = 0 and the last is Stabilized = 1 with weight removed = 1. I think at that point you could say the current session has ended.

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 16, 2022

That should be covered with the above change. Could you check if this works for you?

@borpin
Copy link
Author

borpin commented Mar 16, 2022

Might a check to see if impedance is in the data or and if not then set to unavailable?

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 17, 2022

Please try with 8.0.5-beta. It should now set it to unavailable if impedance is not in data

@borpin
Copy link
Author

borpin commented Mar 17, 2022

Hi @Ernst79

Tested and the condition needs a slight tweak;

            if "weight removed" in data:
                self._extra_state_attributes["weight removed"] = bool(
                    data["weight removed"]
                )
                if "impedance" not in data and data["type"] == "Mi Scale V2" and data["weight removed"] == 0:
                    self._extra_state_attributes["impedance"] = "unavailable"

tested

  • waited for full cycle - all 4 sensors updated with impedance value in the non_stabilized sensor
  • stabilized weight - no impedance. Only weight_removed and non_stabilized sensors update. Impedance is unavailable
  • unstabilized weight - Only weight_removed and non_stabilized sensors update. Impedance is unavailable

Works as expected.

Many thanks for your help and engagement :)

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 17, 2022

Ok, will change that in the final release tomorrow.

@Ernst79
Copy link
Collaborator

Ernst79 commented Mar 18, 2022

8.1.0 has been released as final. Thanks for the sponsoring!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fixed in beta This issue is fixed in the current beta release
Projects
None yet
Development

No branches or pull requests

2 participants