Agent code is web page?

In some IMP examples, I see HTML code inside the agent code. My question: can the agent also serve as a web page? Why would you want to do that? What parts of the agent code does the user see when viewing the HTML source?

The agent allows you to create a simple web server… this was originally intended to allow people to build HTTP APIs for their devices, which is great.

Developers, being the clever people they are, quickly realized that if you have a web server, you can serve up webpages! Very cool.

The user won’t really see any parts of the agent code when they’re viewing the HTML. Here’s what’s actually going on:

  1. Create a string with some HTML in it
  2. Make your http.onrequest return that HTML
  3. Browse to the webpage (agent url)

When they view source - the only ‘code’ they will see is the string that you have returned. Here’s a really simple example:

`const HTML = “I’m an Agent!

Hello World

This webpage is being served from an agent

”;

http.onrequest(function(req, resp) {
resp.send(200, HTML);
});`

For a quick and convenient tryout, for my application UI, I’m also serving a HTML page from the agent and have got as far as receiving button presses in my agent code (using the POST method lifted from the snackbot example). However, I would also like to dynamically update certain text fields on the web page. I guess I could keep redefining the entire HTML text string but it would be nicer to have some “upwards communication” with the content being served. Any clues as to how this might be done?

@iceled - You want to look into something called AJAX - which is a javascript technique in which you make an asynchronous web request, and only reload a portion of the page…

We’ve been mentioning that we’re going to be doing a blog post about AJAX soon, but it hasn’t happened quite yet.

Great - I will look forward to that blog post! However, in the meantime, I’m trying to understand this w3 schools example which is not making much sense so far - the source code doesn’t even contain the alternate content string so it’s all a bit confusing.

jQuery makes ajax (and javascript in general) a lot easier… take a look at this example:

http://www.w3schools.com/jquery/tryit.asp?filename=tryjquery_ajax_load

When you click the button, the javascript fetches a file (i.e. makes a web request) and puts the response of that web request into a specific div / element of the webpage.

OK, a bit more understandable - thanks! But the .load() method only accepts a URL for the data to be implanted so I don’t see how the agent code can provide this from the server its running on.

As an experiment, if I put in a URL to a .txt file on my own server (instead of the “demo_test.txt” ) it doesn’t show up - the jQuery api doc. doesn’t make it clear if there are limitations to the URL just saying

This method is the simplest way to fetch data from the server.
er, which server?

There’s a couple limitations with jQuery - typically you need to make a request to a resource (URL) on the same server as the webpage… but we can get around that using an “Access-Control-Allow-Origin” header. Try this as an experiment:

Replace:
$("#div1").load("demo_test.txt");

With:
$("#div1").load("https://agent.electricimp.com/YOUR_AGENT_URL");

And create the following http handler in your agent code:

`http.onrequest(function(req, resp) {
// Add the Access-Control-Allow-Origin header
resp.header(“Access-Control-Allow-Origin”, “*”);

// Return some data
resp.send(200, "I loaded this text from an Electric Imp Agent!");

});`

Now when you click the button it should load the text “I loaded this text from an Electric Imp Agent” into the div.

OK thanks, that works. So the jQuery example you linked to can obtain content from the Imp agent if the agent wildcards Access-Control-Allow-Origin in the header of its return data. Seems strange that access control is managed from the supply end rather than the demand end but it works.

However, if the entire webpage being sent as a text string from the agent (in response to http.onrequest) is itself making load requests to the same agent URL it would seem to run the risk of being somewhat recursive. Makes me wonder how scared we should we be of breaking things :">

The trick here is to use things like the requests path, query parameters, body, etc

So you might code your agent to serve up a simple webpage when you browse to the agent url, and then your webpage might autoupdate a temperature field with ajax every 30 seconds by making a request to {agentUrl}/temp:

http.onrequest(function(req, resp) { local path = req.path.tolower(); if(req.path == "/") { // if they went to the index, return the HTML page resp.send(200, HTML); return; } else if (path == "/temp" || path == "/temp/") { // if they asked for the temp, return the temperature resp.send(200, temp); return; } else { // if they sent us an unexpected path, return a 404 resp.send(404, "Unknown"); } });

Great, yes, I can see quite a few ways of getting the appropriate data now.

I see I’ve sent this thread a bit off-topic so I’d like to steer it back with a much more relevant question: is the serving of a control panel webpage for an Imp directly from its agent a valid way to implement an impee for volume use? In other words is there any technical or business reason why this would not scale to a commercial application solution? I guess the exposed URL for the device is a bit of an issue for starters.

This isn’t really something we recommend for scale. While technically possible, you’re likely going to want to be hosting your interface somewhere else. You can’t host static files in the agent (css, js, etc) which means you need ALL of your HTML, CS, and JS in a single page, which can be difficult to manage.

It’s a great way to quickly build out a proof of concept, or a one off device without requiring any extra servers / services.

OK, sure, but I wonder why it’s not been made possible to host such resources in order to provide a more complete solution and add value to the EI proposition overall? I would imagine that a “one-stop-shop” for all dependencies would make for a more robust system as well.

ya, but electric imp also is told by others that they do not like an apparently closed ecosystem and that they prefer to control their own servers. There are many opinions out there.

I like putting a single html page on my own cheap hosted space but I have also used the agent-served pages. One time in a pinch (when Hostgator was down), I was able to grab the web page and program it into the agent in about 10 minutes so I could keep operating… whew! It helped that my page was already designed to work this way.

here is an example of part of my html header in which jquery mobile and highcharts are referenced from external sources. This will work whether an agent puts out the web page or your own space does (I am in the USA).

`

`

There is also a way to host the favicon from an external source.

The bummer part of this is that editing html and javascript inside of the imp IDE is not very nice. I don’t edit code that way very often.

@iceled - hosting static files is something we’ve discussed and are considering as a possible future feature.

I encourage you to checkout Firebase. Firebase is a hosted realtime database as a service, but also includes some other powerful features such as hosting static files, user management and authorization rules, etc.

We have found that Firebase + Electric Imp is a very powerful combo (and there is a good/free developer plan with Firebase!)

Would the code segment below be legal in the agent in enclosed within script tags?

" window.open(‘http://www.abc.com’), ‘_blank’, ‘toolbar=no, scrollbars=yes, resizable=yes, top=500, left=500, width=400, height=400’);"

The agent itself is not a webpage.

You could embed that in a script tag inside html served up by the agent.