2 or more modbus slaves

Hi, I am using openhab2-addons modbus binding from marketplace. it works fine with 1 modbus slave. But I need to talk with more than 1 slave. I tried create thnigs configuration - but unsuccessufully last week.

//Bridge modbus:serial:endpointMOXA [port="/dev/ttyr01",baud=9600,id=11,dataBits=8,parity="none",stopBits="1.0",encoding="rtu"] {
//	 Bridge poller holdingsREG1[ start=0, length=6, refresh=4000, type="holding"] {
//		Thing data temp1 [ readStart="0", readValueType="int16", readTransform="JS(divide10.js)" ]
//		Thing data temp2 [ readStart="1", readValueType="int16", readTransform="JS(divide10.js)" ]
//		Thing data temp3 [ readStart="2", readValueType="int16", readTransform="JS(divide10.js)" ]
//		Thing data temp4 [ readStart="3", readValueType="int16", readTransform="JS(divide10.js)" ]
//		Thing data temp5 [ readStart="4", readValueType="int16", readTransform="JS(divide10.js)" ]
//		Thing data temp6 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
//	}
//
//}
Bridge modbus:serial:endpointMOXA2 [port="/dev/ttyr01",baud=9600,id=10,dataBits=8,parity="none",stopBits="1.0",encoding="rtu"] {
	 Bridge poller holdingsREG1[ start=0, length=8, refresh=4000, type="holding"] {
		Thing data teplota1 [ readStart="0", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota2 [ readStart="1", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota3 [ readStart="2", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota4 [ readStart="3", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota5 [ readStart="4", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota6 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data tlakBMP  [ readStart="6", readValueType="int16" ]
		Thing data teplotaBMP[ readStart="7", readValueType="int16", readTransform="JS(divide10.js)"]
	}
	
}

I don`t know , where is mistake. If anybody has any experiences with this, please help mi with it.
Thanx Martin

it is no my situation. I use only modbus binding from market place from Sami Salonen (Modbus openHAB2 binding available for alpha testing). it works fine for 1 slave. In my config - I must REM rows of second slave - because it is not functionally.

Have anybody config for more than 1 slave ?

Thanx Martin

I think you need to give each of your pollers a unique name e.g. holdingsMOXAreg1 , holdingsMOXA2reg1

Maybe, I did it a week ago. I think - I have same errors - access serial port by 2 pollers .
If I will see operational config ,than I will write my config.
Thanx

it is solved.
this is right config .things

Bridge modbus:serial:endpointMOXA [port="/dev/ttyr01",baud=9600,id=11,dataBits=8,parity="none",stopBits="1.0",encoding="rtu"] {
	 Bridge poller holdingsREG[ start=0, length=6, refresh=4000, type="holding"] {
		Thing data temp1 [ readStart="0", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp2 [ readStart="1", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp3 [ readStart="2", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp4 [ readStart="3", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp5 [ readStart="4", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp6 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
	}
}

Bridge modbus:serial:endpointMOXA2 [port="/dev/ttyr01",baud=9600,id=10,dataBits=8,parity="none",stopBits="1.0",encoding="rtu"] {
	 Bridge poller holdingsREG2[ start=0, length=8, refresh=4000, type="holding"] {
		Thing data teplota1 [ readStart="0", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota2 [ readStart="1", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota3 [ readStart="2", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota4 [ readStart="3", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota5 [ readStart="4", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota6 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data tlakBMP  [ readStart="6", readValueType="int16" ]
		Thing data teplotaBMP[ readStart="7", readValueType="int16", readTransform="JS(divide10.js)"]
	}
	
}

this is right .items

Group teploty1
Number prvy  (teploty1) { channel="modbus:data:endpointMOXA:holdingsREG:temp1:number" }
Number druhy (teploty1) { channel="modbus:data:endpointMOXA:holdingsREG:temp2:number" }
Number treti (teploty1) { channel="modbus:data:endpointMOXA:holdingsREG:temp3:number" }

Group teploty2
Number stvrty (teploty2) { channel="modbus:data:endpointMOXA:holdingsREG:temp4:number" }
Number piaty (teploty2) { channel="modbus:data:endpointMOXA:holdingsREG:temp5:number" }
Number siesty (teploty2) { channel="modbus:data:endpointMOXA:holdingsREG:temp6:number" }

Group teploty3
Number prvy2  (teploty3) { channel="modbus:data:endpointMOXA2:holdingsREG2:teplota1:number" }
Number druhy2 (teploty3) { channel="modbus:data:endpointMOXA2:holdingsREG2:teplota2:number" }
Number treti2 (teploty3) { channel="modbus:data:endpointMOXA2:holdingsREG2:teplota3:number" }

Group teploty4
Number stvrty2 (teploty4) { channel="modbus:data:endpointMOXA2:holdingsREG2:teplota4:number" }
Number piaty2  (teploty4) { channel="modbus:data:endpointMOXA2:holdingsREG2:teplota5:number" }
Number siesty2 (teploty4) { channel="modbus:data:endpointMOXA2:holdingsREG2:teplota6:number" }

Group tlaky
Number tlak		(tlaky) { channel="modbus:data:endpointMOXA2:holdingsREG2:tlakBMP:number" }
Number teplotaP 	(tlaky) { channel="modbus:data:endpointMOXA2:holdingsREG2:teplotaBMP:number" }

this is example of work 2 slaves on modbus bus. My HW configuration is : Raspberry Pi3 B - virtual serial port MOXA - nport MOXA 5230 - two arduinos with address 10 and 11.
thanx to all for help.

Martin

Do you think giving the poller-Things a unique name was the fix?
It is not the obvious thing to do, when they belong to different endpoint-Things.
We might need to clarify this in the readme docs?

2 weeks ago i did many changes, maybe raspberry and karaf was fool from it. maybe I have to restart after each change… but now it is clear.
this is the result of yesterday. I cleared syntax with Sami S. I modified my config .things, and .items yesterday after chat with Sami. You can see my config before and after. it is just all.

Martin

Hi guys

Have a close to problem above, but with 2 or more devices on the same port


    // hall.things
    Bridge modbus:serial:hall "controller" @ "hall" [ port="/dev/ttyUSB_modbus_static", id=2, baud=115200, stopBits="1.0", parity="none", dataBits=8, encoding="rtu", receiveTimeoutMillis=200 ] {

    Bridge poller relaysAndButtons [ start=0, length=16, refresh=300, type="coil" ] {
        Thing data mainLightWindowSide      [ readStart="0", writeStart="0", readValueType="bit", writeValueType="bit", writeType="coil" ]
        ...

    // kitchen.things
    Bridge modbus:serial:kitchen "controller" @ "kitchen" [ port="/dev/ttyUSB_modbus_static", id=1, baud=115200, stopBits="1.0", parity="none", dataBits=8, encoding="rtu", receiveTimeoutMillis=200 ] {

        Bridge poller relaysAndButtons [ start=0, length=16, refresh=300, type="coil" ] {
            Thing data mainLight        [ readStart="0", writeStart="0", readValueType="bit", writeValueType="bit", writeType="coil" ]
    ...

The only difference in configs (and devices, of course) is id=2 and id=1

When I put single file to things folder - it works well, but with both - I can see errors at log

13:19:54.494 [ERROR] [ternal.handler.ModbusDataThingHandler] - Thing modbus:data:kitchen:relaysAndButtons:radiatorFlow 'Modbus data' had ModbusSlaveIOExceptionImpl error on read: ModbusSlaveIOException(cause=ModbusIOException, EOF=false, message='I/O exception: IOException Error reading response (EOF)', cause2=null)

Enlarging receiveTimeoutMillis and refresh (what is not a good idea because, I need to use light switching by button press) does not help

How can I fix that ?

As discussed earlier, you must give each of your pollers some unique name.

Bridge poller relaysAndButtons2 [ ...

Bridge poller relaysAndButtons1 [ ...

There is little wired for me, because of nested things config structure and uniq link to thing at items config.

With different names, looks like working as expected - thanks!

@ssalonen the error message resulting is a bit cryptic; is there any easy way to improve binding validation ?

I don’t think it can be improved, openhab core is parsing the configurations from things. Perhaps in this case wrong configuration gets picked up, and as a side effect io errors appear? With io errors there is not much else to log down

I actually thought as well that it is enough that fully qualified thing id would be unique but apparently problems appear already with two things with same id in same file.

This is quite interesting, I wanted to try out the following configuration:

Bridge modbus:tcp:endpointMOXA [] {
	 Bridge poller holdingsREG1[ start=5, length=6, refresh=4000, type="holding"] {
		Thing data temp1 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp2 [ readStart="6", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp3 [ readStart="7", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp4 [ readStart="8", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp5 [ readStart="9", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp6 [ readStart="10", readValueType="int16", readTransform="JS(divide10.js)" ]
	}

}
Bridge modbus:tcp:endpointMOXA2 [] {
	 Bridge poller holdingsREG1[ start=0, length=8, refresh=4000, type="holding"] {
		Thing data teplota1 [ readStart="0", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota2 [ readStart="1", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota3 [ readStart="2", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota4 [ readStart="3", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota5 [ readStart="4", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota6 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data tlakBMP  [ readStart="6", readValueType="int16" ]
		Thing data teplotaBMP[ readStart="7", readValueType="int16", readTransform="JS(divide10.js)"]
	}
	
}

Notice how the two pollers have the same name, while the top level bridges have different name.

All the things come up ONLINE without any issues. I have diagslave running in the background (at localhost:502, default destination for the tcp things), and can confirm correct polls arriving in:

validateMasterIpAddr: accepting connection from 127.0.0.1
Slave   1: readHoldingRegisters from 1, 8 references
..
validateMasterIpAddr: accepting connection from 127.0.0.1
Slave   1: readHoldingRegisters from 6, 6 references

Now, this makes me wonder what is different in above configurations…?

I suppose there would quite some difficulty in detecting ā€œduplicateā€ name/ID, as this essentially what happens as a normal event when (re)loading an edited version of a Thing.

Maybe it’s the serial workings that have a problem with duplicate Thng id and throw the ā€œEOFā€ error.

Testing this more, I can see that there is something wrong the way things file is read, even with unique IDs. Perhaps detecting changes in thing files and/or commenting is causing problems for openHAB? Looks like there is some sort of caching happening

For example,

  1. Start with configuration
Bridge modbus:tcp:endpointMOXA1 [] {
	 Bridge poller holdingsREG1[ start=5, length=6, refresh=4000, type="holding"] {
		Thing data temp1 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp2 [ readStart="6", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp3 [ readStart="7", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp4 [ readStart="8", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp5 [ readStart="9", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data temp6 [ readStart="10", readValueType="int16", readTransform="JS(divide10.js)" ]
	}
}
Bridge modbus:tcp:endpointMOXA2 [] {
	 Bridge poller holdingsREG2[ start=0, length=8, refresh=4000, type="holding"] {
		Thing data teplota1 [ readStart="0", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota2 [ readStart="1", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota3 [ readStart="2", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota4 [ readStart="3", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota5 [ readStart="4", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota6 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data tlakBMP  [ readStart="6", readValueType="int16" ]
		Thing data teplotaBMP[ readStart="7", readValueType="int16", readTransform="JS(divide10.js)"]
	}
	
}

Polling go as expected.

  1. Comment first tcp thing and all children of it
// Bridge modbus:tcp:endpointMOXA1 [] {
// 	 Bridge poller holdingsREG1[ start=5, length=6, refresh=4000, type="holding"] {
// 		Thing data temp1 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
// 		Thing data temp2 [ readStart="6", readValueType="int16", readTransform="JS(divide10.js)" ]
// 		Thing data temp3 [ readStart="7", readValueType="int16", readTransform="JS(divide10.js)" ]
// 		Thing data temp4 [ readStart="8", readValueType="int16", readTransform="JS(divide10.js)" ]
// 		Thing data temp5 [ readStart="9", readValueType="int16", readTransform="JS(divide10.js)" ]
// 		Thing data temp6 [ readStart="10", readValueType="int16", readTransform="JS(divide10.js)" ]
// 	}
// }
Bridge modbus:tcp:endpointMOXA2 [] {
	 Bridge poller holdingsREG2[ start=0, length=8, refresh=4000, type="holding"] {
		Thing data teplota1 [ readStart="0", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota2 [ readStart="1", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota3 [ readStart="2", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota4 [ readStart="3", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota5 [ readStart="4", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data teplota6 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
		Thing data tlakBMP  [ readStart="6", readValueType="int16" ]
		Thing data teplotaBMP[ readStart="7", readValueType="int16", readTransform="JS(divide10.js)"]
	}
	
}

Polling gets disabled as expected
3. Uncomment the first tcp thing (-> same config as in the first step). Original things do not come back
4. Restart openHAB → all things are present. Alternatively, the things re-appear if you rename endpointMOXA1 to something new, e.g. endpointMOXA1New.

Perhaps this symptom (Thing remove/reintroduce in flight failure) is another manifestation of this issue

Thinking about the duplicate Thing name/id issue … if the parser treats that like an edit it might all go down a similar path (remove/reintroduce ā€œupdatedā€ version) and end up here where the Thing doesn’t work.

I’ve added more detailed thoughts to the issue, but experimented with PaperUI - it rejects attempts to create any poller with a duplicate ā€˜thing ID’, even if it belongs to a different tcp/serial bridge.

EDIT - PaperUI also rejects duplicate data thing IDs.
You cannot do this, for example

Bridge modbus:tcp:endpointMOXA1 [] {
	 Bridge poller holdingsREG1[ start=5, length=6, refresh=4000, type="holding"] {
		Thing data temp1 [ readStart="5", readValueType="int16", readTransform="JS(divide10.js)" ]
	}
}
Bridge modbus:tcp:endpointMOXA2 [] {
	 Bridge poller holdingsREG2[ start=0, length=8, refresh=4000, type="holding"] {
		Thing data temp1 [ readStart="0", readValueType="int16", readTransform="JS(divide10.js)" ]

I begin to think PaperUI is right (and it’ll be up to us to configure xxx.things files carefully)