Problem with thinger client programming in Linux


#1

Hi
I’m new here and in this platform. I came across in some problems on linux client programming. I’m trying to stream data from a similar RPi platform to the thinger server but I am a bit confused about how and what I have to send.

I have a function that retrieves data from a serial port and this could be temperatures, relays on/off, led colors, etc. of another electronic board. If I receive a packet with register 0x01 and data filed is “00000001”, for example, it means that the first relay is on. This relay is on if a door of an oven is open. So i want to show in thinger’s dashboard “Door is open”. My idea was:

string send (int relayNumber){
    switch(relayNumber){
        case 1:
            return "on"  //DOOR IS OPEN
            break;
         case 2:
            return "off" //DOOR IS CLOSED
            break;
    }
}

int main(int argc, char * argv[]){
    do{ 
        thing ["data"] >> [](pson& out){
            string status = send(1);
            out["relay"] = status;
        };
        thing.handle();
        thing.stream(thing["data"]);
    }while(1);
}

The application compile correctly but it does not send any data to the bucket, and in the device API I can see an infinite loading. What solution could i adopt? Thanks!


#2

Hi @Takenfal, did you tried to define the resource outside the loop?, like:

int main(int argc, char * argv[]){
        thing ["relay"] >> [](pson& out){
            string status = send(1);
            out = status;
        };
    do{      
        thing.handle();
        thing.stream(thing["relay"]);
    }while(1);
}

Each resource should be defined just once in the code. I also recommend you to only stream the resource only when a change to this resource has been made. This would save a lot of bandwidth.

Best!


#3

Hi! First of all thanks for answering my question.
Reading the documentation I figured out that I had to move the resource out of the loop, as you said. Now everything works excepts the update. In the data bucket, I set the refresh mode as “update by device”, so every time something changes I should see it istantanley. The problem is that the bucket refresh values even after 1 second. I’ll explain:
I have this kind of RPi (called Gateway) that runs a software useful to intercept data between two electronic board (of an industrial oven). Now the primary board (where runs Android) is set to send data only if something happens, like switching a relay on or off. Now if I switch on a relay, the primay board sends the command to the secondary where there are all physical relays. The gateway intercepts this packet and sends a string to thinger (“Relay 1 on”, for example). But it’s not in real time. I post the code:

string translateData(Buffer[]){
    //HERE I DETERMINE WHICH OPERATION HAS BEEN DONE AND I RETURN THE STRING;
    //SO I RETURN RELAY1 ON, RELAY2OFF, etc.
    //IT'S JUST A SWITCH-CASE.
}

string serialRead(){
    //HERE I READ DATA FROM THE SERIAL PORT AND SEND IT TO translateData METHOD
    return translateData (buffer[]);
}

main(){
    fd = openPort(); //SERIAL PORT
    thing["multipleData"] >> [](pson& out){
        out[component] = data;         //IN THE translateData() METHOD I DEFINE BOTH component (RELAY1, RELAY2, etc.) AND data (ON, OFF, etc.) 
    };
    string temp = "";	
    do{
        thing.handle();
        data = serialRead();
        if(data!=temp && data!=""){
	        thing.stream(thing["multipleData"]);
  	        temp=data;
	    }
    }while(1);
return 0;
}

I don’t know where the problem should be.

UPDATE:

Ok, if I put the thing.handle(); out of the loop, the application runs correctly; i mean, data will sent every time something happens, not every second. But, if something changes too frequently (like every 20 ms) i get “Segmentation fault” error. It is strange because if I change the function call (data = serialRead()) with a static string (data = "HI"), thinger sends it without problems at “full speed”, so on the device page i see a lot of MB of data incomimg.


#4

Hi @Takenfal, your code seems to be ok, but your program is not working in real-time, as the thing.handle() method has a 1 second timeout that is waiting for server responses (and also avoiding running the loop constantly, which will turn your CPU to 100%). You need to call the thing.handle() inside the loop, or the server may disconnect you, or your device not react to server queries. If you want, you can decrease the timeout in this class:

You can modify:

tv.tv_sec = 1;
tv.tv_usec = 0;

to something like: (adjust to meet your use case, and monitor your CPU).

tv.tv_sec = 0;
tv.tv_usec = 10000; //0,01 seconds (usec are microseconds).

However, it could be even better to use threads for such things (to avoid high CPU usage). One thread reading from serial, and another one for handling thinger connection and streaming at an appropriate rate. However, this will take some more time and knowledge.

Eventually, I will be releasing an ASIO linux client to handle the client connections much much much efficiently. But it will require some dependencies like Boost Libraries.


#5

Thanks a lot! Your information is precious! Sorry for bothering you but I have two other questions:

  1. Even using the threads (one for reading from the serial and another for handle and streaming data) I get “segmentation fault” error every time I use serialRead() method instead of sending a single string variable lilke “Hello”. If I run the program using serialRead() method, the program starts without problem and it waits unti data is sent from the two boards. But at the exact time when a data is sent, I get segmentation fault error.

  2. It is possible to link the data bucket to an external database?

EDIT: Ok, the problem of the first point is because of the run.sh. I compiled the program with g++ and no more segmentation fault error occured.