Gas consumption, adding the offset from the meter

I do read out my gas meter (an BK4, a diaphragm meter, no smart meter) with a S0-reader (DS2423), which is then attached to my one-wire bus. Of course my gas meter count isn’t in line with the S0-reader. I’m looking for a smart way to align both readings without getting too complicated. I didn’t find a way to update the S0-counter with a given number of counts, so I guess this can’t be done in the chip and therefore there must be some logic…
I want to see the same readout in the openHAB frontend as on the gas meter.

At present I do this:

items:

Number Sensoren_Leist_Gas "Gasverbrauch [%d m\u00B3]" 	(SensorenTemp)	{onewire="deviceId=1D.xxxxx0000000;propertyName=counters.B;refreshinterval=60"}

so, I’m getting new counts every minute, which works fine.

after that I set up a rule, which simply adds the offset to the value from the one-wire bus:

rule "Gaszähler"
	when
		Item Sensoren_Leist_Gas changed
	then
		// den initialen Zählerstand addieren
		var Number initialGas = 60602 as DecimalType
		postUpdate(Sensoren_Leist_Gas, Sensoren_Leist_Gas.state.intValue + initialGas.intValue)
end

So, I get some counts from the S0-counter (say: 280), and add the gas meter’s Count (60.602) to it everytime I get the update. Is there some more elegant way to do this?

Except for some unnecessary casting to DecimalType what you have looks pretty good.

Sensoren_Leist_Gas.postUpdate((Sensoren_Leist_Gas.state as Number) + 60602)

You may not even need to cast to Number in this case but I include it for completeness.

1 Like

Thanks. I notice the different notation you used here also in other threads lately:

  • Sensoren_Leist_Gas.postUpdate((Sensoren_Leist_Gas.state as Number) + 60602)
    vs.
  • postUpdate(Sensoren_Leist_Gas, Sensoren_Leist_Gas.state.intValue + initialGas.intValue)

is there a reason for this? And better though: is there a nice tutorial on how to use the script language, XTend, I think? I’m always surprised with some code snippets here! thanks!

The above is a fairly lengthy explanation.

The tl;dr is the MyItem.sendCommand and postUpdate methods can be smart and handle different types of states more intelligently than the sendCommand and postUpdate actions. So unless you can’t for some reason, always use the method.

Sadly, as watou and I were discussing here there isn’t a good set of documentation for the Rules DSL language. However, this particular issue isn’t a language issue but an openHAB issue.

The best I can offer are:

http://docs.openhab.org/configuration/rules-dsl.html


https://www.eclipse.org/xtend/documentation/203_xtend_expressions.html

And look at examples.

2 Likes

thanks! now I get something to read through! :wink:

1 Like

Heya
I’m curious… I’d like to take the same approach. I was thinking of this interface for the 1-Wire bus click which is based on the 2413 chip.
I was wondering the following: When I poll the bus every 60s and would I get the counts that happened in the meanwhile?

I.e. will I get a number every minute that will be reset after the bus was polled? Or will the number increase every count?

[Edit]: Just noticed that the 2413 is probably not what I want. A counter like the DS2423 might be the better choice. Any idea where I can get a readymade module that doesn’t require soldering? (at least not SMD soldering) and isn’t so pricy?

1 Like

Sorry to have missed that! I’m not sure, if you’re still on it - a year later… but basically the answer is yes, the DS2413 (deprecated Chip, btw) would count regardless the polling. So if you poll every 60secs you’ll get all the counts in between. And no - it won’t reset (only by some strange behaviour I experience from time to time - the manual states, the chip only nulls if it isn’t powered for 10secs). So, you’ll get increasing numbers. I don’t know, what the DS2423 does differently as I don’t use it - but I presume its counter isn’t resetable as this is listed on ist description. So basically I suspect the same behaviour of both - just the DS2423 keeps ist values even after being powerless…)

just to let some reader know, I came up with a more reliant solution - as I experienced some resetting of my S0counter (don’t know the reason yet).

note: You need persistence for this - one that does allow you

This rule just counts the offset between the last two cycles and adds that one to the overall consumption counter.

I had some troubles casting the right types for calculating and item updates. What I found out was quite confusing: Sensoren_Leist_Gas.sendCommand(value) didn’t update the value, only postUpdate did. As this one is an item without a binding, I am confused. Second one was Sensoren_Status_Gas.postUpdate(Sensoren_Status_Gas.previousState().state) didn’t work, I had to use a variable for the update-command for the argument. Same for the overall consumption, I had to use a variable for this…

So here’s my code, looks a bit ugly and rough.

rule "Gaszähler"
	when
		Item Sensoren_Leist_Gas changed
	then
		if (Sensoren_Leist_Gas != UNDEF) {
			// calculate the Delta since the last update
			var Number newCounter = (Sensoren_Leist_Gas.state as Number - previousState as Number)
			
			// NULL abfragen
			if (newCounter < 0) { 
				// This was my concern, if the S0 was nulled, use just the counter (it would be 1)
				newCounter = Sensoren_Leist_Gas.state 
			}
					
			if (Sensoren_Status_Gas.state == NULL) {
				//  I experienced even with .restoreOnStartup the state wasn't restored - so do it manually
				var Number oldConsumption = Sensoren_Status_Gas.previousState().state
				Sensoren_Status_Gas.postUpdate(oldConsumption)
				Thread::sleep(10) // not sure, if needed, but somehow I suspected the script to be too fast sometimes
			}

			// now calculate the consumption and assign it to the counter
			var Number newConsumption = newCounter/100 
			newConsumption += Sensoren_Status_Gas.state
			Sensoren_Status_Gas.postUpdate(newConsumption)
		}
end

this one works for now! :wink: just wanted to share.
Advantage is: I don’t need the offset anymore - The rule relies on persistence.

1 Like