• 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] pilight-cron (implemented with eventing)
#21
Quote:It only works with 2.1 as i didnt figure out how to use ssdp yet.
Just use my ssdp lib with the code in the different c clients.

Great work though! However, i'm still not convinced that this is the perfect modular event approach.

I reviewed your code and noticed that you need to learn a lot more about memory handling.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <time.h>

#include "json.h"

#define PORT 5000
#define BUFSIZE 1024

#define CRONFIG_FILE "/etc/pilight/cronfig.json"

typedef enum
{
    WELCOME,
    IDENTIFY,
    REJECT,
    SEND
} steps_t;

JsonNode *getCronfig(void)
{
    FILE *fp;
    char *content;
    size_t bytes;
    JsonNode *cronfig = json_mkobject();
    struct stat st;

    fp=fopen(CRONFIG_FILE, "r");

    fstat(fileno(fp), &st);
    bytes = (size_t)st.st_size;

     // Wierd this is working with an unallocated buffer
    fread(content, sizeof(char), bytes, fp);

    cronfig = json_decode(content); // Memory leak
    fclose(fp);

    return cronfig;
}

int main(int arc, char* argv)
{
    struct sockaddr_in serverAddress;
    int serverSocket;
    JsonNode *json = json_mkobject();
    JsonNode *code = json_mkobject();
    JsonNode *cronfig = json_mkobject();
    char *sendBuff, *recvBuff, *message;
    sendBuff = malloc(BUFSIZE); // Memory leak, why not sendBuff[BUFSIZE]?
    recvBuff = malloc(BUFSIZE); // Memory leak
    steps_t step = WELCOME;

    char systemTime[6];
    //read cronfig-json
    cronfig = getCronfig(); // Memory Leak
    char *tmp = json_stringify(cronfig, NULL);
    printf("%s\n\n", tmp);

    //create socket
    serverSocket = socket(AF_INET, SOCK_STREAM,0);
    if(serverSocket == -1)
    {
        perror("socket() ");
    }

    /* Why don't you use my socket library and pilight defines ? */
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(PORT);
    serverAddress.sin_addr.s_addr = INADDR_ANY;

    if(connect(serverSocket, (struct sockaddr *) &serverAddress, sizeof(struct sockaddr))== -1)
    {
        perror("connect() ");
    }

    while(1)
    {
        if(step == IDENTIFY)
        {
            if(recv(serverSocket, recvBuff, BUFSIZE, 0) == -1)
            {
                perror("recv() ");
                goto close;
            }
            json = json_decode(recvBuff);
            json_find_string(json, "message", &message);
            usleep(100);
        }

        switch(step)
        {
        case WELCOME:
            send(serverSocket, "{\"message\":\"client gui\"}", BUFSIZE, 0);
            step=IDENTIFY;
            break;
        case IDENTIFY:
            printf("%s\n", message);
            if(strcmp(message, "accept client") == 0)
            {
                step=SEND;
            }
            if(strcmp(message, "reject client") == 0)
            {
                step=REJECT;
            }
            break;
        case SEND: ;
            JsonNode *cronfigChild = json_mkobject();
            cronfigChild = json_first_child(cronfig); // Memory leak
            char *location, *device, *state, *timeToSwitch;
            location = malloc(999); // Memory leak, why not location[999] ?
            device = malloc(999); // Memory leak
            state = malloc(999); // Memory leak
            timeToSwitch = malloc(999); // Memory leak

            //read systemtime
            time_t t;
            struct tm *ts;
            time(&t);
            ts = localtime(&t);
            strftime(systemTime, 6, "%H:%M", ts);
            printf("%s\n", systemTime);

            while(cronfigChild != NULL)
            {
                json_find_string(cronfigChild, "time", &timeToSwitch);
                if(strcmp(systemTime, timeToSwitch)==0)
                {
                    tmp = json_stringify(cronfigChild, NULL); // Memory Leak
                    printf("%s\n", tmp);
                    //Timer einlesen
                    json_find_string(cronfigChild, "location", &location);
                    json_find_string(cronfigChild, "devices", &device);
                    json_find_string(cronfigChild, "state", &state);

                    //Code erzeugen
                    json_delete(code);
                    code = json_mkobject();
                    json_append_member(code, "location", json_mkstring(location));
                    json_append_member(code, "device", json_mkstring(device));
                    json_append_member(code, "state", json_mkstring(state));

                    //Json erzeugen
                    json_delete(json);
                    json = json_mkobject();
                    json_append_member(json, "message", json_mkstring("send"));
                    json_append_member(json, "code", code);

                    //Senden
                    sendBuff = json_stringify(json, NULL); // Memory leak
                    printf("%s\n", sendBuff);
                    send(serverSocket, sendBuff, BUFSIZE, 0);

                }
                //naechsten Timer auswaehlen
                cronfigChild = cronfigChild->next;
            }
            goto close;
            break;
        case REJECT:
            break;
        default:
            goto close;
            break;
        }
    }

close:
    close(serverSocket);
    if(json)
    {
        json_delete(json);
    }
    if(code)
    {
        json_delete(code);
    }

return EXIT_SUCCESS;
}

A small tip, however, there are to much issues in your code to discuss on this forum:
If you want to have dynamic memory allocation, you use malloc/realloc:
Code:
char *buffer = realloc(message, strlen(message)+1);
...
free(buffer);
If you just going to use a fixed size memory buffer, you use a fixed array:
Code:
char buffer[1024];
The second one doesn't need to be freed and thereby doesn't leak memory. It however, most of the times, will make your program use more memory than it actually needs.
 
Reply
#22
Hey curlymo,
thanks for your quick reply and your revision.
My last c code is quite a while ago and I got in touch with c++ and java since then, hence I'm pretty spoiled in terms of memory management. Though I see your point and I'm sure I will get used to this again pretty quickly.

I would love to use your libraries though I had some difficulties compiling my code using them because of their dependencies to each other. Some reference was always missing.

What is your idea of the perfect modular event approach? By far I love this project and I would like to help/contribute in some way.
This could be the part taking care of time based events supplying an event handler on a higher level, as one programm could not possibly serve for handling all kinds of events(time, action, ...).
 
Reply
#23
Why don't you start a new thread so we can discuss the ultimate event json structure Smile

And of course, bad memory management in C is not unique. I altered AVRdude for embedded usage in pilight and i had to rewrite their whole linked list implementation due to massive memory leakages. Man, that avrdude is badly written Angry. Not such a big problem on modern operating systems when you run a program for about 30sec. The kernel will clean up all memory used by a program when it exits. However, i needed it to become a part of an infinite running daemon. Then memory leakages are a big issue.
 
Reply
#24
hello !
can someone help me ? i have copied the files both files pilight-cron.txt and pilight-lib.txt to /usr/local/bin/.

then i removed the .txt from the filenames. (is that correct?).
after that i copied this to my etc/crontab

* * * * * root /usr/bin/php /usr/local/bin/pilight-cron > /dev/null

then i put this in my cron.json

Code:
{
        "timer2":
        {
                "location":"wohnraum",
                "state":"on",
                "time":"19:41",
                "devices":["stehlampe"]
        }
}

this is my config file.

Code:
{
    "wohnraum": {
        "name": "Wohnraum",
        "temperatur": {
            "name": "Aussentemperatur",
            "protocol": [ "wunderground" ],
            "id": [{
                "api": "750977da0262d1b8",
                "location": "dortmund",
                "country": "de"
            }],
            "humidity": 6600,
            "temperature": 700
        },
        "stehlampe": {
            "name": "Stehlampe",
            "protocol": [ "elro_he" ],
            "id": [{
                "systemcode": 26,
                "unitcode": 16
            }],
            "state": "off"
        },
        "fasslampe": {
            "name": "Fasslampe",
            "protocol": [ "elro_he" ],
            "id": [{
                "systemcode": 26,
                "unitcode": 1
            }],
            "state": "off"
        },
        "weinregal": {
            "name": "Weinregal",
            "protocol": [ "elro_he" ],
            "id": [{
                "systemcode": 26,
                "unitcode": 8
            }],
            "state": "on"
        },
        "roterschrank": {
            "name": "Roter Schrank",
            "protocol": [ "elro_he" ],
            "id": [{
                "systemcode": 26,
                "unitcode": 4
            }],
            "state": "off"
        }
    },
    "Heizung": {
        "name": "Heizung",
        "temperatur": {
            "name": "Aussentemperatur",
            "protocol": [ "wunderground" ],
            "id": [{
                "api": "750977da0262d1b8",
                "location": "dortmund",
                "country": "de"
            }],
            "humidity": 6600,
            "temperature": 700
        },
        "Heizung": {
            "name": "Heizung",
            "protocol": [ "relay" ],
            "id": [{
                "gpio": 7
            }],
            "state": "off"
        }
    },
    "Balkon": {
        "name": "Balkon",
        "temperatur": {
            "name": "Aussentemperatur",
            "protocol": [ "wunderground" ],
            "id": [{
                "api": "750977da0262d1b8",
                "location": "dortmund",
                "country": "de"
            }],
            "humidity": 6600,
            "temperature": 700
        },
        "Deckenlampe": {
            "name": "Deckenlampe",
            "protocol": [ "elro_he" ],
            "id": [{
                "systemcode": 26,
                "unitcode": 2
            }],
            "state": "off"
        },
        "Stehlampe": {
            "name": "Stehlampe",
            "protocol": [ "elro_he" ],
            "id": [{
                "systemcode": 9,
                "unitcode": 1
            }],
            "state": "off"
        }
    },
    "Schlafzimmer": {
        "name": "Schlafzimmer",
        "temperatur": {
            "name": "Aussentemperatur",
            "protocol": [ "wunderground" ],
            "id": [{
                "api": "750977da0262d1b8",
                "location": "dortmund",
                "country": "de"
            }],
            "humidity": 6600,
            "temperature": 700
        },
        "Nachttischlampe": {
            "name": "Nachttischlampe",
            "protocol": [ "elro_he" ],
            "id": [{
                "systemcode": 26,
                "unitcode": 2
            }],
            "state": "off"
        }
    }
}

this doesen`t work, can someone please help me !?

Angel
 
Reply
#25
If you have one item you, don't need the [] to run.

I've made an new one which had some features that asked by curlymo on the first page

Currently i running this for some months now.

I've change my code from php to python to get some more speed.
Its now created as an module in python so you can make your own code with out knowledge of the api json code to run.

Example:
Code:
import pilight

p=pilight.pilight();
if p.connect():
   p.controller("living","light1","on");
p.close();

You find the update code with examples of my timers, so you can see what it can currently

Hoping you like this.

Gr Mark


Attached Files
.gz   python-pilight.tar.gz (Size: 5.11 KB / Downloads: 20)
 
Reply
#26
Smile 
@dzjaivnt
By chance I recognized this 'cron' feature for pilight. GREAT!
Also just from code it's hard to understand how to install/use it. Any pointer to help on this?
 
Reply
#27
Sorry, but need help here!

Starting 'pilight-cron' will ask
Code:
$ /home/pi/pilight-cron
Traceback (most recent call last):
  File "/home/pi/pilight-cron", line 6, in <module>
    import pilight
ImportError: No module named pilight

pilight is running (can switch with GUI, get :5001/config, etc).
So it seems my dir structure isn't correct.

Please advice, thanks!


PS Same with /usr/local/lib/pilight-cron after moving 'pilight-cron' to that dir
 
Reply
#28
Us need to add pilight.py also in the same directory, to use the pilight modules Smile
 
Reply
#29
Sorry, having piligt.py in the same dir will start, but throws an error like this:
Code:
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/pudb-2014.1-py2.7.egg/pudb/__init__.py", line 77, in runscript
    dbg._runscript(mainpyfile)
  File "/usr/local/lib/python2.7/dist-packages/pudb-2014.1-py2.7.egg/pudb/debugger.py", line 371, in _runscript
    self.run(statement, globals=globals_, locals=locals_)
  File "/usr/lib/python2.7/bdb.py", line 400, in run
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "/home/pi/pilight_py/pilight-cron.py", line 34, in <module>
    p.controller(str(locName),str(device),str("on"))
  File "/home/pi/pilight_py/pilight.py", line 93, in controller
    self.pilightsocket.send(message)
AttributeError: 'NoneType' object has no attribute 'send'

Does that mean there is another part missing or wrongly configured?
I tried to run the code on raspbery as well on the computer which also runs the webGui successfully (switching the devices or calling for the config with http://192.168.178.16:5001/config)
 
Reply
#30
Sad 
Not OK with the other setup ... so I tried to go back to a very simple setup on raspberryPI .. but it's failing also.

Please check the following and I hope someone can point to the problem Smile
cron_test.py
Code:
#!/usr/bin/python
import socket
import pilight

p=pilight.pilight()
if p.connect():
   p.controller("Ebene","lampe2","on")
p.close()

The dir has:
cron_test.py pilight.py

For debugging I have installed 'pudb' and running with
Code:
python -m pudb.run /home/pi/pilight_py/cron_test.py
which fails with this error logging:

Code:
cat traceback-2.txt
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/pudb-2014.1-py2.7.egg/pudb/__init__.py", line 77, in runscript
    dbg._runscript(mainpyfile)
  File "/usr/local/lib/python2.7/dist-packages/pudb-2014.1-py2.7.egg/pudb/debugger.py", line 371, in _runscript
    self.run(statement, globals=globals_, locals=locals_)
  File "/usr/lib/python2.7/bdb.py", line 400, in run
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "/home/pi/pilight_py/cron_test.py", line 6, in <module>
    if p.connect():
  File "/home/pi/pilight_py/pilight.py", line 77, in connect
    self.pilightsocket.connect((server, int(port)))
  File "/usr/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 111] Connection refused

As it can be seen I'm running this on the raspberry.
But on my other computer which also runs the webGui successfully (switching the devices or calling for the config with http://192.168.178.16:5001/config) the same error!

What is missing for this setup?
 
Reply
  


Possibly Related Threads...
Thread Author Replies Views Last Post
  [Done] pilight config read access for all gneandr 1 2,100 03-25-2015, 01:46 PM
Last Post: curlymo
  [Done] Eventing - operators MOD and DIV Niek 54 19,277 02-19-2015, 12:01 AM
Last Post: Niek
  [Done] pilight eventing - dimming step by step terrar 3 2,861 02-11-2015, 02:39 PM
Last Post: Niek
  [Done] pilight-daemon -V - currently requires root access clach04 1 2,564 10-25-2014, 11:39 PM
Last Post: wo_rasp
  [Done] pilight api: receiving and sending as gui client sweetpi 3 3,632 05-19-2014, 04:39 PM
Last Post: curlymo
  [Done] Continuous pilight-debug Tommybear1979 1 1,970 05-15-2014, 09:12 PM
Last Post: curlymo
  [Done] Eventlist (implemented with eventing) JurnD 18 7,426 01-16-2014, 08:39 PM
Last Post: curlymo
  [Done] auto detect pilight (for mobile/desktop apps) (SSDP) Martin 6 4,476 11-30-2013, 06:51 PM
Last Post: curlymo
  [Done] Message from pilight d.m.raspberry 5 2,938 09-23-2013, 10:25 AM
Last Post: curlymo

Forum Jump:


Browsing: 1 Guest(s)