• 10 dec 2017: forum version update. In case of issues use this topic.
  • 30 nov 2017: pilight moved servers. In case of issues use this topic.
Hello There, Guest! Login Register


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Done] Eventing - operators MOD and DIV
#11
I will do that, but please let me do some testing first.

The error however is not related to the new operators. When I replace the new ones by existing operaters like this:

Code:
"IF ((datetime.hour + (datetime.minute - 30) / 60 ) + 24) + (((datetime.minute - 30) / 60) / 100) == sunriseset.sunset THEN switch DEVICE tuin1 TO on"

it gives me the same error
Code:
[....] Starting : pilight[Jan 10 10:45:34:906439] pilight-daemon: ERROR: rule #1 invalid: operator 24 does not exist
 
Reply
#12
@curlymo

Although by swapping the terms of the comparison the "operator 24 doesn't exist" error is not occurring, the rule is not working like it should.
The first thing that's wrong, is that the rule is executed constantly although the rule should evaluate to "false".

I have put in some debugging lines in my mod and div operators to see if it is my code that is causing this, but I think that it must be something in the evaluation of the rule.

The rule I'm testing with is:

Code:
"IF (sunriseset.sunset == (datetime.hour + (datetime.minute - 30) \\ 60 ) % 24) + (((datetime.minute - 30) \\ 60) / 100) THEN switch DEVICE tuin1 TO on"

pilight-daemon -D gives me these results:

Code:
[Jan 10 13:52:04:133474] pilight-daemon: DEBUG: broadcasted: {"origin":"sender", "protocol":"pollin","message{"systemcode":17,"unitcode":1,"state":"on"},"repeat":1,"uuid":"0000-b8-27-eb-aea8e0"}
[Jan 10 13:52:04:248178] pilight-daemon: DEBUG: div a:35.000000
[Jan 10 13:52:04:248807] pilight-daemon: DEBUG: div b:60.000000
[Jan 10 13:52:04:248975] pilight-daemon: DEBUG: div result:0.000000
[Jan 10 13:52:04:249442] pilight-daemon: DEBUG: div a:22.000000
[Jan 10 13:52:04:249610] pilight-daemon: DEBUG: div b:60.000000
[Jan 10 13:52:04:249761] pilight-daemon: DEBUG: div result:0.000000

There are two identical div clauses the rule, but only the second one is getting the correct input (52-30=22). The mod clause isn't executed at all. To prove that the mod operator is working, I swapped the mod for div and v.v. pilight-debug -D now shows:

Code:
[Jan 10 14:30:39:666003] pilight-daemon: DEBUG: mod a:14.000000
[Jan 10 14:30:39:666614] pilight-daemon: DEBUG: mod b:60.000000
[Jan 10 14:30:39:666786] pilight-daemon: DEBUG: mod result:14.000000
[Jan 10 14:30:39:667220] pilight-daemon: DEBUG: mod a:0.000000
[Jan 10 14:30:39:667379] pilight-daemon: DEBUG: mod b:60.000000
[Jan 10 14:30:39:667531] pilight-daemon: DEBUG: mod result:0.000000

So now mod is getting the correct input only the second time (30-30=0) and now the div clause is neglected.

I examined the rule dozens of times, but still I may be overlooking something.

Here are the sources (still with the debug lines in).

mod.c
Code:
/*
    Copyright (C) 2015 CurlyMo & Niek

    This file is part of pilight.

    pilight is free software: you can redistribute it and/or modify it under the
    terms of the GNU General Public License as published by the Free Software
    Foundation, either version 3 of the License, or (at your option) any later
    version.

    pilight is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with pilight. If not, see    <http://www.gnu.org/licenses/>
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "operator.h"
#include "mod.h"
#include "dso.h"
#include "log.h"
#include "math.h"

static void operatorModCallback(double a, double b, char **ret) {
    sprintf(*ret, "%f", fmod(a, b));
    logprintf(LOG_DEBUG, "mod a:%f", a);
    logprintf(LOG_DEBUG, "mod b:%f", b);
    logprintf(LOG_DEBUG, "mod result:%f", fmod(a, b));
}

#ifndef MODULE
__attribute__((weak))
#endif
void operatorModInit(void) {
    event_operator_register(&operator_mod, "%");
    operator_mod->callback_number = &operatorModCallback;
}

#ifdef MODULE
void compatibility(struct module_t *module) {
    module->name = "%";
    module->version = "0.1";
    module->reqversion = "5.0";
    module->reqcommit = "87";
}

void init(void) {
    operatorModInit();
}
#endif
mod.h
Code:
/*
    Copyright (C) 2015 CurlyMo & Niek

    This file is part of pilight.

    pilight is free software: you can redistribute it and/or modify it under the
    terms of the GNU General Public License as published by the Free Software
    Foundation, either version 3 of the License, or (at your option) any later
    version.

    pilight is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with pilight. If not, see    <http://www.gnu.org/licenses/>
*/

#ifndef _EVENT_OPERATOR_MOD_H_
#define _EVENT_OPERATOR_MOD_H_

#include "operator.h"

struct event_operators_t *operator_mod;

void operatorModInit(void);

#endif
div.c
Code:
REMOVED
Code:
div.h
[code]
/*
    Copyright (C) 2015 CurlyMo & Niek

    This file is part of pilight.

    pilight is free software: you can redistribute it and/or modify it under the
    terms of the GNU General Public License as published by the Free Software
    Foundation, either version 3 of the License, or (at your option) any later
    version.

    pilight is distributed in the hope that it will be useful, but WITHOUT ANY
    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with pilight. If not, see    <http://www.gnu.org/licenses/>
*/

#ifndef _EVENT_OPERATOR_DEV_H_
#define _EVENT_OPERATOR_DEV_H_

#include "operator.h"

struct event_operators_t *operator_div;

void operatorDivInit(void);

#endif

EDIT:
Some more about the mod operator.
I am quite a newbee with c coding and I thought that the fmod function could be used for the mod operator (if it is called fMOD you would expect it to calculate the modulus. This however is not true. fmod calculates the remainder of the division and that is not the same as the modulus. So I'll have to change the mod.c code so it will correctly calculate the modulus.

I have removed the mod.c code from this post.
 
Reply
#13
About the modulus, this is how you create it properly:
Code:
    sprintf(*ret, "%f", (double)((int)a % (int)b));

The best way to debug event bugs is to enable the printf's before all str_replace functions @ line #363, #526, and #582

It will then show you all steps pilight is performing when evaluating rules.
 
Reply
#14
@curlymo

I finished my div and mod operator implementations.
As advised by you I uncommented the printf's to test my rules with the new operators. For now I also kept my own debug lines so I can easily see if the operators gave the correct results and they do.Smile

But when I'm using this rule:

Code:
"IF (dummy.state IS off AND sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + (datetime.minute + 90) \\ 60 ) % 24)) THEN switch DEVICE dummy TO on"


I'm getting the following output from pilight-daemon which shows that all goes well up until the line of asterisks.
In the end the last mod (% 24) never gets processed.

I also noticed that from that line onwards there is an extra space printed before the % operator which is not present in the rule. Maybe this is related to the problem.

Code:
Replace "datetime.minute + 90" with "124.000000" in "datetime.minute + 90"
Replace "(datetime.minute + 90)" with "124.000000" in "(datetime.minute + 90) % 60"

[Jan 12 21:34:14:826436] pilight-daemon: DEBUG: mod a:124.000000
[Jan 12 21:34:14:827015] pilight-daemon: DEBUG: mod b:60.000000
[Jan 12 21:34:14:827179] pilight-daemon: DEBUG: mod result:4.000000

Replace "124.000000 % 60" with "4.000000" in "124.000000 % 60"
Replace "((datetime.minute + 90) % 60)" with "4.000000" in "((datetime.minute + 90) % 60) / 100"
Replace "4.000000 / 100" with "0.040000" in "4.000000 / 100"
Replace "(((datetime.minute + 90) % 60) / 100)" with "0.040000" in "dummy.state IS off AND sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + (datetime.minute + 90) \ 60 ) % 24)"
Replace "datetime.minute + 90" with "124.000000" in "datetime.minute + 90"
Replace "(datetime.minute + 90)" with "124.000000" in "datetime.hour + (datetime.minute + 90) \ 60 "
Replace "datetime.hour + 124.000000" with "145.000000" in "datetime.hour + 124.000000 \ 60 "

[Jan 12 21:34:14:827918] pilight-daemon: DEBUG: div a:145.000000
[Jan 12 21:34:14:828084] pilight-daemon: DEBUG: div b:60.000000
[Jan 12 21:34:14:828233] pilight-daemon: DEBUG: div result:2.000000

Replace "145.000000 \ 60" with "2.000000" in "145.000000 \ 60 "
Replace "(datetime.hour + (datetime.minute + 90) \ 60 )" with "2.000000 " in "(datetime.hour + (datetime.minute + 90) \ 60 ) % 24"
Replace "((datetime.hour + (datetime.minute + 90) \ 60 ) % 24)" with "2.000000  % 24" in "dummy.state IS off AND sunriseset.sunset == 0.040000 + ((datetime.hour + (datetime.minute + 90) \ 60 ) % 24)"
Replace "datetime.minute + 90" with "124.000000" in "datetime.minute + 90"
****************************************************************
Replace "(datetime.minute + 90)" with "124.000000" in "dummy.state IS off AND sunriseset.sunset == 0.040000 + 2.000000  % 24"
Replace "dummy.state IS off" with "0" in "dummy.state IS off AND sunriseset.sunset == 0.040000 + 2.000000  % 24"
Replace "sunriseset.sunset == 0.040000" with "0" in "sunriseset.sunset == 0.040000"
Replace "sunriseset.sunset == 0.040000" with "0" in "0 AND sunriseset.sunset == 0.040000 + 2.000000  % 24"
Replace "0 AND 0" with "0" in "0 AND 0 + 2.000000  % 24"
Replace "0 + 2.000000" with "2.000000" in "0 + 2.000000  % 24"
Replace "(dummy.state IS off AND sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + (datetime.minute + 90) \ 60 ) % 24))" with "2.000000  % 24" in "(dummy.state IS off AND sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + (datetime.minute + 90) \ 60 ) % 24))"
Replace "datetime.minute + 90" with "124.000000" in "datetime.minute + 90"
Replace "(datetime.minute + 90)" with "124.000000" in "(datetime.minute + 90) % 60"

[Jan 12 21:34:14:829344] pilight-daemon: DEBUG: mod a:124.000000
[Jan 12 21:34:14:829508] pilight-daemon: DEBUG: mod b:60.000000
[Jan 12 21:34:14:829655] pilight-daemon: DEBUG: mod result:4.000000

Replace "124.000000 % 60" with "4.000000" in "124.000000 % 60"
Replace "((datetime.minute + 90) % 60)" with "4.000000" in "((datetime.minute + 90) % 60) / 100"
Replace "4.000000 / 100" with "0.040000" in "4.000000 / 100"
Replace "(((datetime.minute + 90) % 60) / 100)" with "0.040000" in "2.000000  % 24"
[Jan 12 21:34:14:830295] pilight-daemon: DEBUG: executed rule: moddiv
[Jan 12 21:34:14:830632] pilight-daemon: DEBUG: **** RAW CODE ****
 
Reply
#15
Can you post the source of the modules?

I think i already see the issue:

"IF (dummy.state IS off AND sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + (datetime.minute + 90) \\ 60 ) % 24)) THEN switch DEVICE dummy TO on"

You have a space between the 60 and the hook Smile
 
Reply
#16
Of course I will post the sources with pleasure. Shall I leave the debug lines in (maybe commented out)?

That's the eye of the expertSmile Thanks.
I didn't realize that the rule interpreter is sensitive for whitespace before hooks. I changed it and the final mod now gets processed indeed.

I will test further to see if the rule really works the way I intended.
 
Reply
#17
It currently is. I want to change that in the next release.

Can you make it a git pull-request maybe?
 
Reply
#18
To be honest, this whole github thing is new to me, so I'll have to to take a little time to learn what a pull request is, firstUnsure.

Since it is great fun to work on pilight components like these operators and my QUIGG-GT1000 and Randomizer protocosl, I will give it a go.

I guess I'll have to create a github account and create a repository first.
 
Reply
#19
There is a lot of documentation about github everywhere. Just read how to do a pull-request. BUT, please first try this on your own repositories before doing a PR to pilight. If you're unsure if you did it right, ask me to look at your local PR first.
 
Reply
#20
I did further testing and ran into what is could be a bug.
My rule still is:

Code:
"IF ((dummy.state IS off) AND (sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + ((datetime.minute + 90) \\ 60)) % 24))) THEN ..."

I followed the logged replacements step by step, up until the line with astersks.

Then I had: (1 AND (sunriseset.sunset == 0.4 + 13))

From there it seems that it is going wild.

I would expect replacement of

"0.4 +13" in "13.04",
"sunrise.sunset == 13.04" in "0",
"(sunrise sunset == 13.04)" in "0",
"1 AND 0" in "0"

But as you can see below, it is doing something completely different...

Code:
Replace "dummy.state IS off" with "1" in "dummy.state IS off"
Replace "(dummy.state IS off)" with "1" in "(dummy.state IS off) AND (sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + ((datetime.minute + 90) \ 60)) % 24))"
Replace "datetime.minute + 90" with "100.000000" in "datetime.minute + 90"
Replace "(datetime.minute + 90)" with "100.000000" in "(datetime.minute + 90) % 60"
Replace "100.000000 % 60" with "40.000000" in "100.000000 % 60"
Replace "((datetime.minute + 90) % 60)" with "40.000000" in "((datetime.minute + 90) % 60) / 100"
Replace "40.000000 / 100" with "0.400000" in "40.000000 / 100"
Replace "(((datetime.minute + 90) % 60) / 100)" with "0.400000" in "sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + ((datetime.minute + 90) \ 60)) % 24)"
Replace "datetime.minute + 90" with "100.000000" in "datetime.minute + 90"
Replace "(datetime.minute + 90)" with "100.000000" in "(datetime.minute + 90) \ 60"
Replace "100.000000 \ 60" with "1.000000" in "100.000000 \ 60"
Replace "((datetime.minute + 90) \ 60)" with "1.000000" in "datetime.hour + ((datetime.minute + 90) \ 60)"
Replace "datetime.hour + 1.000000" with "13.000000" in "datetime.hour + 1.000000"
Replace "(datetime.hour + ((datetime.minute + 90) \ 60))" with "13.000000" in "(datetime.hour + ((datetime.minute + 90) \ 60)) % 24"
Replace "13.000000 % 24" with "13.000000" in "13.000000 % 24"
Replace "((datetime.hour + ((datetime.minute + 90) \ 60)) % 24)" with "13.000000" in "sunriseset.sunset == 0.400000 + ((datetime.hour + ((datetime.minute + 90) \ 60)) % 24)"

*********************************************************

Replace "datetime.minute + 90" with "100.000000" in "datetime.minute + 90"
Replace "(datetime.minute + 90)" with "100.000000" in "(datetime.minute + 90) \ 60"
Replace "100.000000 \ 60" with "1.000000" in "100.000000 \ 60"
Replace "((datetime.minute + 90) \ 60)" with "1.000000" in "sunriseset.sunset == 0.400000 + 13.000000"
Replace "sunriseset.sunset == 0.400000" with "0" in "sunriseset.sunset == 0.400000 + 13.000000"
Replace "0 + 13.000000" with "13.000000" in "0 + 13.000000"
Replace "(sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + ((datetime.minute + 90) \ 60)) % 24))" with "13.000000" in "1 AND (sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + ((datetime.minute + 90) \ 60)) % 24))"
Replace "datetime.minute + 90" with "100.000000" in "datetime.minute + 90"
Replace "(datetime.minute + 90)" with "100.000000" in "(datetime.minute + 90) % 60"
Replace "100.000000 % 60" with "40.000000" in "100.000000 % 60"
Replace "((datetime.minute + 90) % 60)" with "40.000000" in "((datetime.minute + 90) % 60) / 100"
Replace "40.000000 / 100" with "0.400000" in "40.000000 / 100"
Replace "(((datetime.minute + 90) % 60) / 100)" with "0.400000" in "1 AND 13.000000"
Replace "datetime.minute + 90" with "100.000000" in "datetime.minute + 90"
Replace "(datetime.minute + 90)" with "100.000000" in "1 AND 13.000000"
Replace "13.000000" with "1" in "1 AND 13.000000"
Replace "1 AND 1" with "1" in "1 AND 1"
Replace "((dummy.state IS off) AND (sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + ((datetime.minute + 90) \ 60)) % 24)))" with "1" in "((dummy.state IS off) AND (sunriseset.sunset == (((datetime.minute + 90) % 60) / 100) + ((datetime.hour + ((datetime.minute + 90) \ 60)) % 24)))"
 
Reply
  


Possibly Related Threads...
Thread Author Replies Views Last Post
  [Done] pilight eventing - dimming step by step terrar 3 2,861 02-11-2015, 02:39 PM
Last Post: Niek
  [Done] pilight-cron (implemented with eventing) dzjaivnt 30 19,069 04-28-2014, 11:48 PM
Last Post: dzjaivnt
  [Done] Eventlist (implemented with eventing) JurnD 18 7,429 01-16-2014, 08:39 PM
Last Post: curlymo

Forum Jump:


Browsing: 1 Guest(s)