Help with restful like interface

Posted on
  • Hello,

    I currently have a pico running my heating through a few 5V relays. It is not quite as simple as a thermostat; It heats a store of water and uses a pump to provide hot water and heating. I would like to be able to connect to the system over wifi, gather the data and adjust variables. I may install home-assistant so I would like to emulate a rest type interface. I am testing the wifi on a ESP8266 at the moment until I buy a shim.

    I have played with examples previously with control over wifi, I can turn on a pin and read variables but I don’t understand how to interrogate the url and move the information into a variable. I thought of using an if statement to check if the number is 1 and incrementing to by 1 if it’s not and rechecking but it seems a bit adhoc.

    I would like to be able to type something like:

    "192.168.0.13/set/room/23"

    and have the 23 move to the variable for the target room temperature. I assume I would need to use the parse function? A simple example of how to achieve this would be very much appreciated.

    Basic example that I have been using:

    // define the function beServer
    function beServer() { 
      var http = require ("http");
      var httpServer = http.createServer(function(request, response) {
        print(request);
    
        //Handle favicon requests
        if (request.url == "/favicon.ico") {
          response.writeHead(404);
          response.end();
          return;
        }
    // handle requests and serve web page
        response.write("<html><body>");
        if (request.url == "/ledOn"){
          response.write("The led is on.");
          digitalWrite(ledPin, 1);
        } else if (request.url == "/ledOff"){
          response.write("The led is off");
          digitalWrite(ledPin, 0);
        } else {
          response.write("Sorry... I didn't understand");
        }
        response.end(" ");
      }); // End of new browser request
    
      httpServer.listen(80);
      print("Now being an HTTP server!");
    } // End of beServer
    
    

    Background information about the actual system:
    A thermometer switches the boiler when the store cools below a pre-set limit currently cutting in at 62 and out at 72 deg. A valve lets water from the heating circuit into the cylinder when the flow is above 45 deg and within 10 deg of the cylinder temp and the boiler is running. The water pump starts (and pumps water through a heat exchanger) when a flowmeter picks up a flow higher than 1l/min. so lots for thermometers basically.

  • url.parse() will give you all the information about request path and request querystring arguments so you can do all your routing in one handler. If you are making some form of UI to control this, you might also consider using AJAX so your control panel UI is not disappearing at each adjustment. There are a couple of examples on the espruino.com site.

    [Edit]

    This is one, check out the onPageRequest handler examples is the server/pages section, where all path and querystring vars are parsed in one function:-
    http://www.espruino.com/Internet

    And this one, which covers interactive UI, and makes ajax requests in background:-
    http://www.espruino.com/Interactive+Web+­UI

  • Thanks, I had looked at the examples and have used it previously, clearly I needed to sleep on it but I think I get it now.

    I could type:

    192.168.0.13/set?23

    function onPageRequest(req, res) {
      var a = url.parse(req.url, true);
      if (a.pathname=="/set") {
    targetRoomTemp= a.query
    }
    

    to change the varible 'targetRoomTemp' to 23?

    Or with 192.168.0.13/set/23

    function onPageRequest(req, res) {
      var a = url.parse(req.url, true);
      'a.pathname'.split('/')==[1,2,3];
    
      if (a.pathname(2)=="/set") {
    targetRoomTemp= a.pathname(3);
    }
    
  • Re the first example you'd want a key in the querystring something like ?temp=23

    You'd then be able to access as a.query["temp"].

    In your second I can see what you want to do but syntax not quite right. You'd split to a new variable for one thing.

    Happy to give you the right code later - on a mobile currently- but this may help you

    http://www.w3schools.com/jsref/jsref_spl­it.asp

  • Here you go. This is your path routing example.

    var wifi = require("Wifi");
    
    // All routing in here
    function router(req ,res){
      var a = url.parse(req.url, true);
      res.writeHead(200,{'Content-Type': 'text/plain'});
      p = a.path.split("/");
    
      // Test for path formatted to set the temp
      if (p.length == 3 && p[1] == "set") {
        var temp = parseFloat(p[2]);
        res.write("The temp sent to the server was " + temp + "C");
      } else {
        res.write("The request was not formatted to set the temp");
      }
      res.end("");
    }
    
    // When connected create webserver
    function createServer(){
      var port = 8080;
      require("http").createServer(router).lis­ten(port);
      console.log("Listening on " + wifi.getIP().ip + ":" + port);
    }
    
    // Connect to Wifi
    wifi.stopAP();
    wifi.connect("xxxx", {"password":"xxxx"}, createServer);
    
    
  • That's great thank you. I will have a play so I understand better but I have it working!

  • Take a look at apigee blog about design for getting some ideas how to handle the different aspects of identifying a resource - directly/by relationship navigation (in path) or by query (in parms) - and do an operation on them... providing and receiving data. Latter most likely makes you also have a body - url is not sufficient (and verbs and parameters are not exactly the restful way to do it).

    But if you want everything in the url, you will compromise... ;)

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Help with restful like interface

Posted by Avatar for AaronB @AaronB

Actions