Help with a Signed Number and Sensors

I need some help regarding signed numbers.

Currently I’m pulling modbus register values from my Midnite Solar Classic 150 charge controller and returning values for binary sensors. One sensor in particular reports a positive value correctly, but when the value goes negative it starts at 65535 = -0.1, and 65534 = -0.2 . A value of 65536 = 0.0 and that does report as 0.
How do I write a calculation for that? I’ve never even seen anything like that before (let alone heard of it).

Here is my current binary sensor that report positive values correctly, but not the negative values.

      ah_dis:
        friendly_name: Charge Amps
        unit_of_measurement: "Amps"
        value_template: "{{ states.sensor.wbjr_amps.state  | multiply(0.1) | float  | round(2) }}"

Any help would be appreciated.

Two’s complement (16 bit).

Subtract 1 and invert the binary digits to get the magnitude of the negative number. I have no idea how to do this in home assistant.

Also thats not a binary sensor. A binary sensor is on or off (0 or 1, true or false etc).

You are correct, it’s a sensor (I was typing fast and wasn’t paying attention).

I have an idea…I have the calculation for negative values working…
Can one use a greater than “>” inside value template? ie:

value_template: >-
    {% if is_state('states.sensor.wbjr_amps.state) > '50000' %}
        {{ ((states.sensor.wbjr_amps.state | float ) - (65536)) * 0.1 }}
    {% else %}
        {{ states.sensor.wbjr_amps.state  | multiply(0.1) | float  | round(2) }}

Not like that. Try

value_template: >-
  {% if states('sensor.wbjr_amps.state')|int >= 32768 %}
    {{ ( states('sensor.wbjr_amps')|float - 65536 ) * 0.1 }}
  {% else %}
    {{ (( states('sensor.wbjr_amps') *0.1 )|float )|round(2) }}
  {% endif %}

Using the states('sensor.object_id') format instead of states.sensor.object_id.state is recommended to suppress errors if the entity is unavailable.

The most significant bit of the 16 bit number (1000 0000 0000 0000) indicates negative. This corresponds to >= 32768.

Ok, I see now, but it doesn’t work… the if statement returns false when it should be true (at the current moment)… I’m testing inside the template area…

Why the assumption that an integer value is a 16 bit number?

In python 3, an int is the same as long.
https://docs.python.org/3.1/whatsnew/3.0.html#integers

So an integer can be substantially larger than 216

It’s a 16bit twos compliment representation in the sensor, not home assistant.

1 Like

There’s a small typo in the template example. Replace:

{% if states('sensor.wbjr_amps.state')|int >= 32768 %}

with:

{% if states('sensor.wbjr_amps')|int >= 32768 %}
1 Like

that also returned “false” but

(states.sensor.wbjr_amps.state)|int >= 32768 returns true…

Now the sensor is reporting " unknown".

  ah_dis:
    friendly_name: Charge Amps
    unit_of_measurement: "Amps"
    value_template: >-
      {% if states(states.sensor.wbjr_amps.state)|int >= 32768 %}
        {{ ( states('sensor.wbjr_amps')|float - 65536 ) * 0.1 }}
      {% else %}
        {{ (( states('sensor.wbjr_amps') *0.1 )|float )|round(2) }}
      {% endif %}

Here is an error it’s reporting:
TypeError: can’t multiply sequence by non-int of type ‘float’

You need to remove the typo 123 pointed out. Also you are missing some quotes.

  ah_dis:
    friendly_name: Charge Amps
    unit_of_measurement: "Amps"
    value_template: >-
      {% if states('sensor.wbjr_amps')|int >= 32768 %}
        {{ ( states('sensor.wbjr_amps')|float - 65536 ) * 0.1 }}
      {% else %}
        {{ (( states('sensor.wbjr_amps') *0.1 )|float )|round(2) }}
      {% endif %}

This:

states(states.sensor.wbjr_amps.state)

means you don’t know how to use the states() function.

The states function accepts one string parameter: entity_id

So the correct form is:

states('sensor.wbjr_amps')

It’s working now (for the negative reading) and has the correct sensor value… now to wait until tomorrow to verify the the positive (although it should work as I tested that earlier when it was at a positive state).

Thanks, @tom_l m and @123 for your help. Trying to automate My Solar system and turn on and off circuits via arduino and mqtt (based on sunlight, charge, and discharge values).

I agree I may not, I’ve been using the Template page to get values and that string returned the correct value of “true”. I do appreciate the lessons and I’m learning as I go.

I’m not a programmer or coder (I’m a certified sr. systems engineer).

hello @bigmac I will lime to integrate mi midnite solar classis 250 to homeassistant. can you share with me your project?
thanks in advace
Miguel

It’s not really a project. I read values from the Midnite Solar charge controllers (2 of them), write the values to files inside the home assistant configuration directory, then read those values every second. It’s a very complicated system, but it works. I created py services (2 of them) to read and create the files, the rest is handled within home assistant. It’s not something that is a program to install.