# Reading value from multiple bits in BitsWordElement

**URL:** <https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736>\
**Category:** Software-Development\
**Created:** [July 13, 2023, 7:35pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736 "2023-07-13T19:35:47Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![thomas](https://community.openems.io/user_avatar/community.openems.io/thomas/32/670_2.png) [@thomas](https://community.openems.io/u/thomas)\
**Post date:** [July 13, 2023, 7:35pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/1 "2023-07-13T19:35:47Z")

</div>

Hello,

I am writing a device in OpenEMS for a battery system that we are using in our project.

We are reading the status of the battery via Modbus TCP and I am currently implementing the Modbus protocol.

Some of the values are encoded by bits inside a Modbus register. For values where a single bit corresponds to a channel, this is no problem and is easily handled by the `BitsWordElement.bit()` method which maps directly to the channel.

Some of the status information is encoded across multiple bits, but should really map to a single channel within OpenEMS.  
In one specific case, the status is encoded across the bits 0, 1 and 2 (representing numbers 00-07), with the following meaning:

- 00: Sleep
- 01: Charge
- 02: Discharge
- 03: Idle  
etc

The bit \>4 are used to encode other status, e.g single bits for status and alarms etc so can be ignored for this question.

I am unsure what is the best way to read these values in OpenEMS. I suppose one approach would be to use bitshifting and bit masking to extract a number from the first 3 bits. Is this the right approach? How would this be implemented within OpenEMS?

Any help would be greatly appreciated 🙂

Thomas

---

<div class="post-metadata">

**Author:** ![tsicking](https://community.openems.io/user_avatar/community.openems.io/tsicking/32/954_2.png) [@tsicking](https://community.openems.io/u/tsicking)\
**Post date:** [July 14, 2023, 9:01am UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/2 "2023-07-14T09:01:15Z")

</div>

Hi Thomas,

First of all, I would create an Enum `Status` implementing `OptionsEnum` for decoding the status from the integer like that:

```auto
public enum Status implements OptionsEnum {
    UNDEFINED(-1, "Undefined"), //
    SLEEP(0, "Sleep"), //
...

```

Then you need a corresponding channel in your component:

```auto
STATUS(Doc.of(Status.values()))

```

Now if you don’t need the bits \> 4, one could define an `ElementToChannelConverter` like

```auto
value -> value & 0b11100000

```

(or maybe something else)  
If you do need the higher bits, maybe it’s best to define a dummy channel where you put the whole byte (or word) and use an onUpdate-callback on that channel, which “cuts the channel value into pieces” and maps everything correspondingly.

Now as I wrote this, I think this may be exactly your approach written down in a more detailed way… I don’t know of any more elegant ways, maybe someone else does?

Best regards,  
Thomas

---

<div class="post-metadata">

**Author:** ![stefan.feilmeier](https://community.openems.io/user_avatar/community.openems.io/stefan.feilmeier/32/2585_2.png) [@stefan.feilmeier](https://community.openems.io/u/stefan.feilmeier)\
**Post date:** [July 14, 2023, 10:21am UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/3 "2023-07-14T10:21:17Z")

</div>

Hi,

there are a few examples in the code with similar requirements. One example is:

> <https://github.com/OpenEMS/openems/blob/41e27e1fa161ecc42cc292c384c45227d9747a95/io.openems.edge.battery.fenecon.commercial/src/io/openems/edge/battery/fenecon/commercial/BatteryFeneconCommercialImpl.java#L266C32-L281>

Looking at the code in detail, there are a few flaws that I would do differently if I had to write that code today:

- Call a method from onUpdateCallback

```auto
m(new UnsignedWordElement(2729)).build().onUpdateCallback(value -> this.handle2729(value)))

```

- In the method make sure to always set every Channel, even if the value is null. This makes sure that, e.g. if somebody pulls the cable, the values are reset to null or false, whatever is more suitable in the situation. (I would never set states to ‘null’, but only to false)

```auto
protected void handle2729(Integer value) {
	this.channel(BatteryFeneconCommercial.ChannelId.FAULT_STATUS)
			.setNextValue(value == null ? false : (value & 0x1) == 1);
	this.channel(BatteryFeneconCommercial.ChannelId.POWER_ON)
			.setNextValue(value == null ? false : (value & 0x100) >> 8);
	this.channel(BatteryFeneconCommercial.ChannelId.LOW_SELF_CONSUMPTION_STATUS)
			.setNextValue(value == null ? false : (value & 0x200) >> 9);
	this.channel(BatteryFeneconCommercial.ChannelId.FAULT)//
			.setNextValue(value == null ? false : (value & 0x400) >> 10);
	this.channel(BatteryFeneconCommercial.ChannelId.RUNNING)
			.setNextValue(value == null ? false : (value & 0x1000) >> 12);
	this.channel(BatteryFeneconCommercial.ChannelId.
			EXTERNAL_COMMUNICATION_ONLY_UNDER_STANDBY)
			.setNextValue(value == null ? false : (value & 0x2000) >> 13);
}

```

- Add a JUnit test for this specific method

```auto
public class BatteryFeneconCommercialImplTest {

	@Test
	public void testHandle2729() {
		var sut = new BatteryFeneconCommercialImpl();
		var faultStatus = sut.channel(BatteryFeneconCommercial.ChannelId.FAULT_STATUS);
		...

		sut.handle2729(null);
		assertEquals(false, faultStatus.getNextValue().get());
		...

		sut.handle2729(0xFFFF);
		assertEquals(true, faultStatus.getNextValue().get());
		...
	}

}

```

@tsicking: the difference between this approach and an `ElementToChannelConverter` is, that I do not need a separate Channel that maps on the entire Element.

Regards,  
Stefan

---

<div class="post-metadata">

**Author:** ![tsicking](https://community.openems.io/user_avatar/community.openems.io/tsicking/32/954_2.png) [@tsicking](https://community.openems.io/u/tsicking)\
**Post date:** [July 14, 2023, 1:01pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/4 "2023-07-14T13:01:42Z")

</div>

Ah, this is indeed quite beautiful. I wasn’t aware of that possibility, thanks for pointing that out 🖖

---

<div class="post-metadata">

**Author:** ![thomas](https://community.openems.io/user_avatar/community.openems.io/thomas/32/670_2.png) [@thomas](https://community.openems.io/u/thomas)\
**Post date:** [July 14, 2023, 2:41pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/5 "2023-07-14T14:41:09Z")

</div>

Hi @stefan.feilmeier and @tsicking

Thank you both very much for your responses. I will try implementing this later on and will report back.

I think the approach presented is probably the most elegant way of doing it. One other idea I had would be to use two separate `FC3ReadRegistersTask` calls. They both access the same register, but one of them looks at the first 3 bits only using a similar logic to that presented above, and the other then uses `BitsWordElement` to access the subsequent bits directly.

I suppose this approach would be less efficient as it would require 2 modbus read operations. Is this a sufficient reason not to do it? Or is there another drawback I have not considered?

---

<div class="post-metadata">

**Author:** ![stefan.feilmeier](https://community.openems.io/user_avatar/community.openems.io/stefan.feilmeier/32/2585_2.png) [@stefan.feilmeier](https://community.openems.io/u/stefan.feilmeier)\
**Post date:** [July 14, 2023, 2:56pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/6 "2023-07-14T14:56:22Z")

</div>

That would indeed work as well (didn’t even think of it). But yes, the major drawback is, that you have multiple read operations. I cannot think of any other drawback.

---

<div class="post-metadata">

**Author:** ![thomas](https://community.openems.io/user_avatar/community.openems.io/thomas/32/670_2.png) [@thomas](https://community.openems.io/u/thomas)\
**Post date:** [July 17, 2023, 4:48pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/7 "2023-07-17T16:48:21Z")

</div>

@stefan.feilmeier One question about your answer above.

Why is it important to set the values of the channels to null? I understand that we don’t want stale values in the event that we lose connectivity or another error occurs. My question is really, why do we _ **not** _ need this logic for every channel which involves reading from modbus?  
I.e for every other channel I don’t write any logic to handle the case that the response is null - I am using a simple `ElementToChannelConverter` or reading bits to get the value.

Is this something that is handled automatically in OpenEMS? Or is there some reason why it is not necessary to set the null values?

Thomas

---

<div class="post-metadata">

**Author:** ![stefan.feilmeier](https://community.openems.io/user_avatar/community.openems.io/stefan.feilmeier/32/2585_2.png) [@stefan.feilmeier](https://community.openems.io/u/stefan.feilmeier)\
**Post date:** [July 17, 2023, 7:53pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/8 "2023-07-17T19:53:53Z")

</div>

Hi Thomas,

yes, the ModbusBridge takes care of setting values to `null` whenever the connection gets lost. See

> <https://github.com/OpenEMS/openems/blob/2c8332d8eb86243e5a3ad784ec0fffe6e771bf9f/io.openems.edge.bridge.modbus/src/io/openems/edge/bridge/modbus/api/element/ModbusElement.java#L72-L80>

(Unfortunately I just found a bug where this invalidate does not work for bits in a BitsWordElement. I am about to fix this…)

Regards,  
Stefan

---

<div class="post-metadata">

**Author:** ![thomas](https://community.openems.io/user_avatar/community.openems.io/thomas/32/670_2.png) [@thomas](https://community.openems.io/u/thomas)\
**Post date:** [November 25, 2024, 5:17pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/9 "2024-11-25T17:17:08Z")

</div>

Hi all,

I am going to reopen this topic because I am working on a similar issue right now.

I am implementing an OpenEMS device for an ESS which uses one bit of a register for the Grid Connection status - i.e for the bit 0=‘Grid Connected’, 1=‘Off-grid’.

I want to map this to the `SymmetricEss.GRID_MODE`.

I have been using the `BitsWordElement.bit()` method to access the individual bits in my other registers.

`bit()` only takes a `BitConverter` as an argument and this only has the options to map 1-to-1 or to invert the bit. `bit()` doesn’t allow for an `ElementToChannelConverter` to be passed so I am not sure that I can do it using the `bit` method.

The other possibility is to define an `ElementToChannelConverter` which operates on the whole register and does the conversion. This is the approach mentioned in the previous message. This will probably work but it is a little more involved that using the direct `BitsWordElement` method.

---

<div class="post-metadata">

**Author:** ![stefan.feilmeier](https://community.openems.io/user_avatar/community.openems.io/stefan.feilmeier/32/2585_2.png) [@stefan.feilmeier](https://community.openems.io/u/stefan.feilmeier)\
**Post date:** [November 30, 2024, 6:15pm UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/10 "2024-11-30T18:15:02Z")

</div>

Hi Thomas,

ok, I don’t think there is a straight forward way right now to solve this. You can of course always map the bit to an intermediate Channel and add a `onSetNextValue`-Listener that actually sets the `GRID_MODE`. It’s not the cleanest approach, but solves the problem…

Regards,  
Stefan

---

<div class="post-metadata">

**Author:** ![thomas](https://community.openems.io/user_avatar/community.openems.io/thomas/32/670_2.png) [@thomas](https://community.openems.io/u/thomas)\
**Post date:** [December 19, 2024, 10:58am UTC](https://community.openems.io/t/reading-value-from-multiple-bits-in-bitswordelement/1736/11 "2024-12-19T10:58:17Z")

</div>

Thanks Stefan. Yes this seems to be the best way to do it. I have found an example of this in another device implementation so will do this.

Thanks 🙂  
Thomas
