Siemens Energy Monitor Modbus

Hello
I have a Siemens Sentron PAC3200 that is on our network and being polled by an industrial system over Modbus tcp.

Does anyone know if the modbus binding is able to retrieve data from this device?

Yes. You’d need to know technical details - addresses, register numbers, formats.

Modbus-TCP masters can co-exist on the same network (openHAB takes a master role).
Modbus-TCP slaves (like your meter) may be more or less co-operative about being polled by multiple masters. You’d have to try it and see.

Hi

Thank you for getting back to me. So I have made some progress. After finding that the Siemens only accepts one connection at a time, I removed it from the industrial program which now allows Openhab to poll it. I have set up the v2 modbus binding with a slave and polling ‘Thing’. A connection has been established and after adding it to the item file I am receiving data!

Referencing the address to the industrial system I know that I am reading the value for the line voltage on L1. Real time reading is 245volts. The figure that is appearing in openhab is 17264. I presume this is going to need some sort of conversion done to it but I’m a bit stumped on how to work with this?

That is not necessarily a show stopper for sharing.
openHAB binding can be configured to release the TCP connection after polls, allowing someone else to take a turn with a target device.
So it depends how your other polling program behaves. But very often they are “anti-social”, and hog TCP connections.

Insufficient info.
Things that can go wrong here;

Register addressing - Ever since Modbus was invented, there has been confusion between addressing and numbering. Addresses start at 0 , register numbers start at 1. The same register can be referred as “0” or “1” by different people. So when Siemens say “look at register 35” you may or may not need to address register 34. openHAB binding always uses 0-referenced addresses.

Word order - if there are 32-bit values, these are made up of two “real” 16-bit modbus registers. Let’s say regs 20 and 21. Just stick 'em together to make 32-bits, right? Except there is no rule about which way round. 20+21 or 21+20? Very different numbers result. How to deal with this is explained in binding docs.

Just those two factors give you a one-in-four chance of configuring right first time. Look closely at any docs you have about your target register. Try to figure out if you are dealing with integers or floats (less common).

Very interesting. I think I am set up correctly. I am referencing the address configuration from the live industrial system thats collecting the data just now and presenting it correctly.

What makes me think that I am receiving the correct address data is by the following post

This user is demonstrating that 17267 is converting to 243 (volts)

As I am currently receiving 17264 this makes me think that I am set up correctly and just need that final conversion step to get it to volts or am I completely missing the point here?

As I said, you need to find out if your target device is giving data in 32-bit form, in float or integer. That’s homework for you. Happy to help you configure openHAB once you have an idea of what you want it to do. You might need to share some details of your config so far, if it comes to that.

If you want a wild guess - the script you are pointing to for a seemingly unrelated device is dealing in 32-bit floats.

I shall dig further and get back to you.

It wasn’t necessarily the script I was pointing to, it was the output he had “Voltage: [17267” which is the same as me.

As for what I want openhab to do, I simply want it to display L1, L2, L3 voltages and amps on a sitemap. I then plan to persist it to mysql where I can then work with the data in grafana. That I can do once I get the data in the correct format

Why not see if you can find a manual for your device? Modbus devices generally present a table of register addressing and format.

I am making progress. I changed the poller read value type from 32bit integer to 32bit floating point and I am now getting figures that look correct. I’ll need to physically go to the unit and check the physical display but it’s looking promising!

Definitely progress being made but I have now hit a brick wall with the addressing which I can’t understand.

In the manual it defines addressing numbers from 1 to 2820 and (I’ll eventually need these) write addresses 213, 214 and 60001 to 60005. The amps, voltages are down low and I have managed to retrieve these however I need to now pull KWh readings which are in address 2801. The current industrial system is referencing 2801 and pulling data however the modbus thing in openhab will not allow me to enter a Length higher than 123. If I try to enter anything higher than 123 I get the error

Error with read: org.openhab.io.transport.modbus.internal.ModbusSlaveErrorResponseExceptionImpl: Slave responsed with error=3

If i then create a thing and enter 2801 I get the error:

Out-of-bounds: Poller is reading from index 1 to 124 (inclusive) but this thing configured to read ‘float32’ starting from element 2801. Exceeds polled data bounds

This is about how Modbus works. You can read N number of registers, starting at address XX. That data packet size is limited by design, so it happens that N is limited to how many registers fit the packet. About 120, as it happens.

So how can you possibly get register 350? Easy really, start reading at 300 for 100 registers, or at 340 for twenty registers, or just read from 350 for 1 register etc., depends what else you might want. It’s your choice within the limitations.

But if I do that, how can I read register 000? Well no-one is stopping you from running a separate read starting at 0 for ten registers etc.

The openHAB binding controls these read selections by what you assign to your poller Thing parameters. You have as many pollers as you like; each poller is associated with a contiguous block of registers of just one type.

skeleton Thing structure

TCP bridge - represents the "device"
  poller Thing A - input registers 100 to 200, polled every second
    data Thing - register 110, 16-bit integer
    data Thing - registers 120 and 121, 32-bit float
    data Thing - register 400 - ERROR! this reg not included in this polled block
  poller Thing B - holding registers 10 to 15, polled every ten seconds
    data Thing - register 10, 16-bit unsigned integer, also write to register 10
    data Thing - register 12, on/off switch

Note that some devices will reject attempted reads of registers that were not defined by the device designer. Some will let you read imaginary registers and return zeroes, some won’t. So the size and scope of the blocks that you can define to be polled may be limited by device design.

I have all reads working perfectly however I am now struggling at trying to write back. I have persevered most of today on this but it’s not sinking in on how to achieve this.

I am trying to change the PLC tariff from day to night by setting 60006 to 1. I will then need to change it back to 0 tomorrow.

I presumed that a poll was needed however it will not come online with 60006 as a start address so I created a data thing linked to the slave with a write address of 60006. However I am not sure what to set for write type or write value type. I have now become lost with so many variations I have tried and I can’t see how to then send a 1 or a 0 like you would with an MQTT write.

The manual for the PLC states:

60006 Switching tariff - unsigned short
0 = High tariff
1 = Low tariff

Any hints greatly appreciated.

Can’t see anything that you have done from here. What is your best guess at your data Thing? What “doesn’t work”

Write-only data Things are allowed, no read poller is required to include a register for writing. When the device allows, it is generally convenient to read poll though.

There’ll be messages in your openhab.log

May we see this manual?
What type of register is 600006?
Are you, the end user, allowed to switch tariffs without performing some kind of security dance?

Well, that would depend what kind of Item you linked your data Thing to.
If it were a Number type Item, you would command 0 or 1 to your Item. Simples.
You might find it more convenient to link to a Switch type Item. As it happens, the default for a holding register used as Switch is value 0=OFF 1=ON

All working now after restarting the openhab service. I think all of my attempts had confused things.

However, one last problem!

I have set up a rule to switch the tariff at 23:30 and then another rule to switch it again at 07:30.

This is my rule for switching the tariff at 23:30

import org.eclipse.smarthome.core.types.RefreshType

rule "Switch Tariff to OFF PEAK (NIGHT), writes values to DB and resets the DAY counter"
when
    Time cron "0 30 23 1/1 * ? *"
then
        RS_dkwh.sendCommand(RefreshType.REFRESH)

 createTimer(now.plusSeconds(10),[ |

        RS_RESET.sendCommand(ON)
        RS_STF.sendCommand(ON)

])
end

The rule for 07:30 is the same with the only difference being the refresh line is RS_nkwh item

However the issue I have is to do with persistence writing to the DB.

RS_RESET is a Modbus Data thing with a defined write address 60004 (This works fine, it resets the counter)

RS_STF is a Modbus Data thing with a defined write address of 60006 (This works fine, it changes the tariff)

RS_dkwh is defined in my items file against a Modbus Data thing with a read address of 2801. It’s linked to a group which is in my persistence file to write to MySQL

RS_nkwh is defined in my items file against a Modbus Data thing with a read address of 2803. It’s linked to a group which is in my persistence file to write to MySQL

dkwh and nkwh is linked to a Modbus poller which has been set NOT to poll. I thought that having it refresh in the script would grab the value and send it to the DB. It does but regardless of the script it always goes into the night database.

Last night I had the following (RS_dkwh should have changed, not RS_nkwh). This is my issue. At 23:30 it should grab the reading from the day, save it to the DB. Clear the counter then switch the monitor to night tariff.

2020-06-01 23:30:00.056 [ome.event.ItemCommandEvent] - Item 'RS_dkwh' received command REFRESH
2020-06-01 23:30:00.186 [vent.ItemStateChangedEvent] - RS_nkwh changed from 551.2818603515625 to 4668.8046875

I hope I have explained properly.

Comment when interpreting events.log
Item state updates to the same value are not normally logged, that does not mean it didn’t happen.

Remember how the read poller / data Things are structured.
As it says in the docs, issuing a REFRESH to any individual Item/channel causes a read poll cycle for the associated poller Thing. Because that’s the part that controls the read mechanism.
That means that any and all data Things of that poller (and of course associated Items) get updated.

Short version - REFRESHing a Modbus Item will probably also refresh a bunch of sibling Items.

Can’t see your config, can’t comment on the exact effect here.
(I hope when you get all this working, you’ll show your work. It’s going to be bit frustrating if someone else comes along later with one of these meters.)

It’s not that clear what you are trying to achieve with the two counters. You don’t have to use automated persist on your Items. You can direct an Item to persist in a rule, if you want to avoid storing every change or update.

Yes I did read that and the only two sibling items affected by this one poller is the day and night items so i would have thought as a minimum it would have refreshed both not just the one? - I did try splitting them up to having one poller for one item and another poller for another but this is starting to become complex with so many items. I’m now up to 16 things in PaperUi just for this one unit and if this is a success I have 6 other units to pull in to Openhab.

Another issue I’ve just spotted is the figure currently processed by Openhab. The unit is showing on it’s display 55.21Kwh but the data coming into openhab is 55210.175645. Is there a way to move the decimal place against a modbus thing?

Yes, I can post my config once I get it working reliably however all of my modbus config is currently done through PaperUI with the items in an items file

What makes you think it didn’t? As I pointed out, update-to-same-value does not get logged. Whether persistence records updates or only changes depends what you asked for, which like much here is still secret.

If you want to persist only under specific circumstances, you can command individual item persists in a rule.

Yes of course. Modbus binding docs describe how to use transformations on read data, and even give an example for divide by ten.
Note that transformation services are separately installable, that catches many out.

You might consider though if you really need to scale the Item value from Wh to kWh. If you only want that for display purposes, you can apply a transform at the point of use i.e. sitemap UI

EDIT - that’s an impressive power output, by the way :smiley:

I will research further and get back if I’m still stuck.

Hi John,

I’m using two PAC’s for monitoring my usage and production from our photovoltaics. I’m reading the 3 values L1, 2, 3 for real power and use it for further calculations.

You need to install the modes binding and create a things file (mine is called: modbusVer.things):

Bridge modbus:tcp:localhostTCPVer [ host=“192.168.0.231”, port=502, id=1 ] {
Bridge poller inputRegisters [ start=25, length=6, refresh=2000, type=“input” ] {
Thing data wirkleistungl1 [ readStart=“25”, readValueType=“float32” ]
Thing data wirkleistungl2 [ readStart=“27”, readValueType=“float32” ]
Thing data wirkleistungl3 [ readStart=“29”, readValueType=“float32” ]
}
}

and create items in your items file:

Number Verbrauch_L1 “Verbrauch L1 [%.0f Watt]” (PAC3200) { channel=“modbus:data:localhostTCPVer:inputRegisters:wirkleistungl1:number” }

Number Verbrauch_L2 “Verbrauch L2 [%.0f Watt]” (PAC3200) { channel=“modbus:data:localhostTCPVer:inputRegisters:wirkleistungl2:number” }

Number Verbrauch_L3 “Verbrauch L3 [%.0f Watt]” (PAC3200) { channel=“modbus:data:localhostTCPVer:inputRegisters:wirkleistungl3:number” }

Give it a try.

Martin

I have 4 of these units working for a month now. openhab is pulling volts, amps etc from the various registers fine however I am having issues in pulling the day and night kwh readings. It’s very intermittant and I’m not sure if its the units themselves or the way I am going about it.

The units have a Day and a Night counter. at 0730 I run the following rule which grabs the value (updating the item) which persists to a database (works fine). A timer then runs just to add a little pause. It then resets the counter and switches the over to the next tariff, again that side of it seems to work fine but the figures coming back are not always correct. at 2330 I run another rule that effectivly does the same but switches to the other tariff

import org.eclipse.smarthome.core.types.RefreshType

rule "Switch Tariff to ON PEAK (DAY), write Night value to DB and clear counter"
when
    Time cron "0 30 07 1/1 * ? *"
then
	PH_nkwh.sendCommand(RefreshType.REFRESH)
	JS_nkwh.sendCommand(RefreshType.REFRESH)
	BH_nkwh.sendCommand(RefreshType.REFRESH)
	RS_nkwh.sendCommand(RefreshType.REFRESH)

 createTimer(now.plusSeconds(10),[ |
        
        PH_RESET.sendCommand(OFF)	
	    PH_STF.sendCommand(OFF)
		JS_RESET.sendCommand(OFF)	
	    JS_STF.sendCommand(OFF)
		BH_RESET.sendCommand(OFF)	
	    BH_STF.sendCommand(OFF)
		RS_RESET.sendCommand(OFF)	
	    RS_STF.sendCommand(OFF)

])
end

Below is 7 days of readings from one of the units. As you can see 3 readings are wrong and it looks like it has pulled the reading from the opposite counter rather than the correct one for the period that has just passed. What’s confused me is that when it gets it wrong for one unit it’s 99% of the time wrong for them all on the same period but every now and again one unit will be wrong while the others are ok.

2020-08-29 23:30:00
68 kWh
2020-08-30 07:30:01
33 kWh
2020-08-30 23:30:00
102 kWh
2020-08-31 07:30:01
95 kWh
2020-08-31 23:30:00
130 kWh
2020-09-01 07:30:01
35 kWh
2020-09-01 23:30:00
0.00014 kWh
2020-09-02 07:30:01
42 kWh
2020-09-02 23:30:01
141 kWh
2020-09-03 07:30:00
0.00079 kWh
2020-09-03 23:30:01
175 kWh
2020-09-04 07:30:00
42 kWh
2020-09-04 23:30:01
167 kWh
2020-09-05 07:30:00
0.00075 kWh

I might be going about the fetching of the figures completely wrong and would be interested in anyones input on this.