Community
cancel
Showing results for 
Search instead for 
Did you mean: 
idata
Community Manager
1,531 Views

Using the Iotkit-comm library with Eclipse and Iot Analytics

Good Day

I'm working on a project involving uploading data from the edison board to the iot analytics site from eclipse using the iotkit-comm library. Doing it this way seems to bypass or work seperately from the iotkit-admin used in the command line. I'm currently testing my code working towards integration of two parts and every time I run it, it creates an new component element. So I get to a point where I cant display data on my graph because I have too many elements. Is there anyway to delete or reset components using iotkit-comm or any other means, since I cant use iotkit-admin commands?

My code so far looks as follows:

# include

# include

# include

# include

# include

# include

# include "iotkit-comm.h"

# include "util.h"

ServiceSpec *srvSpec = NULL;

ServiceSpec *srvSpec1 = NULL;

int msgnumber = 13; // sensor value

sig_atomic_t volatile isrunning = 1;

void sig_handler(int signum);

mraa_aio_context adc_a3, adc_a0;

uint16_t adc_value = 0, adc_value2 = 0;

float Volt, Curr;

void callback(void *handle, int32_t error_code, void *serviceHandle) {

Context context;

char msg[256];

int i = 0;

CommHandle *commHandle = NULL;

if(serviceHandle != NULL) {

commHandle = (CommHandle *) serviceHandle;

int (**publish) (char *message,Context context);

publish = commInterfacesLookup(commHandle, "publish");

if(publish == NULL) {

fprintf(stderr, "Function \'publish\' is not available; please verify the Plugin documentation !!\n");

return;

}

context.name = "topic";

context.value = "data";

while(i < 10) { // Event Loop

adc_value = mraa_aio_read(adc_a3);

Volt=((float)adc_value/1023)*(float)5.0;

sprintf(msg, "{\"name\": \"Volt\", \"value\": %.2f}", Volt);

printf("Publishing msg:%s\n", msg);

(*publish)(msg, context);

usleep(50000);

adc_value2 = mraa_aio_read(adc_a0);

Curr=((float)adc_value2/1023)*(float)5.0;

sprintf(msg, "{\"name\": \"Curr\", \"value\": %.2f}", Curr);

printf("Publishing msg:%s\n", msg);

(*publish)(msg, context);

usleep(50000);

i++;

}

}

// clean the objects

cleanUpService(&srvSpec, &commHandle);

exit(0);

}

void callback1(void *handle, int32_t error_code, void *serviceHandle) {

Context context;

char msg[256];

int i = 0;

CommHandle *commHandle = NULL;

if(serviceHandle != NULL) {

commHandle = (CommHandle *) serviceHandle;

int (**publish) (char *message,Context context);

publish = commInterfacesLookup(commHandle, "publish");

if(publish == NULL) {

fprintf(stderr, "Function \'publish\' is not available; please verify the Plugin documentation !!\n");

return;

}

context.name = "topic";

context.value = "data";

while(i < 10) { // Event Loop

adc_value2 = mraa_aio_read(adc_a0);

Curr=((float)adc_value2/1023)*(float)5.0;

sprintf(msg, "{\"name\": \"Curr\", \"value\": %.2f}", Curr);

printf("Publishing msg:%s\n", msg);

(*publish)(msg, context);

sleep(1);

i++;

}

}

// clean the objects

cleanUpService(&srvSpec, &commHandle);

exit(0);

}

int main(void) {

puts("Sample program to publish data to IoT Cloud !!");

signal(SIGINT, &sig_handler);

adc_a3 = mraa_aio_init(3);

adc_a0 = mraa_aio_init(0);

if(adc_a3 == NULL && adc_a0 == NULL)

{

return 1;

}

mraa_aio_set_bit(adc_a3,10);

mraa_aio_set_bit(adc_a0,10);

while(1)

{

srvSpec = (ServiceSpec *) parseServiceSpec("/usr/share/iotkit-comm/examples/c/serviceSpecs/InstaPower.json");

srvSpec1 = (ServiceSpec *) parseServiceSpec("/usr/share/iotkit-comm/examples/c/serviceSpecs/InstaCurrent.json"), srvSpec;

if (srvSpec1){

advertiseServiceBlocking(srvSpec, callback);

}

if (srvSpec1){

advertiseServiceBlocking(srvSpec1, callback1);

}

return 0;

}

}

void sig_handler(int signum)

{

if(signum == SIGINT)

isrunning = 0;

}

It's kind off a mess since I'm still working on it but basically running it as is, it takes two readings from analog inputs each with their own component service specification. Right now only one callback function is invoked but I'm publishing both values. The code is based off of tutorials found here: http://iotkit-comm-c.s3-website-us-west-2.amazonaws.com/api/iotkit-comm_8c.html# abf39be7571f5c0c84cb65867131ce7f9 Tutorials: src/lib/iotkit-comm/iotkit-comm.c File Reference

The resource material is limited so I'm pretty much going at it on my own at the moment but If anyone knows more about it, help would be very much appreciated.

Thanks

Tags (1)
0 Kudos
16 Replies
idata
Community Manager
30 Views

Hello PandaBanda,

 

 

I will try to help you with this. If you would like to delete or reset components and you are not able to do it with the iotkit-comm library, why don't you use a system call to use iotkit-admin commands just for this purpose? It is very simple to apply a system call, I suggest you to check the following example: https://www.tutorialspoint.com/c_standard_library/c_function_system.htm.

 

 

Please try this approach and let me know if it helps.

 

-Peter.
idata
Community Manager
30 Views

Hi Peter

That system call function is really neat and seems like it will be very useful in future so thanks for that. Unfortunately the device that I registered from Eclipse seems to be different from the one that I registered from the Linux environment using iotkit-admin. Using the iotkit-comm library I activated the device with the name Bluebot and in iotkit-admin I have the name Eddi. When I used the system call to return the device-id I got Eddi instead of Bluebot. I did try to reset the components anyways but that obviously didn't work.

I'm wondering if I could just use the system call function to publish sensor values using the iotkit-admin observation command? This would perhaps also fix the problem of me not being able to send float values to the dashboard from Eclipse, something I was able to do using the library with an arduino sketch and with iotkit-admin.

idata
Community Manager
30 Views

I believe the approach you mention about using the system call to publish sensor values using the iotkit-admin would be the best approach right now as this would avoid having two devices in two different environments. So, my suggestion is that you try to apply this to your code to see if it fits to your project's needs.

 

 

Let me know how it goes,

 

-Peter.
idata
Community Manager
30 Views

Ok so using the system call has been really great so far, however as I would like to send continuous data packets I want to move on from using the observation command of iotkit-admin to using the iotkit-agent directly. following the guide here: https://github.com/enableiot/iotkit-samples GitHub - enableiot/iotkit-samples: Demonstration code for the IoT Kit The command I should use, as I understand it, is:

iotkit-agent { "n": "Volt", "v": "2.6"}

to send a value of 2.6 to component Volt via UDP protocol. But my output ends up like this:

2016-09-23T10:09:05.735Z - info: Device has already been activated. Updating ...

2016-09-23T10:09:05.803Z - info: Updating metadata...

2016-09-23T10:09:05.885Z - info: Metadata updated.

2016-09-23T10:09:08.664Z - info: Starting listeners...

2016-09-23T10:09:08.905Z - info: Connecting to ws.us.enableiot.com:443...

2016-09-23T10:09:08.959Z - info: TCP listener started on port: 7070

2016-09-23T10:09:08.995Z - error: UDP Error: Error: bind EADDRINUSE 0.0.0.0:41234

at Object.exports._errnoException (util.js:870:11)

at exports._exceptionWithHostPort (util.js:893:20)

at dgram.js:214:18

at nextTickCallbackWith3Args (node.js:453:9)

at process._tickCallback (node.js:359:17)

2016-09-23T10:09:09.013Z - error: UncaughtException: listen EADDRINUSE 127.0.0.1:7070

2016-09-23T10:09:09.017Z - error: Error: listen EADDRINUSE 127.0.0.1:7070

at Object.exports._errnoException (util.js:870:11)

at exports._exceptionWithHostPort (util.js:893:20)

at Server._listen2 (net.js:1234:14)

at listen (net.js:1270:10)

at net.js:1379:9

at nextTickCallbackWith3Args (node.js:453:9)

at process._tickCallback (node.js:359:17)

I'm not sure what to make of this or how to troubleshoot it.

idata
Community Manager
30 Views

If I'm not mistaken, according to https://github.com/enableiot/iotkit-samples you should be sending the message to local host with a command similar to the following to send a UDP message:

 

 

echo -n '{ "n": "temp sensor", "v": "5", "on": 1401893417000}' | nc -u 127.0.0.1 41234

 

 

Could you please try the format above and let us know if the issue persists?

 

Let us know.

 

-Peter.
idata
Community Manager
30 Views

I tried to use that line but I got the following output:

BusyBox v1.22.1 (2016-06-06 14:50:27 PDT) multi-call binary.

Usage: nc [IPADDR PORT]

I tried taking out the -u after nc but then I got a error about not connecting to the remote host. I tried to use tcp but that didn't work either, didnt even get an error, it just didn't work. So I did a quick google on that first out output and I found this command

echo -n '{ "n": "Voltage", "v": 3.6}' > /dev/udp/localhost/41234

Seems to work just fine. Thanks for all the help.

idata
Community Manager
30 Views

Okay so I'm actually having trouble using that line with the system call function when I try to run it I get a "Segmentation fault". Which apparently happens when a program tries to read or write to an illegal memory location. I suspect it has to do with the "/dev/udp/localhost/41234" part of the command. Also I can't find any folders/files with that name when I search through the directories on the Edison. I'm not sure what to try at this point.

idata
Community Manager
30 Views

Does the line "echo -n '{ "n": "Voltage", "v": 3.6}' > /dev/udp/localhost/41234" work when it is not on a system call? Or is it simply accepted? I mean is the issue present only when that line is used on your code?

Let me know.

 

-Peter.
idata
Community Manager
30 Views

It works normally, but when used in my code it gives me that error

idata
Community Manager
30 Views

I'm not sure why this would happen. Please let me see what I can find out about this, if I find something useful I'll post it in here.

 

 

-Peter.
idata
Community Manager
30 Views

Hello PandaBanda,

 

 

I've an update for this.

 

 

The command echo -n '{ "n": "Voltage", "v": 3.6}' > /dev/udp/localhost/41234 is just writing a string to the udp port. Writing to a file from a code is not very practical, I suggest to include a UDP client inside the code that writes to local port "41234". Think of this port like a UDP Server that is listening. Once the data is received in the proper format, the "UDP Server" will send the data to the IoT Analytics.

 

 

Please try writing a simple UDP client that writes a string '{ "n": "Voltage", "v": 3.6}' to port 41234. The data should go to the cloud without any issues.

 

 

Please try this and let us know how it goes.

 

-Peter.
idata
Community Manager
30 Views

Hi Peter

First of all, I found the problem that caused the segmentation error, should have mentioned earlier. It happened to be that the "command" character array was too small for that line so I extended it and it started to work.

I also found a way to make the TCP format command (echo -n '28# { \"n\": \"Voltage\", \"v\": %.2f}' | nc 127.0.0.1 7070) to work. For the TCP command to work you have to specify the exact message length that you want to send like 28 in the case above. My problem with this is that if a value changes from 1 digit to 2 digits for example, then the tcp message length would change and my data would not be sent. I would also have no way of knowing that the submission failed unless I checked the agent.log file in the /tmp folder of the Edison.

The only command that doesn't work is the UDP command in the format:

echo -n '{ "n": "temp sensor", "v": "5", "on": 1401893417000}' | nc -u 127.0.0.1 41234

which would have been ideal. I like your suggestion of writing a UDP client in the code but I'm not sure how I would go about doing this or how to implement it in my current code. How does it differ from the line above? Are there any tutorials or documents that provide more information on this? I'm still trying to understand how this all works.

Thanks, I really appreciate the help you've provided.

idata
Community Manager
30 Views

'I'm glad to hear that you found what was causing the segmentation issue and that you found a way to make the TCP command work.

 

 

Regarding the UDP client, there are no examples for this specific application, nevertheless, I found some guides/examples online that might be of help for you:

 

 

https://www.abc.se/~m6695/udp.html

 

http://www.programminglogic.com/sockets-programming-in-c-using-udp-datagrams/

 

http://web.cecs.pdx.edu/~jrb/tcpip/sockets/ipv6.src/udp/udpclient.c

 

https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c

 

https://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html

 

http://www.cs.rpi.edu/~goldsd/docs/spring2014-csci4220/echo-client-udp.c.txt

 

 

Please check them to see if they are of help for you.

 

-Peter.
idata
Community Manager
30 Views

Hello PandaBanda,

 

 

Do you have any updates about this?

 

 

-Peter.
idata
Community Manager
30 Views

Hi Peter

I'm so sorry for the inactivity, this got a bit hectic with school activities being suspended.

I decided to stick to sending the UDP strings to the file as before instead of writing the UDP client in code since this worked sufficiently for my project. I would have liked to try writing the UDP client at a later stage but since the IoT Analytics service is now discontinued I guess I can't do that anymore.

But thanks so much for all your help up to this point.

idata
Community Manager
30 Views

Thank you for keeping us up to date. As you mentioned, the service is now discontinued, however, you can find several alternatives in https://software.intel.com/en-us/iot/hardware/edison# cloud. Please check them in case you are still interested in a cloud analytics-like approach.

 

 

-Peter.
Reply