homieiot / convention

🏡 The Homie Convention: a lightweight MQTT convention for the IoT
https://homieiot.github.io/
Other
710 stars 59 forks source link

Percentage Property #190

Closed szwenni closed 4 years ago

szwenni commented 4 years ago

It would be nice to have a property called percentage. The initial thought on this was that OH homie binding only has support for integer and float values but in the generic OH binding there is also a percentage support. I now implemented the percentage behavior in my own codebase, but I think it is cleaner if there is a specified property datatype for that instead of looking into the unit string and finding the % sign.

The other reason is that for integer values and also for float values theoretically the underlying datatype has to be long long which takes much more space than a simple uint8_t if you think in a microcontroller context.

Maybe you can give feedback on pros and cons.

davidgraeff commented 4 years ago

Wikipedia: "In mathematics, a percentage (from Latin per centum "by a hundred") is a number [or ratio] expressed as a fraction of 100".

The datatype just compensates for the fact that MQTT has no standardized data types (as in "programming data types" like int, bool, string). A percentage is still a number, and even if the other end has no support for "percentages", the value can still be interpreted.

The EspEasy author told me that the Homie spec is already too complicated and would consume too much memory (which is not true in general, but for them). If we force people to cope with yet another data type, that doesn't help.

ThomDietrich commented 4 years ago

Hello @szwenni, A percentage value is a number, most often with the limits of 0 to 100 (float or integer). Is your request regarding a significant difference to the number datatype or are you concerned that a number datatype value is not auto-discovered as a percentage datapoint by your controller? Why is the unit not enough from your pov? For further discussion a description of your environment (device and controller implementation) and the resulting pain point would be useful

szwenni commented 4 years ago

Hello @davidgraeff and @ThomDietrich , Yes you are right that percentage is also a number, but from homie definition a integer has a very big range and is signed. Typically percentage goes from 0 to 100. Now if you start to generically implement the homie protocol to a microcontroller like ESP you need to implemet every IntegerProperty as long long which makes no sense regarding percentage in my opinion.

Regarding the controller topic. E.g. i openhab all numbers are automatically added as Number which makes it logically not possible to assign a Dimmer (0-100%) to it because its type is number. In my opinion it is ot the best solution for the controller side to parse the unit and then guess the right format from it in auto-discover mode.

My setup right now is a self implemented homie library for ESP32, a lighting control which uses that library and openhab with the mqtt binding.

davidgraeff commented 4 years ago

In my opinion it is ot the best solution for the controller side to parse the unit and then guess the right format from it in auto-discover mode.

That's done in OH. If it doesn't work at the moment, it's a bug. "guess" is the wrong word here, the type is not determined heuristically but deterministic. If the format is "%", it will be a percentage type.

you need to implement every Integer Property as long long

No you don't. Just use uint8_t on both sides (controller + device) if you expect a percentage to be published or received. A homie conforming implementation will never send a value > 100.

In theory Homie at the moment requires people to use std::atoll for integral number parsing, I doubt that this is done in all implementations. If we follow your argumentation, we would not just need "percentage" but all C/C++ number types as well for implementations to pick the least expensive string-to-int conversion.

kollokollo commented 4 years ago

If the propery would have a unit, a minimum value, a maximum value and a resolution defined, then everything is fine. Example:

unit="%" min=0 max=100 res=1 (or 0.1 if you like).

This way it is not even important if the property is integer or rational.

This could be a general concept for all measured values, since all measurements are taken by an ADC with a limited resolution (number of bits). After having multiplied the ADC number with a calibration factor (here comes the unit), there would still be a range (min/max) and a resolution (epsilon, minimum change possible) for each property. Min/max and resolution are also important for any user interface, imagine a slider (needs min/max) or a ticker (needs res/eps) or a combination of course. You sometimes want to increase a setpoint value by just one tic!

davidgraeff commented 4 years ago

Maybe format can be extended for integer and float type topics. I quote the current specification:

For integer and float: Describes a range of payloads e.g. 10:15

For one: We should add a sentence that for "unit=%" this is implicitly "0:100".

An optional third parameter could be the resolution, for example "0:100:0.1"

lbdroid commented 4 years ago

Taking unit % to mean range of 0:100 is probably not good, since sometimes the full range isn't required. Percent is still valid even if you restrict it to a subset, such as 0:49. For example, charging an interest rate of 50% or higher per year is in many places deemed to be criminal, so you wouldn't offer anything greater than 49.

Its also unnecessary, because if you are using percent, just set the range to 0:100 or as appropriate.

Resolution, however, would be a HIGHLY useful parameter, since you don't necessarily need all possible steps.

mjcumming commented 4 years ago

It would be great to clear this issue up. See https://github.com/openhab/openhab-addons/pull/6845

The problem is the OH implementation uses the '%' unit to change the value.

How can we get a consensus and close this issue?

lbdroid commented 4 years ago

@mjcumming : That question, 0-100 vs 0.0-1.0 is actually very simple. 50% means 0.5

To put it another way; 50% of 100 = 50 0.5 x 100 = 50

So with the unit '%', the number should be interpreted in the range of 0-100. WithOUT the '%' unit, the same meaning would be applied to the range 0.0-1.0.

mjcumming commented 4 years ago

Its not that simple or straight forward or there wouldn't be so much confusion.

When I write down 50% everyone knows its 50%. No one writes down .5% and then says that is actually 50% which is exactly what the current implementation does.

lbdroid commented 4 years ago

Exactly. In fact, if you write down .5%, it literally means "half of one percent".

ajxn commented 4 years ago

Hm.

Den tis 24 mars 2020 kl 15:24 skrev Michael Cumming < notifications@github.com>:

Its not that simple or straight forward or there wouldn't be so much confusion.

The confusion are real, it looks, and we got an example.

When I write down 50% everyone knows its 50%. No one writes down .5% and then says that is actually 50% which is exactly what the current implementation does.

50/100 is 0.50 and also 50% 40/100 is 0.40 and also 40% 80/200 is 0.40 and also 40% 100/100 is 1.00 and also 100% 10/100 is 0.10 and also 10% 1/100 is 0.01 and also 1% 1/200 is 0.05 and also 0.5%

So you are right. No one writes 0.5% and say it is 50%, because it isn't. 1/200 is 0.5% and 100/200 is 50% They are not the same, and that wasn't what Ibdroid wrote.

Ibdroid wrote 0.50, that is 50/100 or 100/200 is 50%, not 0.5.

So, if you send 50%, you can also send 0.50 which is the same valuse.

By the way, do a small memory device really need to implement ALL of the standard? Isn't it enough to implement the things that is strictly needed to do the job it does?

And really, if you can't fullfill the standard, why not make a proxy that work between the devices? Handle a couple of these low power devices and register each to the server.

The standard should be good for humans, and if some devices can't handle it, let a device work as a proxy. A proxy which have enough power to follow the standard? That is how it is done in XMPP and some other standard IoT protocols.

Yours Anders

mjcumming commented 4 years ago

Ok, so I am guessing we are agree that if a property is of type integer or float and that property has a unit of % it should be interpreted exactly as it would read (using your examples above).

The problem is the MQTT/Homie binding for OpenHAB DOES NOT do this. If a property has a unit of % it divides the value of the property by 100. So in OpenHAB using Homie 100% is actually 1% and 50% is actually .5%. This is where the confusion is.

It would be great for the Homie maintainers to comment so that the OpenHAB binding can be changed to "correct" this.

lbdroid commented 4 years ago

@mjcumming : I don't think it is necessary or appropriate for homie to account for errors made in other systems that may utilize it. If there is a bug in openhab, then the users of openhab should bring it up with the developers of openhab so that openhab can be fixed.

mjcumming commented 4 years ago

Agree, the confusion is that one of the maintainers of Homie and the author of the OpenHAB binding is @davidgraeff. So while we may agree on how Homie should work, we need to have clarification from the maintainers of Homie and clarification in the documentation of expected behavior. @davidgraeff ?

fvdpol commented 4 years ago

While I can see that a conversion from the dimensionless % to a float can make sense from a pure math perspective I think these implicit unit of measure conversions are counterintuitive.

Would a ppm or ppb unit also be converted by dividing by 1e6 or 1e9? What about dB? Hope not unless the user explicitly asked for that conversion.

I personally like my dimmer (or motor speed control) values in %, or my relative humidity sensors in %. :-)

Note that the assumption that % is always between 0 and 100% is NOT always true; depending on the context how/where the dimensionless number user the value may also be negative or larger than 100. Also assumption that a percentage is an integer number is only correct in some specific cases; generally this should be a float/real number.

davidgraeff commented 4 years ago

I'm not saying that the openHAB implementation is perfect. The thing is, I stepped down as OH developer and mqtt binding maintainer so I will not making required changes :/

mjcumming commented 4 years ago

I believe the changes have been made in OH.

mjcumming commented 4 years ago

Clarified the percentage property in the convention:

Percent