Send Modbus Data to File

Hi , I have some DS18B20 temperature sensor and read the data of them through MODBUS , so i bind some items to modbus registers , like below and it works well

Number  Temp_gServerRoom_Rack1 "Rack 1 [%d °C]"    <temperature>   (ds18b20,gServerRoom)   { modbus="slave1:0" }
Number  Temp_gServerRoom_Rack2 "Rack 2 [%d °C]"    <temperature>   (ds18b20,gServerRoom)   { modbus="slave1:1" }

Two Questions :

  1. Data will shown like this " 2323 °C " how can i show like "23.23 °C "?
    (Modbus sends integer value)
  2. how can i write modbus data to an arbitrary file ?
    because I want to send temperature data by snmp to the network , I installed snmd on my raspberry pi and I need a file that contain the temperature data and updates if data changes.

One way is to use an additional item and rules, like this untested example:

your.items

Number Temp_gServerRoom_Rack1_Corrected "Rack 1 [%d °C]"    <temperature>   (ds18b20,gServerRoom)
Number  Temp_gServerRoom_Rack2_Corrected "Rack 2 [%d °C]"    <temperature>   (ds18b20,gServerRoom)

your.rules

rule CorrectTemp1
when
  Item Temp_gServerRoom_Rack1 received update
then
  val corrected = (Temp_gServerRoom_Rack1.state as DecimalType).toBigDecimal.movePointLeft(2)
  Temp_gServerRoom_Rack1_Corrected.postUpdate(corrected)
end

rule CorrectTemp2
when
  Item Temp_gServerRoom_Rack2 received update
then
  val corrected = (Temp_gServerRoom_Rack2.state as DecimalType).toBigDecimal.movePointLeft(2)
  Temp_gServerRoom_Rack2_Corrected.postUpdate(corrected)
end

I have about 20 sensor , I have to write for each sensor a rule?
I think it takes long time to change the data, i write a rule like this for 10 sensor

rule "sensor1 div100 division"
when
	Item Temp_gServerRoom_Rack1 received update
then
	var Number temp = (Temp_gServerRoom_Rack1.state as DecimalType) 
        temp = temp / 100
	postUpdate(Temp_gServerRoom_Rack1_corrected, temp)
end

it causes problem like make long delay to show data.

It should run much faster if

Item Temp_gServerRoom_Rack1 received update

were changed to

Item Temp_gServerRoom_Rack1 changed

Other approaches (like allowing simple math alternatives for valuetypes like int16/100 or adding support for transformations) would require changes to the binding. @ssalonen any advice?

You can avoid writing many rules with use of groups.
Put all your ‘real’ sensor items in a group
Write one rule to trigger on group update -
then iterate through the group to calculate new ‘corrected’ items

This may help

Nice trick with the groups!

One option also would be to use item transformations to display the data, see this wiki article. Note that state of the item does not change in this approach, just the display.

This is especially OK for situations where openhab just displays the data and you are fine persisting values as they come from the binding.

I’m also working on implementing transformation support for the modbus binding which would help to do scaling and other preprocessing for the data that is read / written.

Best
Sami

Does anyone has any idea about this problem? :confused:

I mean something like redirection and pipe concept on linux

Under openHAB 1.x, you could use Logging Persistence, but since it used a logger implementation not used in openHAB 2+, it’s not supported there, or to incorporate one of the other persistence services into your solution.

One alternative could be to do File I/O from rules, since you can use standard Java libraries from your rules.

I can change value of all member group (groups is ds18b20) by this rule,
But how to show corrected value(how to overwrite all members group again)

rule "sensor 1"
when
  Item ds18b20  changed
then
  ds18b20.members.forEach[sensor |
  var Number temp = (sensor.state as DecimalType)
  temp = temp / 100
  postUpdate( /*What should I Write here to Show corrected Value*/ )
end

this is my items file


Number  Temp_gServerRoom_Rack1 "Rack 1 [%.2f  °C]"     <temperature>   (ds18b20,gServerRoom)             { modbus="slave1:0" }
Number  Temp_gServerRoom_Rack2 "Rack 2 [%.2f  °C]"     <temperature>   (ds18b20,gServerRoom)             { modbus="slave1:1" }
.
.
.

Number Temp_gServerRoom_Rack10 "Rack 10 [%.2f  °C]"     <temperature>   (ds18b20,gServerRoom)            { modbus="slave1:9" } 

The group rule idea was to be implemented alongside Watou’s second ‘corrected item’.

So each real temperature sensor
Number Temp_gServerRoom_Rack1 …
would have a corresponding item to hold the corrected value
Number Temp_gServerRoom_Rack1_Corrected …

The rule triggers on a change to the group of ‘real’ sensors, and within the forEach[sensor … loop
you can get the name of the current sensor item, and work out the name of its associated corrected item, by
val dtStr = sensor.name + "_Corrected"
and post an update to that of your newly calculated correction.
Every call of the rule updates all of the corrected items, but who cares, it is not much overhead at all.

Have another read of the Design Pattern link


I don’t think OH has any real arbritary file writing tools. You might be able to adapt one of the persistence, or better perhaps, the logging methods. Those do after all write data to files. Or write an external script that can be called with data that you want written.

1 Like