RRDtool

Ive been busy migrating from 2.1 to 2.6
I decided to start from scratch, a lot of work but i am getting there!

I also made some nice graphs. One of them displays the power usage in my house.

But now i not only want to see this in a graph but i also want to display the last value from this graph in a sensor.

I guess this can be done with a fetch command but i don’t have any idea how and where to do this.

Can anyone gets me started on this? below is the print from my rrd4j-config.xml. I would like to get the last value from the datasource wattage and display this in a sensor.

<?xml version="1.0" encoding="UTF-8"?>

<rrd_graph_def name=“Energie”>

<vertical_label>WATT</vertical_label>

Stroomverbruik

Pulsen

Stroom.rrd

Pulsen

AVERAGE

wattage

Pulsen,9600,*

wattage

#9999FF

stroomverbruik

2

kWh meter

</rrd_graph_def>

Hi Bart,

I'm not too familiar with how the RRD engine works, but surely the last value it has is the one it got from the OpenRemote Sensor?

So have you tried displaying that sensor?

(At least that's how I show current and accumulated Velbus energy data from a VMB7IN)

Cheers,

Stuart

Hi Stuart,

Thank you for youre reply.

Its not quite that easy. I have the Emninent energy reader. This device only registers the pulses from the kWh meter .

I use the RRD engine to save the counter values but also to substract the previous value from the last value and convert this amount of pulses to total wattage per hour. The “Derive” function takes care of that. Before plotting the graph i also multiply these pulses per secound by 9600 to get the correct wattage.

Long story short the sensor only measures the amount of pulses from the kWh meter. The "wattage"variable is the value i would like to show.

It was the easyest way for me to convert the amount of pulses to current usage. (My electricitymeter gives 375 pulses when 1 kWh is used.) I read out the sensor every two minutes so when the difference between the last and teh previous reading is 375 my current usage is 1000Watts.

Hope this explains what i am trying to do here.

Bart

Wow!

That's one complex way if getting a reading.

I really wish I could help you.

A Velbus input module could count the LED pulses and give you the answer, but they really doesn't help you right now.

Good luck,

Stuart

Hi Bart,

I'd use rules to achieve this: -

Convert pulses to watts
Push value into in memory (virtual) command
Create sensor to show this in memory command value
Configure RRD4J to log this sensor

Can create instantaneous power and KWh sensors and log both to RRD4J as well as show the values on you panels.

Rich

Hi Richard,

Thats exactly the way i started to do this. But, i can’t seem to get this working. Sometimes after reboot it works but most of the time it does nothing, i just can’t get it right. It probably has something to do with reading the last and the previous version.

This is the rule i made;

rule “write old value”

timer (int: 00s 2m)

when

$evt1: Event (source == “Pulsen”)

then

double newValue = Double.parseDouble($evt1.getValue().toString());

execute.command(“KWh”, String.format("%.0f", newValue));

end

rule “heartbeat_every_2_minutes”

timer (int: 00s 2m) when eval (true) then

execute.command (“Pulsen”);

end

rule “Totaal Verbruik”

timer (int: 00s 2m)

when

$evt: Event (source == “Pulsen”)

$oldevt: Event (source == “meterstand”)

then

double newValue = Double.parseDouble($evt.getValue().toString());

double oldValue = Double.parseDouble($oldevt.getValue().toString());

double realtimeWatts = (newValue - oldValue)*30000/375;

execute.command(“Watt”, String.format("%.0f", realtimeWatts));

end

The RDD graph is always spot on and makes the correct calculations

Hi Bart,

To do this with rules use a custom fact to store the previous pulse value, something like this should work but I’ve not tested it: -

declare PulseCount

value : Double

end

Then a rule to fire at startup: -

rule “initialise”

when

eval(true)

then

PulseCount counter = new PulseCount();

counter.setValue(-1);

end

timer (int: 00s 2m)

rule “pulse update”

when

$evt: Event (source == “Pulsen”)

and $counter:PulseCount()

then

double newValue = Double.parseDouble($evt.getValue().toString());

double oldValue = $counter.getValue();

$counter.setValue(newValue);

// Check if old value is initialised

if (oldValue < 0) {

return;

}

// Do calculation

double realtimeWatts = (newValue - oldValue)*30000/375;

execute.command(“Watt”, String.format("%.0f", realtimeWatts));

end

Hi Richard,

Thanks a lot for youre help. With my limited knowledge of java /drools i would never get this far. I ve been struggling many hours to get a rule that can do this!

I am going to test this tommorow and see if i can get this working.

I let you know if i succeeded.

Bart

Just remark about this rules. It will work in this example, however if you want to use the custom fact in other rule, or more precisely trigger other rules by its changes then the rules should be:

declare PulseCount

value : Double

end

rule “initialise”

when

eval(true)

then

PulseCount counter = new PulseCount();

counter.setValue(-1);

end

rule “pulse update”

no-loop true

timer (int: 00s 2m)

when

$evt: Event (source == “Pulsen”)

and $counter:PulseCount()

then

double newValue = Double.parseDouble($evt.getValue().toString());

double oldValue = $counter.getValue();

$counter.setValue(newValue);

update($counter);

// Check if old value is initialised

if (oldValue < 0) {

return;

}

// Do calculation

double realtimeWatts = (newValue - oldValue)*30000/375;

execute.command(“Watt”, String.format("%.0f", realtimeWatts));

end

// following rule would not be executed by the previous code

rule “second rule”

when

PulseCount()

then

// do something

end

Obvious thing I missed off was to insert the fact after creating it: -

rule “initialise”

when

eval(true)

then

PulseCount counter = new PulseCount();

counter.setValue(-1);

insert(counter);

end

Rich

Richard , Michal,

I put the new rule in my controller to see if all is working. Unfortunately there is one error in the new part of the rule and i don’t now how to fix it.

Heres the part from the bootlog;

ERROR 2016-08-27 10:38:40,592 : Rule definition ‘modeler_rules.drl’ could not be deployed. See errors below.
ERROR 2016-08-27 10:38:40,593 : Rule Compilation error The method setValue(int) in the type PulseCount is not applicable for the arguments (double)
INFO 2016-08-27 10:38:40,714 : Started event processor : Drools Rule Engine
INFO 2016-08-27 10:38:40,786 : Started event processor : RRD4J Data Logger

i am googling to find some kind of drools for dummies to understand the basics of drools. I havent got a clue what to change now. Does this have something to do with the value from my Zwave counter (“Pulsen”). the counter has a negative value when i display the value in OR. at the the moment its -1625712

Apologies, try: -

rule “initialise”

when

eval(true)

then

PulseCount counter = new PulseCount();

counter.setValue(-1d);

end

Richard,

Thnx, there are no errors in the boot log anymore. But it still is not working. Is it correct that the “heartbeat” rule is there?

rule “heartbeat_every_2_minutes”

timer (int: 00s 2m) when eval (true) then

execute.command (“Pulsen”);

end

It seems that the rule is not firing, i put in an extra line to display the oldValue and newValue but they stay empty.

timer (int: 00s 2m)

rule “pulse update”

when

$evt: Event (source == “Pulsen”)

$counter:PulseCount()

then

double newValue = Double.parseDouble($evt.getValue().toString());

double oldValue = $counter.getValue();

$counter.setValue(newValue);

execute.command(“KWh”, String.format("%.0f", newValue));

execute.command(“wattage”, String.format("%.0f", oldValue));

// Check if old value is initialised

if (oldValue < 0) {

return;

}

// Do calculation

double realtimeWatts = (newValue - oldValue)*30000/375;

execute.command(“Watt”, String.format("%.0f", realtimeWatts));

end

You shouldn’t need the heartbeat rule, you should have a sensor called Pulsen and the sensor/protocol will be responsible for updating the pulse count.

Ok. i understand. The problem with this eminent zwave energy meter reader is that it is not fully supported. Thats why i got the advice to poll the energy reader every 2 minutes. I tried leaving the heartbeat out but did not receive any update from the sensor.

I’m not familiar with Z wave but that sounds a little limiting.

So you have a rule that fires off a ‘send pulses’ command (which according to your heartbeat rule the command is called ‘Pulsen’ also - ensure this command name is unique) to the z wave module; is there then another command to receive this value and link it to a sensor?

Provided that the sensor named ‘Pulsen’ has a value and that value changes then there is no reason why the rule would not fire. When you link the sensor to a label on your panel do you see the pulse value and does it change over time (obviously putting your heartbeat rule back in place to get the z wave module to broadcast its’ value).

That's correct, the rule triggers a command Pulsen which is linked to a sensor named Pulsen as well. I made a label linked to this sensor so I can monitor if the data changes every two minutes, and it does! I did the same with oldValue en newValue, to monitor if there is any data written to these. But unfortunately they stay empty.
That's why I think the rule is not triggered.

I would remove the timer from the ‘pulse update’ rule then it will fire whenever the sensor value changes (which will only be every two minutes anyway due to your heartbeat rule): -

declare PulseCount

value : Double

end

Then a rule to fire at startup: -

rule “initialise”

when

eval(true)

then

PulseCount counter = new PulseCount();

counter.setValue(-1);

insert(counter);

end

rule “pulse update”

when

$evt: Event (source == “Pulsen”)

and $counter:PulseCount()

then

double newValue = Double.parseDouble($evt.getValue().toString());

double oldValue = $counter.getValue();

$counter.setValue(newValue);

// Check if old value is initialised

if (oldValue < 0) {

return;

}

// Do calculation

double realtimeWatts = (newValue - oldValue)*30000/375;

execute.command(“Watt”, String.format("%.0f", realtimeWatts));

end

You can always put: -

System.out.println(“WRITE SOME TEXT”);

In your rule body which will be written to console window if/when it triggers (useful for debugging).

Hurray, the rule works! Big Thank You for all the tips and tricks and off course a nice working rule!!
I did a step by step debug (thanks for the WRITE SOME TEXT) tip! Somewhere down the line i missed a line ( insert(counter); was missing). After that the rule finally fired but did not get past the // Check if old value is initialized line. For some reason the output from “Pulsen” is a negative value so oldValue will always stay < 0. so i changed the initialisation to 0.
This is the working rule;

rule “heartbeat_every_2_minutes”

timer (int: 00s 2m) when eval (true) then

execute.command (“Pulsen”);

end

declare PulseCount

value : Double

end

rule “initialise”

when

eval (true)

then

PulseCount counter = new PulseCount();

counter.setValue(0d);

insert(counter);

end

rule “pulse update”

no-loop true

when

$evt: Event (source == “Pulsen”)

and $counter:PulseCount()

then

double newValue = Double.parseDouble($evt.getValue().toString());

double oldValue = $counter.getValue();

$counter.setValue(newValue);

update($counter);

execute.command(“KWh”, String.format("%.0f", newValue));

execute.command(“oldval”, String.format("%.0f", oldValue));

// Check if old value is initialised

if (oldValue == 0) { return; }

// Do calculation

double realtimeWatts = (newValue - oldValue)*30000/375;

execute.command(“Watt”, String.format("%.0f", realtimeWatts));

end