Incorrect are performed the rules

Hi. I have energy meter Eastron SDM220. I want to build graphs of electricity consumption in day and night time.
Write rule.

rule "Energy by hour"
when
        Time cron "0 0 * * * ?"
then
        var hour = CounterkWh.state as DecimalType - CounterkWh.historicState(now.minusHours(1), "mysql":).state as DecimalType
//the designated time bands
        if(now.getHourOfDay > 7 && now.getHourOfDay < 23)
        {
                logInfo("TEST","sdm220_hourcounter_day = "+hour)
                postUpdate(sdm220_hourcounter_day, hour)
        }
        else
        {
//on the border ranges to add zero values in chart
//as in table as primary key timestamp is used between additions of the data in the same table it's worth pausing one second

                if(now.getHourOfDay==7)
                {
                        postUpdate(sdm220_hourcounter_night, hour)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_night, 0)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_day, 0)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_day, hour)
                }
                else if(now.getHourOfDay==23)
                {
                        postUpdate(sdm220_hourcounter_day, hour)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_day, 0)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_night, 0)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_night, hour)
                }
                else
                {
                        postUpdate(sdm220_hourcounter_night, hour)
                }
        }
        postUpdate(sdm220_hourcounter, hour)
end

But it works incorrect. The graph should look like this

I have this

In database following values from sdm220_hourcounter_day are written

 | 2017-06-19 23:00:00 |   0.27203369140625 |
 | 2017-06-19 23:00:02 |                  0 |
 | 2017-06-20 07:00:06 |   0.21600341796875 |
 | 2017-06-20 08:00:00 |    0.2760009765625 |
 | 2017-06-20 09:00:00 |    0.2869873046875 |
 | 2017-06-20 10:00:00 |   0.26800537109375 |
 | 2017-06-20 11:00:00 |     0.281982421875 |
 | 2017-06-20 12:00:00 |   0.60797119140625 |
 | 2017-06-20 13:00:00 |    0.2740478515625 |
 | 2017-06-20 14:00:00 |   0.60296630859375 |
 | 2017-06-20 15:00:01 |    0.2540283203125 |
 | 2017-06-20 16:00:00 |   0.23199462890625 |
 | 2017-06-20 17:00:00 |   0.22198486328125 |
 | 2017-06-20 18:00:00 |      0.22900390625 |
 | 2017-06-20 19:00:00 |    0.2540283203125 |
 | 2017-06-20 20:00:00 |   0.30596923828125 |
 | 2017-06-20 21:00:00 |    0.2769775390625 |
 | 2017-06-20 22:00:00 |   0.26104736328125 |
 | 2017-06-20 23:00:00 |      0.27294921875 |
 | 2017-06-20 23:00:02 |                  0 |
 | 2017-06-21 07:00:06 |    0.2969970703125 |

And from sdm220_hourcounter_night value

| 2017-06-19 07:00:00 |   0.19097900390625 |
| 2017-06-19 07:00:02 |                  0 |
| 2017-06-19 23:00:06 |   0.27203369140625 |
| 2017-06-20 00:00:00 |    0.2650146484375 |
| 2017-06-20 01:00:00 |   0.23297119140625 |
| 2017-06-20 02:00:00 |    0.2239990234375 |
| 2017-06-20 03:00:00 |     0.218994140625 |
| 2017-06-20 04:00:00 |    0.2120361328125 |
| 2017-06-20 05:00:00 |   0.24896240234375 |
| 2017-06-20 06:00:00 |   0.23004150390625 |
| 2017-06-20 07:00:00 |   0.21600341796875 |
| 2017-06-20 07:00:02 |                  0 |
| 2017-06-20 23:00:06 |      0.27294921875 |

At 7 a.m. and 23 p.m. there should be one more zero value.

What am I doing wrong?

Nothing. This is one of the challenges of working with charts.

I can’t tell what you are using for graphing. If it is Grafana you simply need to turn on “Staircase line”. But that will get rid of the diagonal line segments in the whole chart.

I don’t know about Habpanal’s charting.

From the table, it looks like you are only saving everyChange so it would make no sense to have two 0s in the database next to each other. That is as it should be.

The only thing that I can think of doing is to use a Proxy Item configured to store everyUpdate in persistence. Then have a rule:

rule "Insert extra 0 when necessary"
when
    Item sdm220_hourcounter_night changed
then
    if(sdm220_hourcounter_night_proxy.state == 0) sdm220_hourcounter_night_proxy.postUpdate(0)

    sdm220_hourcounter_night_proxy.postUpdate(sdm220_hourcounter_night.state)
end

You then chart the proxy.

Thanks for reply!

I use standart Habpanal’s charting. Sometimes rule worked correct, but only for day or night and unstable. I mean the database sometimes included double zero as expected.

I won graphics. It took a while to check. In persistence/mysql.persist write

Strategies {
        // if no strategy is specified for an item entry below, the default list will be used
        everyMinute     : "0 * * * * ?"
        every5Minutes : "0 */5 * * * ?"
        everyHour   : "0 0 * * * ?"
        everyDay    : "0 0 0 * * ?"
        default = everyChange
}

And everyChange give this bag - the value have not change and not write in the database.

That is an incomplete .persist file.

In addition to defining strategies, you must specify which Items get saved to the DB using what strategy.

See https://github.com/openhab/openhab1-addons/wiki/Persistence#configuration

Did you solve the problem?

Yes! In /etc/openhab2/persistence/mysql.persist change default strategy on everyupdate.

The default is everyChange (that is, with every change, but two zeros in a row is not changing, so a second and discarded), changed it to everyUpdate (that is, with each update to make the data and the second zero - this is the update data because more recent value) and it worked well!

По умолчанию стоит everyChange (то есть при каждом изменении, но два нуля подряд это не изменение, поэтому второй и отбрасывался), поменял его на everyUpdate (то есть при каждом обновлении вносить данные, а второй ноль - это уже обновление данных, т.к. более свежее значение) и всё заработало хорошо!

Could you please add at least an english translation for users who have maybe the same problem?
English is the preffered language here in the public accessible areas.

Thank you.

Thanks. I will try it

Не пробовали прикручивать Grafana?

Можете скинуть файлы с вашими настройками?

  • rules
  • cfg
  • persist
  • items

As Jerome already stated, please write in english.

1 Like

Grafana is not used (want to but no time).

cat persistence/mysql.persist

Strategies {
        // if no strategy is specified for an item entry below, the default list will be used
        every5Seconds   : "*/5 * * * * ?"
        everyMinute     : "0 * * * * ?"
        every5Minutes : "0 */5 * * * ?"
        everyHour   : "0 0 * * * ?"
        everyDay    : "0 0 0 * * ?"
        default = everyUpdate
}

Items {
    // persist all items once a day and on every change and restore them from the db at startup
    CounterV*, CounterW* : strategy = everyMinute
    * : strategy = default, restoreOnStartup
}

cat items/default.items

Group   All
Group   Beckhoff        (All)
Group   gSDM220         (All)
Group:Switch:OR(ON, OFF)        Lights  "Весь свет [(%d)]"              (All)
Switch  BInput10                "Гостинная"     (Beckhoff, Lights)      {modbus="slave1:0"}
Switch  BInput17                "Спальня 2"     (Beckhoff, Lights)      {modbus="slave10:0"}
Switch  BInput11                "Спальня 4"     (Beckhoff, Lights)      {modbus="slave2:0"}
Switch  BInput12                "Детская 3"     (Beckhoff, Lights)      {modbus="slave3:0"}
Switch  BInput18                "Детская 2"     (Beckhoff, Lights)      {modbus="slave9:0"}
Switch  BInput13                "Кухня"         (Beckhoff, Lights)      {modbus="slave4:0"}
Switch  BInput14                "Коридор"       (Beckhoff, Lights)      {modbus="slave5:0"}
Switch  BInput15                "Ванная"        (Beckhoff, Lights)      {modbus="slave6:0"}
Switch  BInput16                "Туалет"        (Beckhoff, Lights)      {modbus="slave7:0"}
Switch  MqttTest                "LED [%s]"              {mqtt=">[mqttbroker:test/led:command:ON:1],>[mqttbroker:test/led:command:OFF:0],<[mqttbroker:test/led:state:ON:1],<[mqttbroker:test/led:state:OFF:0]"}
Number  CounterV                "Напряжение [%.1f V]"                                   <energy>        (gSDM220)       {modbus="sdm220V1:0"}
Number  CounterA                "Ток [%.1f A]"                                          <energy>        (gSDM220)       {modbus="sdm220V2:0"}
Number  CounterW                "Активная мощность [%.1f W]"                            <energy>        (gSDM220)       {modbus="sdm220V3:0"}
Number  CounterVA               "Полная мощность [%.1f VA]"                             <energy>        (gSDM220)       {modbus="sdm220V4:0"}
Number  CounterVAr              "Реактивная мощность [%.1f VAr]"                        <energy>        (gSDM220)       {modbus="sdm220V5:0"}
Number  CounterQ                "Коэффициент мощности [%.1f]"                           <energy>        (gSDM220)       {modbus="sdm220V6:0"}
Number  CounterAngle            "Угол сдвига фазы [%.1f °]"                             <energy>        (gSDM220)       {modbus="sdm220V7:0"}
Number  CounterHz               "Частота [%.1f Hz]"                                     <energy>        (gSDM220)       {modbus="sdm220V8:0"}
Number  CounterkWhp             "Полученная активная энергия [%.1f kWh]"                <energy>        (gSDM220)       {modbus="sdm220V9:0"}
Number  CounterkWhs             "Сгенерированная активная энергия [%.1f kWh]"           <energy>        (gSDM220)       {modbus="sdm220V10:0"}
Number  CounterkVArhp           "Полученная реактивная энергия [%.1f kVArh]"            <energy>        (gSDM220)       {modbus="sdm220V11:0"}
Number  CounterkVArhs           "Сгенерированная реактивная энергия [%.1f kVArh]"       <energy>        (gSDM220)       {modbus="sdm220V12:0"}
Number  CounterkWh              "Общая активная энергия [%.1f kWh]"                     <energy>        (gSDM220)       {modbus="sdm220V13:0"}
Number  CounterkVAh             "Общая реактивная энергия [%.1f kVAh]"                  <energy>        (gSDM220)       {modbus="sdm220V14:0"}

Number  sdm220_hourcounter_day          (gSDM220)
Number  sdm220_hourcounter_night        (gSDM220)
Number  sdm220_daycounter_day           (gSDM220)
Number  sdm220_daycounter_night         (gSDM220)
Number  sdm220_hourcounter              (gSDM220)
Number  sdm220_daycounter               (gSDM220)

DateTime  Date    "Дата [%1$tA, %1$td.%1$tm.%1$tY]"       <calendar>      {channel="ntp:ntp:demo:dateTime"}
DateTime  Time    "Московское время: [%1$tH:%1$tM]"               <clock>         {channel="ntp:ntp:demo:dateTime"}
Switch  Alert           "Alert"
String  Block_CS        "Блокируем CS"  <lock>  {channel="exec:command:cs:input"}
String  Block_ALL       "Блокируем Интернет"    <lock>  {channel="exec:command:all:input"}
String  OFF_PC_Andru    "Вкл/Выкл комп" <network>      {channel="exec:command:pc:input"}

Number DayTimeCount     (gSDM220)
Number NightTimeCount   (gSDM220)

cat rules/count.rules

rule "Energy by hour"
when
        Time cron "0 0 * * * ?"
then
        var hour = CounterkWh.state as DecimalType - CounterkWh.historicState(now.minusHours(1), "mysql").state as DecimalType
//определяем диапазоны времени
        if(now.getHourOfDay > 7 && now.getHourOfDay < 23)
        {
                logInfo("TEST","sdm220_hourcounter_day = "+hour)
                postUpdate(sdm220_hourcounter_day, hour)
        }
        else
        {
//на границе диапазонов добавляем нулевые значения в график
//так как в таблице в качестве primary key используется timestamp, между добавлениями данных в одну и ту же таблицу стоит пауза в одну секунду
                if(now.getHourOfDay==7)
                {
                        postUpdate(sdm220_hourcounter_night, hour)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_night, 0)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_day, 0)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_day, hour)
                }
                else if(now.getHourOfDay==23)
                {
                        postUpdate(sdm220_hourcounter_day, hour)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_day, 0)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_night, 0)
                        Thread::sleep(2000)
                        postUpdate(sdm220_hourcounter_night, hour)
                }
                else
                {
                        postUpdate(sdm220_hourcounter_night, hour)
                }
        }
        postUpdate(sdm220_hourcounter, hour)
end

rule "Energy by day"
when
        Time cron "0 0 0 * * ?"
then
        var day = CounterkWh.state as DecimalType - CounterkWh.historicState(now.minusDays(1), "mysql").state as DecimalType
        //night counter, 00:00..07:00 + 23:00..00:00
        var day2 = CounterkWh.historicState(now.minusHours(17),"mysql").state as DecimalType - CounterkWh.historicState(now.minusDays(1), "mysql").state as DecimalType + CounterkWh.state as DecimalType - CounterkWh.historicState(now.minusHours(1),"mysql").state as DecimalType
        //day counter, 07:00..23:00
        var day1 = CounterkWh.historicState(now.minusHours(1),"mysql").state as DecimalType - CounterkWh.historicState(now.minusHours(17),"mysql").state as DecimalType
        logInfo("TEST","sdm220_daycounter_day = "+day1)
        logInfo("TEST","sdm220_daycounter_night = "+day2)
        logInfo("TEST","sdm220_daycounter = "+day)
        postUpdate(sdm220_daycounter, day)
        postUpdate(sdm220_daycounter_day, day1)
        postUpdate(sdm220_daycounter_night, day2)
end

I use this entry https://geektimes.ru/company/plarium/blog/288206/

Thank you.