4 bytes value , keep only 2 bytes and convert to decimal

Hi all,
via modbus i read a value of a fancoil motor speed. The istruction said that the data is a 4 bytes value and the 1st 2 bytes is about motor speed the other 2 is about other values that i don’t need.
Infact for example i read:

8192 --> 0010 0000 0000 0000 --> 0000 0000 --> 0

11024 --> 0010 1011 0001 0000 --> 0001 0000 --> 16

11035 --> 0010 1011 0001 1011 --> 0001 1011 --> 27

So how i can do the job via home assistant?

Those look like two byte values (i.e., 16 bits), not four byte values (which would be 32 bits.)

But if you did have four byte values, and you wanted to keep only the two least significant bytes, then you could add this to your modbus register sensor configuration:

structure: ">xxH"

This basically means the upper two bytes are padding (i.e., don’t care), and the lower two bytes are interpreted as “unsigned short”. You can find more details here:

And here:

https://docs.python.org/3.5/library/struct.html

Thanks,
this afternoon i understood that i need to work around structure and i made some test. The strange thing it that i see the data only if i use @h with other value, the item disappear from HA

As you sad the modbus value is a 16bit value

i test with this code:

- name: Velocità Motore
  slave: 11
  register: 001
  count: 1
- name: Velocità Motore Byte
  slave: 11
  register: 001
  count: 1
  data_type: custom
  structure: ">xxH"

i tried with “>xH” too with no luck

Sorry, I don’t understand what you mean by this. Also, when you say “no luck”, it helps if you’re more specific. How did it not work? Did you see errors, and if so, what were they? Did you get a value but it was wrong? …?

If we’re talking about Velocità Motore Byte, then the problem is you’re specifying 1 for count (which means one byte), but you’re specifying a four byte structure for unpacking, which doesn’t make any sense if the data is only one byte.

sorry i was upgrading ha too so i haven’t log.

Velocità motore (motor speed) and Velocità motore Byte read the same modbus register.
On the 1st one i have the decimal values that i wrote before, i’m trying to convert it to what i want using Velocità motore Byte (that will replace the 1st when i will find the path!!!)

in the dev guide the seller report this (italian language)

I don’t understand why i need to set count 2 due in the 1st (velocità motore) it read the value as decimal

About structure, if i set something the parameter disappear from list but i don’t have any error and if i check the config it return as config ok

My mistake. The count is the number of “registers”, and it appears each register is two bytes. So, yeah, count of 1 is probably right.

But, having said that, if you want to extract the LSB (Least Significant Byte), then you need a structure value of '>xB'. The ‘x’ means one byte of padding, and the ‘B’ means one unsigned byte.

perfect it works like a charm

Next step is write something via modbus, but it’s another story :slight_smile:

thank you very much for support

1 Like

a question, if i want to extract a single bit from the MSB byte? ‘>Bx’ extract the byte and then…?

My best guess (since jinja templating doesn’t seem to support bitwise and’ing or shifting) is to create a Template Binary Sensor. Something like:

binary_sensor:
  - platform: template
    sensors:
      modbus_reg_bit_3:
        value_template: "{{ states('sensor.modbus_reg')|int // 8 % 2 }}"

This assumes the modbus register byte is extracted into sensor.modbus_reg. Then it would extract (in this example) bit 3 into a new binary_sensor.modbus_reg_bit_3. (Obviously change the names and bit manipulation as necessary.

Thanks for the tips, can you explain how i can read it? I don’t understand what mean

Also about writing i need to set a bit to turn on or off a controller, is it possible to do it?

The need is to set the second bit to 0 or 1 due:
1st bit enable or disable the manual use of controller
2nd bit power on or off the controller
3rd bit set winter/summer
4rd bit set manual/automatic fan

This is just a different way to do bit shifting and masking.

// is basically an integer division, meaning throw away the fractional part of the result. So, e.g., 7 // 2 = 3.

% is modulo division, which means keep the remainder. So, e.g., 3 % 2 = 1.

I’m using the // operator to effectively do bit shifting. So, let’s say you’re trying to get bit 3 (where bit 0 is the least significant bit), then you divide by 8, which is 2 raised to the power of 3. (Actually, you can do // (2**3), since 2**3 - i.e., raise 2 to the power of 3 - is the same as 8.) In this case, integer dividing by 8 (or 2**3) is the same as shifting right 3 bits. Now you have bit 3 in the bit 0 position.

Next you do % 2 to “throw away” all the bits except for bit 0.

So, basically, if you’re looking for bit N, then you do // (2**N) % 2.

I hope that’s understandable. It’s a bit hard to explain. :slight_smile: It would be much easier if jinja had bitwise operators, but apparently we’re lucky it even does add, subtract, muliply & divide! For more details, see:

http://jinja.pocoo.org/docs/dev/templates/#math

Setting a bit is a different story. I really don’t know how you write to a modbus register.

1 Like

Thanks, you explain very well and reading i remember what i studied about 20 years ago :smiley: :smiley: :smiley:

1 Like