Skip to content

Conversation

@Gariam-1
Copy link

@Gariam-1 Gariam-1 commented Dec 7, 2025

I added support for single operand operators and many others that I could even remotely think they could be useful.
This might be overkill, but I don't think there's any harm in having them. And yes, you can do all of this stuff with HA's template sensors, but this is a much cleaner alternative.

Single operands are used by omitting the registers, as that would be the second operand. Adding a way to have 3 or more operands would expand the possibilities even more, even if just constants defined in the definition file.

Right now there's no documentation for this feature aside for some examples where only "subtract" is used. But if this (or part of it) is merged, documenting it is in order.

I added support for single operand operations and many others that I could even remotely think they could be useful.

Single operands are used by omitting the registers, as that would be the second operand.

Yes, you can do all of this stuff with HA's template sensors, but this is much cleaner.
Refined the list a bit and added comments.
Copy link
Contributor

@Guldoman Guldoman left a comment

Choose a reason for hiding this comment

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

It looks like there were a bunch of reverts, were they done by accident?
Like the self._requests = profile["requests"] and the value = (value - maxint) ones.

@Gariam-1
Copy link
Author

Gariam-1 commented Dec 9, 2025

Mhh, yeah. I didn't mean those. I only meant to change the _read_registers_custom function.

The main branch of my fork doesn't have those, but the branch I pushed does, for some reason, and I didn't realize.

Anyway, anything outside _read_registers_custom is unintended.

Fixed unintended reverts and some mistakes with unhandled divisions by 0.
@Gariam-1
Copy link
Author

Gariam-1 commented Dec 9, 2025

Now it should be fixed.

About the names. I don't know if you are ok with alternative names, so feel free to drop them or change them if you have better ideas. As long as the operations are there, the names are less important.

Refactor _read_registers_custom to handle variables and improve logic for register checks.
@Gariam-1
Copy link
Author

Gariam-1 commented Dec 19, 2025

Just added support for variables.
Now it's possible to save the result of a calculation for later use (within the same sensor) and pass on to another one.

To declare a variable use "define: {var_name}"
To recall it use "variable: {var_name}"

p.s. after a define, "value" is reset to 0
if no registers are given, variables will take their place in the equations, otherwise they will replace "value"

Refactor operator handling and variable management in sensor processing.
@davidrapan
Copy link
Owner

I've made some minor tweaks, and even so I still don't like the validation part, I think it's now mergeable. Just check if it still works for you. 😉

@davidrapan davidrapan changed the title More power to custom sensors Extend custom sensor operators Dec 22, 2025
@davidrapan davidrapan force-pushed the main branch 2 times, most recently from 741d5f4 to 36abfef Compare December 22, 2025 22:15
Refined operator list and added plain numbers support for variables.
@Gariam-1
Copy link
Author

Gariam-1 commented Dec 23, 2025

Yeah, seems to work fine.

I put some more thought into the operator list, especially the names, as I realized that once they go live they cannot be easily taken back. Should at least be decent now.
In addition, now the "variable" keyword also accepts plain numbers.
And I'll stop here, as I no longer have any ideas, while touching only the _read_registers_custom function.

I didn't touch the validation part, but what don't you like about it?

Lastly, this is an example sensor I made with this:
It's meant to indicate the amount of power generated that is instantly being consumed. (inverter: ZCS 3000SP)

- name: "Solar Consumption Power"
        mppt: 1
        class: "power"
        state_class: "measurement"
        uom: "kW"
        scale: 0.01
        rule: 2
        icon: "mdi:lightning-bolt"
        description: "Solar power directly consumed"
        sensors:
          # grid_return = max(0, grid_power)
          - signed:
            registers: [0x0212]
          - operator: positive
            define: grid_return

          # solar_local = power_generation - grid_return
          - signed:
            registers: [0x0215]
          - operator: subtract
            variable: grid_return
            define: solar_local

          # battery_charge = max(0, battery_power)
          - signed:
            registers: [0x020D]
          - operator: positive
            define: battery_charge

          # solar_to_batt = min(solar_local, battery_charge)
          - variable: solar_local
          - operator: min
            variable: battery_charge
            define: solar_to_batt

          # result = solar_local - solar_to_batt
          - variable: solar_local
          - operator: subtract
            variable: solar_to_batt

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.

Extend custom sensor operators (e.g. min, max, etc.)

3 participants