1 2 Previous Next 28 Replies Latest reply on Mar 25, 2015 12:17 PM by ForumMigrationAdmin

    IoT dashboard Control/Actuator working code or tutorial?

    ForumMigrationAdmin

      Hi there,

      I am new to all of this, but fairly technical, UNIX guy, some coding background but I am not a developer full time and am trying to learn Intel's Edison IoT.  I have a new Edison and an Arduino and am using the Arduino IDE and SSH to the device. When I started I re-flashed the Edison with the latest and set up an IoT Analytics account. I have the device registered with and and able to send to the analytics dashboard (https://dashboard.us.enableiot.com) and it works fine. I have sent a number of observations temp, humidity and a "seismograph" sensor I created. It all worked fine. I am also able to connect to the Arduino/Edison and read and activate a number of Grove sensors, etc. and it all works fine. I can turn lights on, flash them, read the sound, temp sensors, turn on the relay, etc. all fine.

      What I am REALLY trying to do is control an LED from the Cloud. After reading all of the tutorials and getting this far I tried to run the Actuator example program and it didn't work. First it was syntax errors by I managed to correct those (conflicting libraries between the iotkit and arduino libraries. The code compiles fine and I am able to successfully send a command (LED On, value 1, component "powerswitch", command "LED.v1.0", value 1 and did this 5 times successfully tonight.

      The problem is nothing happens on the board! No light, no message in the serial window, no message to the user, no error, nothing.

      I read that you have to enable mgtt mode not REST so I did that but I'm at a loss. the sample code is complicated to me and I don;t udnerstand all parts of what it is doing. My specific questions are:

      • how can I view/see a log to even know if the Edison received the call from the cloud?
      • I know the agent is running on the device and can send commands directly from the terminal on my Mac and they work.
      • In looking at the code it is unclear to me where the payload is coming in from the cloud server - I see some aJsonObject lines and assume that's them but have no idea what's supposed to be happening there and if it is

      Here's the sample code that comes with the iotkit dist (I haven't edited it at all but would change "component" and command to match mine (powerswitch and LED.v1.0). (I am particularly curious about the iotkit.send("power", 1) - why would it be sending when the objective is to receive a 1 or 0 from the cloud??)

      //This example reacts for default actuator component if registered on device
      //LED.v1.0 command is used
      //When executed from Control section on dashboard with value 0, LED light is turned off
      //When executed from Control section on dashboard with value 1, LED light is turned on
      //iotkit-agent must use MQTT connection (not REST) for actuation to work.
      //It also sends 1 as power when agent is started.

      #include <IoTkit.h>    // include IoTkit.h to use the Intel IoT Kit
      #include <Ethernet.h>  // must be included to use IoTkit
      #include <aJSON.h>
      #include <stdio.h>

      // create an object of the IoTkit class
      IoTkit iotkit;       
      int temp;
      char buf[112];

      void setup() {
        Serial.begin(115200);
        // call begin on the IoTkit object before calling any other methods
        iotkit.begin();
        delay(10500);
        iotkit.send("power", 1);
      }

      void loop() {
        iotkit.receive(callback);
        delay(5000);
      }

      void callback(char* json) {
        Serial.println(json);
        aJsonObject* parsed = aJson.parse(json);
        if (&parsed == NULL) {
          // invalid or empty JSON
          Serial.println("recieved invalid JSON");
          return;
        }
        
        aJsonObject* component = aJson.getObjectItem(parsed, "component");
        aJsonObject* command = aJson.getObjectItem(parsed, "command");
        aJsonObject* argv = aJson.getObjectItem(parsed, "argv");
        aJsonObject* argvArray = argv->child;
        aJsonObject* name = argvArray->child; // name : on
        aJsonObject* value = name->next; // value: 1/0
       
        if ((component != NULL)) {
          if (strcmp(component->valuestring, "actuator") == 0) {
            if ((command != NULL)) {
              if (strcmp(command->valuestring, "light") == 0 && strcmp(value->valuestring, "0") == 0) {
                Serial.println("Light Off!");
                pinMode(13, OUTPUT);
                digitalWrite(13, false);
              }
              if (strcmp(command->valuestring, "light") == 0 && strcmp(value->valuestring, "1") == 0) {
                Serial.println("Light on!");
                pinMode(13, OUTPUT);
                digitalWrite(13, true);
              }
            }
          }
        }
      }

      Thanks to anyone who can help - I am at a standstill at this point and appreciate any feedback that could get me sorted.

      D.

        • 1. Re: IoT dashboard Control/Actuator working code or tutorial?
          ForumMigrationAdmin

          Hi David.
          You're almost there. The agent log is in /tmp/agent.log. I would tail this log as you run your actuation example sketch so you can see incoming/outgoing messages processed by the agent:
          # tail -f /tmp/agent.log

          One thing to note: if you register a new component on your device, you will need to restart the agent:
          # systemctl restart iotkit-agent

          You should see the following in the log as the actuation message comes in from the Cloud:

          {
              "type": "command",
              "transport": "mqtt",
              "content": {
                  "domainId": "c349d0ef-a076-413a-a447-xxxxxxxxx",
                  "deviceId": "jasper-edison",
                  "gatewayId": "jasper-edison",
                  "componentId": "805110c5-8f82-4494-a0aa-xxxxxxxxx",
                  "command": "LED.v1.0",
                  "params": [{
                      "name": "LED",
                      "value": "1"
                  }]

              },
              "level": "info",
              "message": "STATUS: device/jasper-edison/control",
              "timestamp": "2015-02-03T21:59:38.611Z"
          }
          {
              "level": "info",
              "message": "Fired STATUS: %sdevice/jasper-edison/control{\"type\":\"command\",\"transport\":\"mqtt\",\"content\":{\"domainId\":\"c349d0ef-a076-413a-a447-xxxxxxx\",\"deviceId\":\"jasper-edison\",\"gatewayId\":\"jasper-edison\",\"componentId\":\"805110c5-8f82-4494-a0aa-xxxxxxxx\",\"command\":\"LED.v1.0\",\"params\":[{\"name\":\"LED\",\"value\":\"1\"}]}}",
              "timestamp": "2015-02-03T21:59:38.614Z"
          }

          The "callback" function in the sketch is called every 5 seconds (by iotkit.receive) and will handle the actuation message being relayed by the client. The function then parses the message to look for the "LED" parameter value. It will set board pin 13 to that value (0 or 1)..

          Brian

          • 2. Re: IoT dashboard Control/Actuator working code or tutorial?
            ForumMigrationAdmin

            Aside from the other actuation samples for Python and Node.js, there is some further information in the agent wiki in GitHub.

            Samples repo:
            Python
            Node.js

            Good luck and let me know how it goes.
            Brian

            • 3. Re: IoT dashboard Control/Actuator working code or tutorial?
              ForumMigrationAdmin

              Thanks very much for replying Brian - very much appreciated. I'm completely stuck.

              I assume when you say the log is /tmp/agent.log you mean /tmp on the Edison/Arduino, not on my Mac, correct? I logged in to the Edison via Serial as root. I went cd /tmp and ls and I see no agent.log. I looked at what was there and this is what I see. the files in /tmp are bolded below:

                           Poky (Yocto Project Reference Distro) 1.6 Interactio_Hub ttyMFD2

                           Interactio_Hub login: root
                           Password:
                           [   30.987805] systemd-fsck[262]: /dev/mmcblk0p10: recovering journal
                           [   31.048046] systemd-fsck[262]: /dev/mmcblk0p10 contains a file system with errors, check forced.
                           [   31.174725] systemd-fsck[262]: /dev/mmcblk0p10: 17/152608 files (0.0% non-contiguous), 26872/610299 blocks
                           root@Interactio_Hub:~#                  
                          root@Interactio_Hub:~#
                          root@Interactio_Hub:~# cd /tmp
                          root@Interactio_Hub:/tmp# ls
                          log.txt
                          log_er.txt
                          systemd-private-1639e800f5cc41d69c807e406f8ffd21-systemd-timesyncd.service-GEit4F
                          watchdog-sample.tmp

                          wpa_ctrl_235-1

               

              Perhaps I have to turn logging on? I don't even know how nor have I been able to find any complete documentation for iotkit...

              Also, I tried "tailing" agent.log as you suggested:

              1. what is "tailing"
              2. when I did it I sent a package from the dashboard which it said was sent but nothing happened or changed on my end and it took over my serial screen and I had to reboot the Arduino to get it back.

              Last question - I am not sure that i have the syntax correct in the sketch. I have a component (the default actually) called "powerswitch" (all lower case). It is registered and seems OK both in the dashboard and by iotkit on the device. As I say I am able to send to it. It says it's Command String is "LED.v1.0". I have edited this is the sketch to change thew word component to powerswitch and command to LED.v1.0. Do I need to change any of the others? For instance, I also see:

              • power (in iotkit.send("power", 1);
              • an integer variable called "temp" which doesn;t appear to be referenced anywhere - is it leftover or ??
              • argv - not sure what this is
              • then in the IF statements there are "actuator" and "light"
              • last, in the IF statements there are pinmode commands to send the high or low bit, but they both say pinmode(13, OUTPUT); - do I need to change OUTPUT to 1 and 0 respectively??

              Since it's supposed to be a beginner example I was hoping there would be some clear documentation describing line by line what it's doing and what the variables are...

              I'm sorry, I'm not a developer and am just trying to turn a light on/off from the Cloud for a prototype I am building. Very frustrating!

              Thanks again,

              David

              • 4. Re: IoT dashboard Control/Actuator working code or tutorial?
                ForumMigrationAdmin

                Quick update - I was able to vi agent.log. Is it hidden?? Here is what I see:

                {"level":"info","message":"Trying to connect to host ...","timestamp":"2015-02-0
                {"level":"info","message":"Starting Health testing ","timestamp":"2015-02-03T23:
                {"level":"info","message":"Trying with Secure Connection tobroker.us.enableiot.c
                {"level":"info","message":"Waiting for MQTTConnector to connect # 1","timestamp"
                {"level":"info","message":"MQTTConnector: Connection successful to broker.us.ena
                {"kind":"healthcheck","isHealthy":true,"currentSetting":"PROD","name":"iotkit-ga
                {"level":"info","message":"Connected to broker.us.enableiot.com","timestamp":"20
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                ~
                - /tmp/agent.log 1/7 14%

                • 5. Re: IoT dashboard Control/Actuator working code or tutorial?
                  ForumMigrationAdmin

                  Update later tonight.

                  I have spent hours going through the actuator code and here is what I have now. Note: I am just trying to see the json payload in the serial terminal at this point, so all I am doing is running the code, printing "online" in the serial window and turning the LED on. My intent here is to try to understand the sequence of the code. Ideally I would step through the code or even better, echo each line as it executes so i could see where it is failing. No printlns appear other than online when i execute the code below.

                  So, I have narrowed my question/confusion down somewhat - I don't think the callback procedure is running at all, as I am getting no "SerialPrintln"s at all even though I added some to "echo" the code execution. My question at this point is where should the callback procedure be in the code (in the loop or not? I suspect not because it is defining the procedure).

                  This brings me to my next question - what calls the callback procedure and also the aJsonObject* calls?

                  #include <IoTkit.h>    // include IoTkit.h to use the Intel IoT Kit
                  #include <Ethernet.h>  // must be included to use IoTkit
                  #include <aJSON.h>
                  #include <stdio.h>

                  // create an object of the IoTkit class
                  IoTkit iotkit;       
                  //int temp;
                  int led = 8;
                  char buf[112];

                  void setup() {
                    Serial.begin(115200);
                    // call begin on the IoTkit object before calling any other methods
                    iotkit.begin();
                    delay(3000);
                    Serial.println("online");
                    iotkit.send("power", 1);
                    pinMode(led, OUTPUT);
                    digitalWrite(led, 1);        // turn the LED on (HIGH is the voltage level)
                  }

                  void loop() {
                    iotkit.receive(callback);    // wait for payload from Cloud via JSon
                    delay(2000);                 // the loop routine runs over and over again forever:
                  }

                  void callback(char* json) {
                    Serial.println(json);
                    aJsonObject* parsed = aJson.parse(json);
                    Serial.println("test callback is running?");
                    if (&parsed == NULL) {
                      // invalid or empty JSON
                      Serial.println("recieved invalid JSON");
                      return;
                    }
                    
                    aJsonObject* component = aJson.getObjectItem(parsed, "powerswitch");
                    Serial.println("powerswitch");
                    aJsonObject* command = aJson.getObjectItem(parsed, "LED.v1.0");
                    Serial.println("LED.v1.0");
                    aJsonObject* argv = aJson.getObjectItem(parsed, "argv");
                    Serial.println("argv");
                    aJsonObject* argvArray = argv->child;
                    aJsonObject* name = argvArray->child; // name : on
                    aJsonObject* value = name->next; // value: 1/0 

                  //  if ((component != NULL)) {
                  //    if (strcmp(component->valuestring, "actuator") == 0) {
                  //      if ((command != NULL)) {
                  //        if (strcmp(command->valuestring, "light") == 0 && strcmp(value->valuestring, "0") == 0) {
                  //          Serial.println("Light Off!");
                  //          pinMode(led, OUTPUT);
                  //          digitalWrite(led, 0);
                  //        }
                  //        if (strcmp(command->valuestring, "light") == 0 && strcmp(value->valuestring, "1") == 0) {
                  //          Serial.println("Light on!");
                  //          pinMode(led, OUTPUT);
                  //          digitalWrite(led, 1);
                  //        }
                  //      }
                  //    }
                  // }

                  }

                  Last, I checked to make sure iotkit-agent is running. It is, but I noticed an intermittent issue where when executing some agent commands I get a bad username/password error:

                  root@Interactio_Hub:~# iotkit-agent catalog
                  2015-02-04T05:52:01.063Z - info: Trying to disconnect
                  2015-02-04T05:52:01.092Z - info: Sending attributes...
                  2015-02-04T05:52:01.101Z - info: Trying with Secure Connection tobroker.us.enableiot.com:8883
                  2015-02-04T05:52:01.143Z - info: Waiting for MQTTConnector to connect # 1
                  2015-02-04T05:52:02.018Z - error: UncaughtException: Connection refused: Bad username or password
                  2015-02-04T05:52:02.044Z - error: Error: Connection refused: Bad username or password

                      at MqttClient._handleConnack (/usr/lib/node_modules/iotkit-agent/node_modules/mqtt/lib/client.js:508:9)
                      at Connection.<anonymous> (/usr/lib/node_modules/iotkit-agent/node_modules/mqtt/lib/client.js:191:10)
                      at Connection.EventEmitter.emit (events.js:95:17)
                      at Connection._write (/usr/lib/node_modules/iotkit-agent/node_modules/mqtt/lib/connection.js:187:12)
                      at doWrite (_stream_writable.js:226:10)
                      at writeOrBuffer (_stream_writable.js:216:5)
                      at Connection.Writable.write (_stream_writable.js:183:11)
                      at write (_stream_readable.js:582:24)
                      at flow (_stream_readable.js:591:7)
                      at CleartextStream.pipeOnReadable (_stream_readable.js:623:5)

                  I Googled this but can't find anything useful. Does uname and pwd get defined anywhere?? I am assuming this is username and pwd for dashboard.us.enableiot.com?

                  Thanks again in advance - any help is appreciated.

                  David

                  • 6. Re: IoT dashboard Control/Actuator working code or tutorial?
                    ForumMigrationAdmin

                    Thanks for your patience. You're doing all the right things from a debugging perspective. From the log, it looks like your agent is running fine. Can you check which version of the agent you have? In the Edison console window run:
                    # iotkit-admin -V

                    If it's older than 1.5.1 then actuation is broken and you will need to update the agent. The agent isn't able to understand actuation messages before that version. Also, there was a server upgrade yesterday so I need to check on the errors you are seeing in the log. You shouldn't need to worry about any usernames or passwords.

                    Regarding your questions on the sketch. The sketch uses a component named "power". Here's a summary of what happens during the sketch:

                    Runs once at start:
                    void setup() {
                      Serial.begin(115200);
                      // this initializes the serial console
                      // call begin on the IoTkit object before calling any other methods
                      iotkit.begin();  // this opens UDP ports 41234 for sending and 41235 for listening
                      delay(10500); // wait 10.5sec
                    iotkit.send("power", 1); // send a test observation to the Cloud for component "power" (value=1). You should see this in the agent log
                    }

                    Runs continuously:
                    void loop() {
                      iotkit.receive(callback);
                    // listens to UDP port 41235 for actuation messages and calls "callback" if one is received
                      delay(5000); // wait 5sec
                    }

                    For the logic in "callback" that toggles the LED,
                    pinMode(13, OUTPUT);  // sets pin-13 for writing (output)
                    digitalWrite(13, false/true); // sets pin-13 to on/off (1 or 0)

                    The rest of the "callback" sketch is mainly parsing the JSON data structure that the agent is sending. It's pretty messy in C so the code looks ugly. The message format from the agent looks like:

                    {
                        "component": "power",
                        "command": "LED.v1.0",
                        "argv": [{
                           "name": "LED",
                            "value": "1"
                        }]
                    }

                    The important parts of the message are "component", "name" and "value". "Power" should be the name of your component. It should only have one parameter - "LED". These are the parameters you set on the web page when you submitted the actuation request.

                    Also, "tail" is a Linux command that lists the last few lines of a file. It's useful (with the '-f' option) to continuously display the end of a log file. I'll run the command on my Edison in my console terminal and i'll see the agent activity as my sketches run. (hit control-C to exit tail)
                    # tail -f /tmp/agent.log

                    Brian

                    • 7. Re: IoT dashboard Control/Actuator working code or tutorial?
                      ForumMigrationAdmin

                      Awesome information - thanks a million.

                      I checked the version and I have 1.5.0. Oddly, I downloaded this Feb 2nd and re-flashed the Edison so one would assume it was up to date, but apparently not. I'm thinking it would be a good idea for Intel to update the dist. that links from the iot downloads page.

                      I'll start by doing the update with npm as outlined on the wiki - hopefully it works. it says it's installing version 1.6.4. I'm really surprised that the default I had was 1.5.0 given I installed in Monday...

                      Once (if) I get that done I'll try to re-register the device as "power" not "powerswitch" and go from there. When you say the one parameter is LED does that mean i can drop the v1.0 off LED.v1.0?

                      Thanks Brian - you're a life saver.

                      David

                      • 8. Re: IoT dashboard Control/Actuator working code or tutorial?
                        ForumMigrationAdmin

                        I really don;t know what to do with this thing at this point (let's just say a hammer is looking pretty good at this point!)

                        I try to update iotkit-agent. I can't find any clear instructions, so I follow this:

                        2.3.2. Agent is not pre-installed

                        If you are working on a device other than a Galileo or Edison, or the agent is not pre-installed: 

                        You may need to install Node.js and npm first. Please see the Node.js web site for instructions. 

                        You will need to install the agent and it’s dependencies. To do that, “cd” to the directory where you want the agent installed and type:

                              npm install iotkit-agent

                              mv node_modules/iotkit-agent/ .

                              rm –rf node_modules

                        First command - success!

                        Second command (mv command) - fails. Says I cannot modify it since it is not a directory. This is Intel documentation about Intel code on an Intel board - this should just work; someone needs to check this stuff for errors and edit it, geez.

                        I decided to skip it and restart the Edison. I do so (twice) and get this:

                        root@Interactio_Hub:/usr/bin# iotkit-admin test
                        2015-02-04T22:49:34.887Z - info: Trying to connect to host ...
                        2015-02-04T22:49:34.915Z - info: Starting Health testing
                        2015-02-04T22:49:34.923Z - info: Trying with Secure Connection tobroker.us.enableiot.com:8883
                        2015-02-04T22:49:34.974Z - info: Waiting for MQTTConnector to connect # 1
                        2015-02-04T22:49:36.479Z - info: MQTTConnector: Connection successful to broker.us.enableiot.com:8883
                        2015-02-04T22:49:36.677Z - info: STATUS: device/e6-2b-c2-c2-86-7e/health kind=healthcheck, isHealthy=true, currentSetting=PROD, name=iotkit-gateway, build=0.12.
                        0, date=2015-01-26T13:46:41.332Z, items=[connected=true]
                        2015-02-04T22:49:36.685Z - info: Fired STATUS: %sdevice/e6-2b-c2-c2-86-7e/health{"kind":"healthcheck","isHealthy":true,"currentSetting":"PROD","name":"iotkit-ga
                        teway","build":"0.12.0","date":"2015-01-26T13:46:41.332Z","items":[{"broker":{"connected":true}}]}
                        2015-02-04T22:49:36.692Z - info: Connected to broker.us.enableiot.com
                        2015-02-04T22:49:36.694Z - info: Environment: PROD
                        2015-02-04T22:49:36.695Z - info: Build: 0.12.0
                        root@Interactio_Hub:/usr/bin# iotkit-agent -V
                        2015-02-04T22:49:50.596Z - info: Trying to disconnect
                        2015-02-04T22:49:50.631Z - info: Sending attributes...
                        2015-02-04T22:49:50.640Z - info: Trying with Secure Connection tobroker.us.enableiot.com:8883
                        2015-02-04T22:49:50.692Z - info: Waiting for MQTTConnector to connect # 1
                        2015-02-04T22:49:50.915Z - error: UncaughtException: Connection refused: Bad username or password
                        2015-02-04T22:49:50.945Z - error: Error: Connection refused: Bad username or password

                            at MqttClient._handleConnack (/usr/lib/node_modules/iotkit-agent/node_modules/mqtt/lib/client.js:508:9)
                            at Connection.<anonymous> (/usr/lib/node_modules/iotkit-agent/node_modules/mqtt/lib/client.js:191:10)
                            at Connection.EventEmitter.emit (events.js:95:17)
                            at Connection._write (/usr/lib/node_modules/iotkit-agent/node_modules/mqtt/lib/connection.js:187:12)
                            at doWrite (_stream_writable.js:226:10)
                            at writeOrBuffer (_stream_writable.js:216:5)
                            at Connection.Writable.write (_stream_writable.js:183:11)
                            at write (_stream_readable.js:582:24)
                            at flow (_stream_readable.js:591:7)
                            at CleartextStream.pipeOnReadable (_stream_readable.js:623:5)
                        root@Interactio_Hub:/usr/bin#

                        The agent will not start, athough the iotkit-admin test worlks successfully.,

                        Now I can't even run iotkit-agent -V to see what version it is.

                        Is it just me or ???

                        Thanks...

                        • 9. Re: IoT dashboard Control/Actuator working code or tutorial?
                          ForumMigrationAdmin

                          OK, thanks to several messages and help from Brian I managed to get it working but it was a host of problems:

                          First - the iotkit version on the Edison was too old. I downloaded and flashed the latest Edison image (Rel-1-Maint-WW42 fromhttps://communities.intel.com/docs/DOC-23242) on Monday but evidently they include a very old iotkit in that dist (1.5.0). Actuation will not work with anything below 1.5.1.  you can see what version you have by typing:

                          iotkit.admin - V

                          To upgrade it, once you have the Edison flashed and connected to the internet, run the following command (from Brian):

                          npm update -g iotkit-agent

                          The latest I installed today was 1.6.4

                          Second - the example code included in the iotkit dist is horribly wrong. Here are the details as I sent them to Brian tonight at 11:46pm Pacific time (I hope this helps someone else):

                          Here is what I see in my serial monitor. this is the JSON payload from the IoT Analytics Dashboard (plus some printlns I echoed to see what was happening):

                          Good JSON Command from Server: {"component":"power","command":"LED.v1.0","argv":[{"name":"LED","value":"1"}]}
                          {"component":"power","command":"LED.v1.0","argv":[{"name":"LED","value":"1"}]}
                          OK just finished aJsonObject lines
                          begin loop after comp null line
                          continue, now after strcmp power in loop
                          continue, now after command null in loop
                          Light on!
                          Good JSON Command from Server: {"component":"power","command":"LED.v1.0","argv":[{"name":"LED","value":"0"}]}
                          {"component":"power","command":"LED.v1.0","argv":[{"name":"LED","value":"0"}]}
                          OK just finished aJsonObject lines
                          begin loop after comp null line
                          continue, now after strcmp power in loop
                          continue, now after command null in loop
                          continue, now after strcmp command LED line in loop
                          Light Off!

                          and here is the code I am running:

                          #include <IoTkit.h>    // include IoTkit.h to use the Intel IoT Kit
                          #include <Ethernet.h>  // must be included to use IoTkit
                          #include <aJSON.h>
                          #include <stdio.h>

                          // create an object of the IoTkit class
                          IoTkit iotkit;       
                          int temp;
                          //int LED;
                          char buf[112];

                          void setup() {
                            Serial.begin(115200);
                            // call begin on the IoTkit object before calling any other methods
                            iotkit.begin();
                            delay(10500);
                            iotkit.send("power", 1);
                          }

                          void loop() {
                            iotkit.receive(callback);
                            delay(5000);
                          }

                          void callback(char* json) {
                            Serial.println(json);
                            aJsonObject* parsed = aJson.parse(json);
                            if (&parsed == NULL) {
                              // invalid or empty JSON
                              Serial.println("recieved invalid JSON");
                              return;
                            }

                          aJsonObject* component = aJson.getObjectItem(parsed, "power");
                            aJsonObject* command = aJson.getObjectItem(parsed, "LED.v1.0");
                            aJsonObject* argv = aJson.getObjectItem(parsed, "argv");
                            aJsonObject* argvArray = argv->child;
                            aJsonObject* name = argvArray->child; // name : on
                            aJsonObject* value = name->next; // value: 1/0
                            Serial.println("OK just finished aJsonObject lines");
                           
                          //  if ((component != NULL)) {       // was stopping here
                              Serial.println("begin loop after comp null line");
                          //    if (strcmp(component->valuestring, "power") == 0) {    //changed to power from actuator
                          //      strcmp(component->valuestring, "power");              //changed to power from actuator
                                  Serial.println("continue, now after strcmp power in loop");
                          //      if ((command != NULL)) {
                                  Serial.println("continue, now after command null in loop");
                          //      if (strcmp(command->valuestring, "LED.v1.0") == 0 && strcmp(value->valuestring, "0") == 0) { //changed to LED.v1.0 from light
                                  if (strcmp(value->valuestring, "1")) { //changed to LED.v1.0 from light
                                    Serial.println("continue, now after strcmp command LED line in loop");
                                    Serial.println("Light Off!");
                                    pinMode(13, OUTPUT);
                                    digitalWrite(13, 0); //should false be changed to 0?
                                  }
                          //      if (strcmp(command->valuestring, "LED") == 0 && strcmp(value->valuestring, "1") == 0) {
                                  if (strcmp(value->valuestring, "0")) {
                                    Serial.println("Light on!");
                                    pinMode(13, OUTPUT);
                                    digitalWrite(13, 1);
                                  }
                          //      }
                          //    }
                          //  }
                          }

                          I learned a few things and still have some questions. I will post this in the forum so it may help others.

                          1. Some of the syntax in the example code is wrong, especially for the default dashboard component powerswitch.

                              The following need to be changed:

                          • component needs to be changed to power
                          • command needs to be changed to LED.v1.0
                          • actuator needs to be changed to power
                          • light needs to be changed to LED.v1.0

                              This means the component on the Edison needs to be registered as “power” also, like this: iotkit-admin register power powerswitch.v1.02. The 4 nested IF statements are what was stopping the program from running past the aJsonObject parsing. In reviewing the code I added a series of printlns to debug where it was getting stuck. I determined that there are essentially 4 IFs: 2 are checking to see that the values received for control and command are not null and the other 2 are trying to be generic to scan any payload and match the conditions for component, command and arguments in the IF statement. It is trying to say:

                          • IF the payload component is not NULL and
                          • IF the payload component value is “power” then
                          • IF the payload command value is “LED.V1.0” and
                          • IF the payload command value is not null and
                          • IF the payload argv value is “0”…
                          • THEN turn the LED off

                          or

                          • IF the payload command value is “LED.V1.0” and
                          • IF the payload command value is not null and
                          • IF the payload argv value is “0”…
                          • THEN turn the LED on

                          The problem is this is a large combination of conditions in a series of nested IF statements and for whatever reason(s) the conditions don’t get met by the default dashboard payload so it does not execute.

                          In short, the logic just doesn’t work!

                          3. I did get it working, however the LED switches the wrong way! Note that in my code I had to change the bolded 0 in the code below to reverse it:

                                  if (strcmp(value->valuestring, " 0 ")) {
                                    Serial.println("Light on!");
                                    pinMode(13, OUTPUT);
                                    digitalWrite(13, 1);

                          Now, I did make a lot of changes in the IF statements and perhaps something is amiss.

                          So! My question is:

                          Can anyone post some sample code (actually ideally working code, not just sample code…) to replace the conditions in the example’s nested IF statements? The conditions are needed for a production application; the way it is I can only control one component at a time.

                          David

                          • 10. Re: IoT dashboard Control/Actuator working code or tutorial?
                            ForumMigrationAdmin

                            Citation :

                            David B. a écrit :

                             

                            [...]

                            First - the iotkit version on the Edison was too old. I downloaded and flashed the latest Edison image (ww36-14) on Monday but evidently they include a very old iotkit in that dist (1.5.0).

                            [...]

                             

                             

                            The latest Edison image should be ww42 I'd say. Nevertheless, the iotkit-agent there would still be fairly old - on my image it tells 0.8.7. Looks like I should upgrade iotkit-agent some time ...

                            • 11. Re: IoT dashboard Control/Actuator working code or tutorial?
                              ForumMigrationAdmin

                              Hi Mathias - yes, you are correct. Sorry, I made a typo. The version I downloaded was:

                              Rel-1-Maint-WW42

                              From here:

                              https://communities.intel.com/docs/DOC-23242

                              Thanks, and yes, it looks like you should update it!

                              David

                              • 12. Re: IoT dashboard Control/Actuator working code or tutorial?
                                ForumMigrationAdmin

                                Great to hear. Yes, I think the main issue was the parameter name, “light”. I should have had you verify you had the latest sample code:

                                https://github.com/enableiot/iotkit-samples/blob/master/arduino/IoTkit/examples/IoTKitActuationExample/IotKitActuationExample.ino

                                This latest version has cleaner logic but could still be improved. The if/then logic is to verify that a received actuation message is actually for the component you are about to turn on/off. After parsing this message, the only things you really care about are:

                                component
                                argv: name
                                argv: value

                                Command really isn’t important. It’s an arbitrary string that is a property of the component’s type (i.e., powerswitch.v1.0).

                                The reason argv is an array is that a component-type can have several parameters. For example, you could have a motor which has multiple parameters:

                                onOff: 0/1 (or speed=0 could be 'off')
                                speed: 0-100 
                                direction: 0/1

                                Then, the sketch would extract all of these parameters from the message and if all values were present, set the appropriate pins.

                                Brian

                                • 13. Re: IoT dashboard Control/Actuator working code or tutorial?
                                  ForumMigrationAdmin

                                  Guys,

                                  I also can't get this thing running, I flashed clean my edison and updated iotkit to 1.6.4

                                  I cannot switch it to mqtt:

                                  iotkit-admin protocol mqtt

                                  fs.js:427
                                    return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                                                   ^
                                  Error: ENOENT, no such file or directory '/home/root/data/user.js'
                                      at Object.fs.openSync (fs.js:427:18)
                                      at Object.fs.readFileSync (fs.js:284:15)
                                      at Object.module.exports.saveToUserConfig (/usr/lib/node_modules/iotkit-agent/lib/common.js:236:23)
                                      at Command.<anonymous> (/usr/lib/node_modules/iotkit-agent/admin/configurator.js:225:28)
                                      at Command.<anonymous> (/usr/lib/node_modules/iotkit-agent/lib/commander/index.js:253:8)
                                      at Command.EventEmitter.emit (events.js:98:17)
                                      at Command.parseArgs (/usr/lib/node_modules/iotkit-agent/lib/commander/index.js:482:12)
                                      at Command.parse (/usr/lib/node_modules/iotkit-agent/lib/commander/index.js:374:21)
                                      at Object.<anonymous> (/usr/lib/node_modules/iotkit-agent/bin/admin.js:91:11)
                                      at Module._compile (module.js:456:26)

                                  Please help!

                                  • 14. Re: IoT dashboard Control/Actuator working code or tutorial?
                                    ForumMigrationAdmin

                                    Hi Jakub.

                                    That looks like a bug in the agent but I need to verify. There are a couple of work-arounds.

                                    1. You can move to the /usr/lib/node_modules/iotkit-agent and run the command.

                                    2. Move the agent data directory to some non-default location. This is recommended in the update/install instructions as updating the agent will wipe out everything.
                                    # iotkit-admin move-data-directory ~/.data
                                    Then try setting MQTT protocol
                                    # iotkit-admin protocol mqtt

                                    Brian

                                    1 2 Previous Next