[SOLVED] Railduino connection with RS485/modbus TCP

Hey,

Is there anyone who has a Railduino 1.3 or 2.0 with RS485/modbus TCP working in openHAB2.
I am a newbie with openHAB2.

Thanks for information.

The digital inputs now work with modbus tcp… :smiley:

*.things

Bridge modbus:tcp:rail2 [ host="192.168.0.12", port=502, id=2 ]
{
	Bridge poller digitalInputs [ start=0, length=35, refresh=200, type="holding" ]
{
        Thing data di01 [ readStart="5.0", readValueType="bit" ]
        Thing data di02 [ readStart="5.1", readValueType="bit" ]
        Thing data di03 [ readStart="5.2", readValueType="bit" ]
        Thing data di04 [ readStart="5.3", readValueType="bit" ]
        Thing data di05 [ readStart="5.4", readValueType="bit" ]
        Thing data di06 [ readStart="5.5", readValueType="bit" ]
        Thing data di07 [ readStart="5.6", readValueType="bit" ]
        Thing data di09 [ readStart="6.0", readValueType="bit" ]
        Thing data di10 [ readStart="6.1", readValueType="bit" ]
        Thing data di11 [ readStart="6.2", readValueType="bit" ]
        Thing data di12 [ readStart="6.3", readValueType="bit" ]
        Thing data di13 [ readStart="6.4", readValueType="bit" ]
        Thing data di14 [ readStart="6.5", readValueType="bit" ]
        Thing data di15 [ readStart="6.6", readValueType="bit" ]
        Thing data di16 [ readStart="6.7", readValueType="bit" ]
        Thing data di17 [ readStart="7.0", readValueType="bit" ]
        Thing data di18 [ readStart="7.1", readValueType="bit" ]
        Thing data di19 [ readStart="7.2", readValueType="bit" ]
        Thing data di20 [ readStart="7.3", readValueType="bit" ]
        Thing data di21 [ readStart="7.4", readValueType="bit" ]
        Thing data di22 [ readStart="7.5", readValueType="bit" ]
        Thing data di23 [ readStart="7.6", readValueType="bit" ]
        Thing data di24 [ readStart="7.7", readValueType="bit" ]
}


	Bridge poller relayRegisters [ start=0, length=150, refresh=500, type="holding" ]
{
         Thing data ro01 [ writeStart="00", writeValueType="int16", writeType="holding" ]
         Thing data ro02 [ writeStart="01", writeValueType="int16", writeType="holding" ]
         Thing data ro03 [ writeStart="02", writeValueType="int16", writeType="holding" ]
         Thing data ro04 [ writeStart="03", writeValueType="int16", writeType="holding" ]
		 Thing data ro05 [ writeStart="0.4", writeValueType="bit", writeType="holding" ]
		 Thing data ro06 [ writeStart="0.5", writeValueType="bit", writeType="holding" ]

  }
}

*.items

Contact DI01            "Digital Input index  1 [%d]"    { channel="modbus:data:rail2:digitalInputs:di01:contact" }
Contact DI02            "Digital Input index  2 [%d]"    { channel="modbus:data:rail2:digitalInputs:di02:contact" }
Contact DI03            "Digital Input index  3 [%d]"    { channel="modbus:data:rail2:digitalInputs:di03:contact" }
Contact DI04            "Digital Input index  4 [%d]"    { channel="modbus:data:rail2:digitalInputs:di04:contact" }
Contact DI05            "Digital Input index  5 [%d]"    { channel="modbus:data:rail2:digitalInputs:di05:contact" }
Contact DI06            "Digital Input index  6 [%d]"    { channel="modbus:data:rail2:digitalInputs:di06:contact" }
Contact DI07            "Digital Input index  7 [%d]"    { channel="modbus:data:rail2:digitalInputs:di07:contact" }
Contact DI08            "Digital Input index  8 [%d]"    { channel="modbus:data:rail2:digitalInputs:di08:contact" }
Contact DI09            "Digital Input index  9 [%d]"    { channel="modbus:data:rail2:digitalInputs:di09:contact" }
Contact DI10            "Digital Input index 10 [%d]"    { channel="modbus:data:rail2:digitalInputs:di10:contact" }
Contact DI11            "Digital Input index 11 [%d]"    { channel="modbus:data:rail2:digitalInputs:di11:contact" }
Contact DI12            "Digital Input index 12 [%d]"    { channel="modbus:data:rail2:digitalInputs:di12:contact" }
Contact DI13            "Digital Input index 13 [%d]"    { channel="modbus:data:rail2:digitalInputs:di13:contact" }
Contact DI14            "Digital Input index 14 [%d]"    { channel="modbus:data:rail2:digitalInputs:di14:contact" }
Contact DI15            "Digital Input index 15 [%d]"    { channel="modbus:data:rail2:digitalInputs:di15:contact" }
Contact DI16            "Digital Input index 16 [%d]"    { channel="modbus:data:rail2:digitalInputs:di16:contact" }
Contact DI17            "Digital Input index 17 [%d]"    { channel="modbus:data:rail2:digitalInputs:di17:contact" }
Contact DI18            "Digital Input index 18 [%d]"    { channel="modbus:data:rail2:digitalInputs:di18:contact" }
Contact DI19            "Digital Input index 19 [%d]"    { channel="modbus:data:rail2:digitalInputs:di19:contact" }
Contact DI20            "Digital Input index 20 [%d]"    { channel="modbus:data:rail2:digitalInputs:di20:contact" }
Contact DI21            "Digital Input index 21 [%d]"    { channel="modbus:data:rail2:digitalInputs:di21:contact" }
Contact DI22            "Digital Input index 22 [%d]"    { channel="modbus:data:rail2:digitalInputs:di22:contact" }
Contact DI23            "Digital Input index 23 [%d]"    { channel="modbus:data:rail2:digitalInputs:di23:contact" }
Contact DI24            "Digital Input index 24 [%d]"    { channel="modbus:data:rail2:digitalInputs:di24:contact" }


Switch RO01             "Relays index 1 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro01:switch" }
Switch RO02             "Relays index 2 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro02:switch" }
Switch RO03             "Relays index 3 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro03:switch" }
Switch RO04             "Relays index 4 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro04:switch" }
Switch RO05             "Relays index 5 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro05:switch" }
Switch RO06             "Relays index 6 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro06:switch" }

*.sitemap

Text label="Railduino 2" icon="attic" {
Switch item=RO01 label="Room1"
Switch item=RO02 label="Room2"
Switch item=RO03 label="Room3"
Switch item=RO04 label="Room4"
Switch item=RO05 label="Room5"
Switch item=RO06 label="Room6"
}

But only relay 1 and 2 are working now (room1 and room2).

writeValueType=“bit” does not work like with the inputs.

Can someone please help me.

ModbusTCP Railduino2

This is a limitation of Modbus, it is not possible to write a single bit of a register over modbus.

Well, strictly speaking, there is a complicated “write mask register” method with FC22 - I’ve never seen a device that supports that yet. Does this railduino support modbus FC22 mode?

The usual way to represent relays in a modbus slave is as coil types. This is after all what modbus was designed for.
Many slave designs represent relays both as bits in a register and as individual coils.
Does railduino offer a connection to the relays as coils?

If you are stuck with writing individual bits in a register, then you have to do it “by hand”.
In reality, you would (re)write the whole register to get the bit you want set or unset.
You have to make a decision about what to do about the rest of the bits in that register - should we read how the register is set just before we write it? Or should we keep a record in openHAB of how we think it ought to be set, and use that?
You can implement these functions in rules, or in the extended javascript transform available via the modbus binding.

That’s a bit of work - coils is the way to go, if possible.

Thanks for your response.

FC22 does not work.

When i write with Modbus Poll (FC06 of FC16) 1 or 2 or 4 or 8 etc. Then pull 1 relay at a time.
And by 3 or 5 or 6 etc. then a combination of relays.
I do not know how to program it in openhab.

I hope for an easy solution.
I am a carpenter with many hobbies :blush:
Sorry for bad english …

I saw a script on this page.
No idea what it means …

Railduino2 - Page16

I think you should ask the railduino makers to add coil functions to their modbus implementation, in the interest of all their users. The way they do it now makes it awkward for any user, not just openHAB.

Assuming that isn’t going to happen soon, we’ll need to build a workaround.

We will use a Number Item to hold an “image” of the register in the slave, and allow individual Switch Items to set/reset bits in that image by openHAB commands.
When the image changes, we will write the whole register to Modbus.

Changed your poller thing for the relays

	Bridge poller relayRegisters [ start=0, length=1, refresh=500, type="holding" ]
    {
         Thing data roAll [ readStart="0", readValueType="uint16", writeStart="0", writeValueType="uint16", writeType="holding", writeMultipleEvenWithSingleRegisterOrCoil=true]
         Thing data ro01 [ readStart="0.0", readValueType="bit" ]
         Thing data ro02 [ readStart="0.1", readValueType="bit" ]
         Thing data ro03 [ readStart="0.2", readValueType="bit" ]
         Thing data ro04 [ readStart="0.3", readValueType="bit" ]
	 Thing data ro05 [ readStart="0.4", readValueType="bit" ]
	 Thing data ro06 [ readStart="0.5", readValueType="bit" ]
  }

This should read-poll the whole register representing the relays. And write it using FC16.
We keep the one-bit channels for each relay, but read-only, just to make it easier to update our Switch Items.

Now for some Items

Number ROALL "Relays register [%d]" { channel="modbus:data:rail2:relayRegisters:roAll:number", autoupdate="false" }
Group ROgroup
Switch RO01 "Relays index 1 [%s]" (ROgroup) { channel="modbus:data:rail2:relayRegisters:ro01:switch", autoupdate="false" }
Switch RO02 "Relays index 2 [%s]" (ROgroup) { channel="modbus:data:rail2:relayRegisters:ro02:switch", autoupdate="false" }
Switch RO03 "Relays index 3 [%s]" (ROgroup) { channel="modbus:data:rail2:relayRegisters:ro03:switch", autoupdate="false" }
Switch RO04 "Relays index 4 [%s]" (ROgroup) { channel="modbus:data:rail2:relayRegisters:ro04:switch", autoupdate="false" }
Switch RO05 "Relays index 5 [%s]" (ROgroup) { channel="modbus:data:rail2:relayRegisters:ro05:switch", autoupdate="false" }
Switch RO06 "Relays index 6 [%s]" (ROgroup) { channel="modbus:data:rail2:relayRegisters:ro06:switch", autoupdate="false" }

So we have a Number to represent our relays register, and linked some Switches to the read-only channels.
I’ve added autoupdate="false" to each Item to stop autoupdate interfering when we use commands.
Each of our Switches goes into a group, just to make it easier later.

At this stage, our Switch Items should show what state the railduino’s relays are in. But nothing happens when we ON/OFF them from openHAB - we need a rule to do that part.

import java.lang.Math    // we need this for testBit

rule "update relay register"
when
   Member of ROgroup received command
then
   var BigInteger register = 0  // we need BigInteger to use testBit
   if ( ROALL.state != NULL && ROALL.state != UNDEF) { // avoid invalid register
      register = (ROALL.state  as DecimalType).toBigDecimal.toBigInteger   // use existing image
   }
   switch triggeringItem.name {    // act on switched Item name
      case "RO01" : {
         if  (receivedCommand = ON) {
            register = register.setBit(0)
         } else {
            register = register.clearBit(0)
         }
      case "RO02" : {
         if  (receivedCommand = ON) {
            register = register.setBit(1)
         } else {
            register = register.clearBit(1)
         }
      case "RO03" : {
         if  (receivedCommand = ON) {
            register = register.setBit(2)
         } else {
            register = register.clearBit(2)
         }
      case "RO04" : {
         if  (receivedCommand = ON) {
            register = register.setBit(3)
         } else {
            register = register.clearBit(3)
         }
      case "RO05" : {
         if  (receivedCommand = ON) {
            register = register.setBit(4)
         } else {
            register = register.clearBit(4)
         }
      case "RO06" : {
         if  (receivedCommand = ON) {
            register = register.setBit(5)
         } else {
            register = register.clearBit(5)
         }
   }
    // at last, write to Modbus
    ROALL.sendCommand(register.toString)   // not sure you can send BigInt as a command
end

This is all untested, and I’m sure there are neater ways to write it.

It’s less than ideal because race conditions can arise if several commands or states happen very quickly. I would avoid sending commands to more than one switch at a time without a delay between.

Note this setup relies on everyone agreeing which end of the register is “bit 0” !!

Warning - if you send a non-ON/OFF command (like REFRESH) to any of the switches, it will clear that relay. Most people won’t be doing that, but I’m not sure if that might kick in at boot time. You could code round that if it is a problem by reworking bits else to else if

I’m going to try tonight.
Thank you for your input!

It does not work…

I am in contact with sedtronic:

Hi Rik,

just made some check and I realised that since last firmware update I use Modbus TCP library that supports all FC functions including write coil function.

I tried it right now and it works.
You must realise that if you want to write just one coil it depends at what bit position of which byte you write.

Let me know.

And there was a newer update, but made no difference.
Or I may use wrong settings.

writeType=“coil” does not work, gives an offline error.

If you want help with your problems, you may have to give just a little more information.

Okay, they seem to saying the railduino now supports coils. It would be nice to know addresses, but let’s guess they start from zero like the registers.

I know nothing about railduino but I did read that you have to set something up with loxone? to link modbus bits to actual relays? something to do with analog bits? I can’t help you with that.

Use your Modbus Poll tool to find out if coil read and write works with your railduino. If it doesn’t, there’s no point in changing the OH modbus things to coil.

Sorry, do not have much time yesterday. I have a broken stove, :frowning: its very cold.

With modbus poll on FC15, I can operate coil 0-7.
Do not understand the translation to openHAB.

	Bridge poller relayRegisters [ start=0, length=150, refresh=500, type="coil" ]
{
         Thing data ro01 [ writeStart="0", writeValueType="int16", writeType="coil" ]
         Thing data ro02 [ writeStart="1", writeValueType="int16", writeType="coil" ]
         Thing data ro03 [ writeStart="2", writeValueType="int16", writeType="coil" ]
         Thing data ro04 [ writeStart="3", writeValueType="int16", writeType="coil" ]

RO01 and RO02 only the two relays are checked in first row.

I had contact with Sedtronic, he write back:

it looks like you are writing whole byte at once instead of just a bit.

R01 is at bit 0 of byte 0
R02 is at bit 1 of byte 0
R03 is at bit 3 of byte 0
…
R09 is at bit 1 of byte 1
R10 is at bit 2 of byte 1

That’s more important :smiley:

Okeydokey, FC15 multiple coils.

Length is about “how many coils/registers to read”. You haven’t got 150 relays, max 12 for railduino? so let’s fix that. You probably want to fix it in your input Thing as well.

By default, coils write as FC05 so we need to fix that to write FC15 instead.

Modbus coils are binary, so we want to use “bit” values here.

I’m guessing that you really want to read the coil status back into openHAB from the railduino, but you’ve not specified read params so let’s fix that too.

	Bridge poller relayRegisters [ start=0, length=12, refresh=500, type="coil" ]
{
         Thing data ro01 [ readStart="0", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro02 [ readStart="1", readValueType="bit", writeStart="1", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
}

Item still much the same

Switch RO01 "Relays index 1 [%s]"  { channel="modbus:data:rail2:relayRegisters:ro01:switch", autoupdate="false" }

That’s what you have to do if you don’t have coil commands. As we do have coil commands, we can use those instead.
I hope Sedtronic updates his documentation sometime :smiley:

Thanks thanks thanks!
The beginning is there. 1 to 8 works! 9-12 does nothing.

*.things (edit code - now works)

		Bridge poller relayRegisters [ start=0, length=12, refresh=500, type="coil" ]
{
         Thing data ro01 [ readStart="0", readValueType="bit", writeStart="0", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro02 [ readStart="1", readValueType="bit", writeStart="1", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro03 [ readStart="2", readValueType="bit", writeStart="2", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro04 [ readStart="3", readValueType="bit", writeStart="3", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro05 [ readStart="4", readValueType="bit", writeStart="4", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro06 [ readStart="5", readValueType="bit", writeStart="5", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro07 [ readStart="6", readValueType="bit", writeStart="6", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro08 [ readStart="7", readValueType="bit", writeStart="7", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro09 [ readStart="16", readValueType="bit", writeStart="16", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro10 [ readStart="17", readValueType="bit", writeStart="17", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro11 [ readStart="18", readValueType="bit", writeStart="18", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
         Thing data ro12 [ readStart="19", readValueType="bit", writeStart="19", writeValueType="bit", writeType="coil", writeMultipleEvenWithSingleRegisterOrCoil=true ]
}

*.items

Switch RO01             "Relays index 1 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro01:switch", autoupdate="false" }
Switch RO02             "Relays index 2 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro02:switch", autoupdate="false" }
Switch RO03             "Relays index 3 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro03:switch", autoupdate="false" }
Switch RO04             "Relays index 4 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro04:switch", autoupdate="false" }
Switch RO05             "Relays index 5 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro05:switch", autoupdate="false" }
Switch RO06             "Relays index 6 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro06:switch", autoupdate="false" }
Switch RO07             "Relays index 7 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro07:switch", autoupdate="false" }
Switch RO08             "Relays index 8 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro08:switch", autoupdate="false" }
Switch RO09             "Relays index 9 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro09:switch", autoupdate="false" }
Switch RO10             "Relays index 10 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro10:switch", autoupdate="false" }
Switch RO11             "Relays index 11 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro11:switch", autoupdate="false" }
Switch RO12             "Relays index 12 [%d]"   { channel="modbus:data:rail2:relayRegisters:ro12:switch", autoupdate="false" }

*.sitemap

Text label="Railduino 2 - relays" icon="light" {
Switch item=RO01 label="Room1" 
Switch item=RO02 label="Room2" 
Switch item=RO03 label="Room3"
Switch item=RO04 label="Room4"
Switch item=RO05 label="Room5"
Switch item=RO06 label="Room6"
Switch item=RO07 label="Room7"
Switch item=RO08 label="Room8"
Switch item=RO09 label="Room9"
Switch item=RO10 label="Room10"
Switch item=RO11 label="Room11"
Switch item=RO12 label="Room12"
}
	Bridge poller digitalInputs [ start=5, length=24, refresh=200, type="holding" ]
{

That’s why I want to find out, I almost stopped. Nowhere can you find a solution for the.
Remains difficult matter for me :flushed:

This may be a matter of how the relay bits are mapped into modbus addresses.
Just to be sure, what openHAB calls ro01 does actually change relay-1 on your slave?

Please try relays 9 - 12 from modbus poll tool. If doesn’t work, try relay 15, 16 etc. If that doesn’t work, try relays 17, 18

While you are playing with MB poll, see if FC05 works as well as FC15.

I have an idea that one end or other has a different idea about how FC15 works on the second byte.

Yes
16 -> RO09
17 -> RO10
18 -> RO11
19 -> RO12
(RO12 worked after reboot OpenHAB.)

Nice man!!

Now see if I can poll 1wire on UDP. It does not work with Modbus TCP.

Hello friends,

I have the same issue with Fidelix Combi module and I have to control relays, by individual bits of one holding register.
based on your comments and OpenHAB modbus documentations, I tried alot with different types but not success.
as far as I know when data is on “Holding register” poller type should be “holding” and if we use “coil” openHAB will not go to holding register tables and will go to coil tables. so if I use the codes that @R19i80k sent which is

Bridge poller relayRegisters [ start=0, length=12, refresh=500, type="coil" ]

my poller will not work with this error:

2019-01-28 12:05:03.870 [ERROR] [ernal.handler.ModbusDataThingHandler] - Thing modbus:data:endpointAdvantech1:fidelix:mDO3 'Modbus data' had ModbusConnectionException error on write: ModbusConnectionException(Error connecting to endpoint=ModbusSerialSlaveEndpoint@1b75dad[portName=COM1])

Therefore I have to use “holding” type like this:

Bridge poller fidelix [ start=0, length=1, refresh=500, type="holding" ] {

with this type, poller is working and I can switch on/off first relay, but only first relay!
why? because openHAB is writing 1 on the byte witch is dedicated to first DO (first bit)
I guess in my case I have to follow the instructions that @rossko57 advised with a program to wirte each bit.
any other advise is appreciated

here is my .things:

Bridge modbus:serial:endpointAdvantech1 [port="COM1",baud=9600,id=3,dataBits=8,parity="none",stopBits="1.0",encoding="rtu"] {
    Bridge poller fidelix [ start=0, length=1, refresh=500, type="holding" ] {
      Thing data mDO1 [ readStart="0.1", readValueType="bit", writeStart="0", writeValueType="int16", writeType="holding", writeMultipleEvenWithSingleRegisterOrCoil=true ]
      Thing data mDO2 [ readStart="0.2", readValueType="bit", writeStart="0", writeValueType="int16", writeType="holding", writeMultipleEvenWithSingleRegisterOrCoil=true ]
      Thing data mDO3 [ readStart="0.3", readValueType="bit", writeStart="0", writeValueType="int16", writeType="holding", writeMultipleEvenWithSingleRegisterOrCoil=true ]
      Thing data mDO4 [ readStart="0.4", readValueType="bit", writeStart="0", writeValueType="int16", writeType="holding", writeMultipleEvenWithSingleRegisterOrCoil=true ]

    }

Hello again.
rules that @rossko57 sent is working after some syntax corrections.

here is the .things :


Bridge modbus:serial:endpointAdvantech1 [port="COM1",baud=9600,id=3,dataBits=8,parity="none",stopBits="1.0",encoding="rtu"] {
    Bridge poller fidelix [ start=0, length=1, refresh=500, type="holding" ] {
      Thing data mDOall [ readStart="0", readValueType="uint16", writeStart="0", writeValueType="uint16", writeType="holding", writeMultipleEvenWithSingleRegisterOrCoil=true ]
      Thing data mDO1 [ readStart="0.0", readValueType="bit"]
      Thing data mDO2 [ readStart="0.1", readValueType="bit"]
      Thing data mDO3 [ readStart="0.2", readValueType="bit"]
      Thing data mDO4 [ readStart="0.3", readValueType="bit"]
      Thing data mDO5 [ readStart="0.4", readValueType="bit"]
      Thing data mDO6 [ readStart="0.5", readValueType="bit"]
      Thing data mDO7 [ readStart="0.6", readValueType="bit"]
      Thing data mDO8 [ readStart="0.7", readValueType="bit"]

    }
}

and .items :

Number mDOall "Relays register [%d]" { channel="modbus:data:endpointAdvantech1:fidelix:mDOall:number", autoupdate="false" }
Group mDOGroup
Switch      mLighting1 "Modbus Lighting1" (mDOGroup) ["Lighting"] { channel="modbus:data:endpointAdvantech1:fidelix:mDO1:switch",autoupdate="false" }
Switch      mLighting2 "Modbus Lighting2" (mDOGroup) ["Lighting"] { channel="modbus:data:endpointAdvantech1:fidelix:mDO2:switch",autoupdate="false" }
Switch      mLighting3 "Modbus Lighting3" (mDOGroup) ["Lighting"] { channel="modbus:data:endpointAdvantech1:fidelix:mDO3:switch",autoupdate="false" }
Switch      mLighting4 "Modbus Lighting4" (mDOGroup) ["Lighting"] { channel="modbus:data:endpointAdvantech1:fidelix:mDO4:switch",autoupdate="false" }
Switch      mLighting5 "Modbus Lighting5" (mDOGroup) ["Lighting"] { channel="modbus:data:endpointAdvantech1:fidelix:mDO5:switch",autoupdate="false" }
Switch      mLighting6 "Modbus Lighting6" (mDOGroup) ["Lighting"] { channel="modbus:data:endpointAdvantech1:fidelix:mDO6:switch",autoupdate="false" }
Switch      mLighting7 "Modbus Lighting7" (mDOGroup) ["Lighting"] { channel="modbus:data:endpointAdvantech1:fidelix:mDO7:switch",autoupdate="false" }
Switch      mLighting8 "Modbus Lighting8" (mDOGroup) ["Lighting"] { channel="modbus:data:endpointAdvantech1:fidelix:mDO8:switch",autoupdate="false" }

and last , rules :

import java.lang.Math    // we need this for testBit

rule "update relay register"
when
   Member of mDOGroup received command
then
  //var BigInteger register = 0   // we need BigInteger to use testBit
  var int regold = mDOall.state as DecimalType
  // if ( mDOall.state != NULL && mDOall.state != UNDEF) { // avoid invalid register
   var register = (mDOall.state  as DecimalType).toBigDecimal.toBigInteger  // use existing image
 //  }
 switch triggeringItem.name {    // act on switched Item name
      case "mLighting1" : {
         if  (receivedCommand == ON) {
            register = register.setBit(0)
           } 
         else {
            register = register.clearBit(0)
         }
      }
      case "mLighting2" : {
         if  (receivedCommand == ON) {
            register = register.setBit(1)
         } else {
            register = register.clearBit(1)
         }
      }
      case "mLighting3" : {
         if  (receivedCommand == ON) {
            register = register.setBit(2)
         } else {
            register = register.clearBit(2)
         }
      }
      case "mLighting4" : {
         if  (receivedCommand == ON) {
            register = register.setBit(3)
         } else {
            register = register.clearBit(3)
         }
      }
      case "mLighting5" : {
         if  (receivedCommand == ON) {
            register = register.setBit(4)
         } 
         else {
            register = register.clearBit(4)
         }
      }
      case "mLighting6" : {
         if  (receivedCommand == ON) {
            register = register.setBit(5)
         } else {
            register = register.clearBit(5)
         }
      }
      case "mLighting7" : {
         if  (receivedCommand == ON) {
            register = register.setBit(6)
         } else {
            register = register.clearBit(6)
         }
      }
      case "mLighting8" : {
         if  (receivedCommand == ON) {
            register = register.setBit(7)
         } else {
            register = register.clearBit(7)
         }
      }
    }
   mDOall.sendCommand(register)  // at last, write to Modbus
  
end

tested and works fine.
Thanks

1 Like