0

Connecting to Adafruit IO with Paho Javascript client
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Connecting to Adafruit IO with Paho Javascript client

by k00kykelly on Fri Dec 04, 2015 3:24 am

I'm trying to get a Paho Javascript websockets client to talk to the Adafruit IO brok3r. My code is running on http://kellyandjeremiah.com/lights/ and also included below.
I get an alert: Connection failed: AMQJSC0001E Connect timed out.
Plus an error in the console: Firefox can't establish a connection to the server at ws://io.adafruit.com:1883/mqtt.

The server is up because my Arduino + CC3000 client receives stuff from the dashboard.

I assume AMQJSC0001E is the client ID. It looks like it is set to "web" + Date.now().toString(). According to https://learn.adafruit.com/adafruit-io/mqtt-api it needs to be a unique value like a random guid. So, probably ok?

Maybe the username or password aren't specified in the right spot?

Also, any tips on how to hide my Adafruit IO key (or at least make it less obvious) would be appreciated.

Code: Select all | TOGGLE FULL SIZE
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="mqttws31.js"></script>
<script type="text/javascript" src="jquery-2.0.3.min.js"></script>
<script>
//modified from example at http://www.infoq.com/articles/practical-mqtt-with-paho
jQuery.ready()
alert(1);

var client = new Paho.MQTT.Client("io.adafruit.com", Number(1883), "web" + Date.now().toString());

// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;

//Variables to store light status
var status1 = 1;

//Options object for connection
var connect_options = {
    timeout: 3,
    onSuccess: function () {
        // Connection succeeded; subscribe to our topic
        console.log('Connected!');
        client.subscribe('k00kykelly/feeds/pin#', {qos: 1}); //originally QoS 0
    username: "k00kykelly";
     password: "7424389eb3f1fa52d5109700445dfb3d019591a9";       
    },
    onFailure: function (message) {
        alert("Connection failed: " + message.errorMessage);
    }
 
};

// connect the client
client.connect(connect_options);

// called when the client loses its connection
function onConnectionLost(responseObject) {
  if (responseObject.errorCode !== 0) {
    console.log("Connection Lost:"+responseObject.errorMessage);
  }
}

// called when a message arrives
function onMessageArrived(message) {
    console.log("Message Arrived:"+message.payloadString);
   alert('message arrived: ' + message.payloadString);
//    $("#temp_txt").html(message.payloadString);
   
    //Store the value
//    temp = parseFloat(message.payloadString);       
}

//Do this when button is clicked
function clicked(clicked_id) {
alert('pin ' + clicked_id);
    message = new Paho.MQTT.Message("1");
    alert(message);
    message.destinationName = ("k00kykelly/pin" + clicked_id);
    alert(2);
    client.send(message);   
    console.log('toggle light' + clicked_id);
    alert('Sending ' + status1 + 'to pin' + clicked_id);
}

</script>
</head>

<body>
<img src ="house4screen.jpg" width ="480" height ="285" alt="house" usemap="#housemap" />

<map name="housemap">
<area shape="circle" id="02" alt="tree" title="" coords="275,182,58" onclick="clicked(this.id)"/>
<area shape="poly" id="07" alt="left fence" title="" coords="1,189,0,212,44,207,43,186" onclick="clicked(this.id)"/>
<area shape="poly" id="13" alt="right fence" title="" coords="479,230,415,215,414,184,474,196" onclick="clicked(this.id)"/>
<area shape="poly" id="01" alt="right front" title="" coords="480,282,413,252,398,239,405,229,433,223,476,234" onclick="clicked(this.id)"/>
<!-- use href="#" if you want the cursor to change to the hand when you mouseover the links -->

</map>

k00kykelly
 
Posts: 7
Joined: Thu Feb 06, 2014 10:01 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by two9er on Fri Dec 04, 2015 8:19 am

Sorry can't help with your connection problem. As for your password being exposed, simply edit it to password: "<MyAIOkey>"; when you need to post it.

two9er
 
Posts: 4
Joined: Sun Jan 12, 2014 3:26 pm
Location: Leadville, CO

Re: Connecting to Adafruit IO with Paho Javascript client

by jwcooper on Fri Dec 04, 2015 1:00 pm

I haven't used the Paho Javascript client, but we have an example using mqtt over websockets with the mqtt.js client (https://github.com/mqttjs/MQTT.js) here: https://jsfiddle.net/4wwhu2o6/

jwcooper
 
Posts: 664
Joined: Tue May 01, 2012 9:08 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by k00kykelly on Fri Dec 04, 2015 3:43 pm

Nice! That's the kind of example I was looking for. I haven't found an example for Paho that includes authentication and I've probably just misunderstood how to get those options right from reading though their docs. I'm kind of learning as I go with JavaScript.

I'm not familiar with Node.js though...

1) I don't quite understand the browserify section. To run these commands is this just in a directory with the appropriate files or do I need to be running a Node.js webserver locally?

2) What is the difference between a stand alone module and a library?

3) Under the "Important notes for existing users" it talks about how the code was recently split into 3 parts. Is the client side portion all that is needed to work in a browser?

k00kykelly
 
Posts: 7
Joined: Thu Feb 06, 2014 10:01 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by k00kykelly on Fri Dec 04, 2015 3:51 pm

Actually it looks like I can download a version of the stand alone module from JSFiddle.

k00kykelly
 
Posts: 7
Joined: Thu Feb 06, 2014 10:01 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by nginear on Mon Jan 08, 2018 11:57 pm

jwcooper wrote:I haven't used the Paho Javascript client, but we have an example using mqtt over websockets with the mqtt.js client (https://github.com/mqttjs/MQTT.js) here: https://jsfiddle.net/4wwhu2o6/


I've used your example to get up and running with Adafruit IO and javascript. It works as expected, except upon connecting and subscribing I don't get the retained or last message on the feed. I only get messages after the feed has changed, and then every time after that. I would like my web client to know what the current state is. Is this a limitation of Adafruit IO, or maybe MQTT.js? Or is the javascript code in your example just not sufficient to push the message into the html?

nginear
 
Posts: 4
Joined: Wed Feb 24, 2016 3:01 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by abachman on Tue Jan 09, 2018 12:53 pm

hi nginear,


We do not currently support the MQTT retain flag for subscriptions / last value messages. We do have a couple HTTP APIs that can help, though: https://io.adafruit.com/api/docs/#!/Data/lastData and https://io.adafruit.com/api/docs/#!/Data/retainData.

If you call the .csv version of that URL with an `include` parameter value of "value", you can get just the value for the most recent data in the feed. From the command line, with the curl command, that would look like:
Code: Select all | TOGGLE FULL SIZE
$ curl -H "X-AIO-Key: $IO_KEY" https://io.adafruit.com/api/v2/$IO_USER/feeds/$FEED_KEY/data/last.csv?include=value
value
31.90914238063747


Alternatively, .../data/retain will return the last data in a CSV format that mimics the output of our MQTT csv topics. For a value with no location data, that looks like:
Code: Select all | TOGGLE FULL SIZE
$ curl -H "X-AIO-Key: $IO_KEY" https://io.adafruit.com/api/v2/$IO_USER/feeds/$FEED_KEY/data/retain
31.90914238063747,,,

---

It's possible we'll be able to support the retain flag in the future since it's a very useful part of the MQTT specification, but it's not on our radar at this time.


- adam

abachman
 
Posts: 229
Joined: Mon Feb 01, 2010 12:48 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by nginear on Tue Jan 09, 2018 2:03 pm

Thanks Adam,

The API calls might help temporarily (for demonstration) for my browser needs.

But even beyond the browser, any new wifi connected device that subscribes to the feed could really benefit from having the last message sent immediately upon a successful subscribe, which is how I understand the MQTT specification should work.

There has been a discussion on this topic since early 2016 over here... https://github.com/adafruit/Adafruit_MQ ... /issues/20. I realize this is a different library, and maybe I should be using that instead, but it seemed like they were really close to implementing the feature there.

nginear
 
Posts: 4
Joined: Wed Feb 24, 2016 3:01 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by abachman on Tue Jan 09, 2018 2:21 pm

There has been a discussion on this topic since early 2016 over here... https://github.com/adafruit/Adafruit_MQ ... /issues/20. I realize this is a different library, and maybe I should be using that instead, but it seemed like they were really close to implementing the feature there.


It's related, the Adafruit MQTT library is what the Adafruit IO Arduino library uses under the hood. It's a broker issue, in our case, though.

We used to support the retain flag, but it caused a huge performance overhead on our MQTT broker and backend messaging system. Like I said, it's possible (and even likely) that we'll introduce it to IO in the future, but it's not in our plans right now.

It's not an excuse, but you can see even very large IoT service providers like Amazon don't support it:
The MQTT specification provides a provision for the publisher to request that the broker retain the last message sent to a topic and send it to all future topic subscribers. AWS IoT does not support retained messages. If a request is made to retain messages, the connection is disconnected.

https://docs.aws.amazon.com/iot/latest/developerguide/protocols.html


- adam

abachman
 
Posts: 229
Joined: Mon Feb 01, 2010 12:48 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by nginear on Tue Jan 09, 2018 2:47 pm

Thanks for the helpful reply. I have the brower api call working to pull the last value. It's not pretty or secure, but for demonstration purposes it works.

nginear
 
Posts: 4
Joined: Wed Feb 24, 2016 3:01 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by abachman on Tue Jan 09, 2018 3:26 pm

It's not pretty or secure, but for demonstration purposes it works.


Secure? I may not be understanding correctly.

The .../data/retain URL will work with any programming environment or language that can make HTTP requests, a browser is not necessary. It's at least as secure as the MQTT interface since both rely on the same API Key (on your end) and same SSL certificate (on our end). Here's a demo sketch that grabs the most recent value for a feed every 10 seconds as an example: https://gist.github.com/abachman/4cf13359f6a9cd0ff4340edb03b48948 It should work for the Feather M0 ATWINC1500 or the Huzzah (ESP8266) boards, those were the two I had handy.

Definitely do not include your IO API Key in any code or app you are distributing publicly, that would be insecure for sure.


- adam

abachman
 
Posts: 229
Joined: Mon Feb 01, 2010 12:48 pm

Re: Connecting to Adafruit IO with Paho Javascript client

by nginear on Tue Jan 09, 2018 4:18 pm

Yeah, I'm building in the browser which is why I posted in this Javascript client forum. I am just building a functionality demo, so security isn't too big of a concern.

I have no concern about the security of device api calls or interfaces with Adafruit IO. And I do see how your example sketch would enable the device to access the last message value. Sorry we weren't on the same page.

nginear
 
Posts: 4
Joined: Wed Feb 24, 2016 3:01 pm

Please be positive and constructive with your questions and comments.