Testing SW from Espruino book

Posted on
  • Hello,
    I'm trying some code from page 246 (Espruino Pico+ESP8266):

    // Test ESP8266
    var WIFI_NAME = "MYSSID";
    var WIFI_KEY =  "WIFIPWD";
    var wifi;
    var json;
    
    var homepage = '<html><body>'+
    '<h1>My Espruino</h1>'+
    '<a href="/getTemp">Temperature</a></br>'+
    '<form action="/?led=0" method="post">'+
    '<input type="submit" value="LEDS OFF"/></form>'+
    '<form action="/?led=1" method="post">'+
    '<input type="submit" value="LED RED ON"/></form>'+
    '<form action="/?led=2" method="post">'+
    '<input type="submit" value="LED GREEN ON"/></form>'+
    '<form action="/?led=3" method="post">'+
    '<input type="submit" value="LED RED+GREEN ON"/>d</form>'+
    '</body></html>';
    
    
    function onInit() {
      USB.setConsole(true);
      Serial1.setup(115200, { tx:B6, rx: B7});
      wifi = require("ESP8266WiFi_0v25").connect(Serial1, function(err) {
        if(err) throw err;
        console.log("Connecting to WiFi");
        wifi.connect(WIFI_NAME, WIFI_KEY, function(err) {
          if(err) {
            console.log("Connection error: "+err);
            return;
          }
          onConnected();
        });
      });
    }
    
    function onConnected() {
      console.log("Connected");
      require("http").createServer(onPageRequest).listen(80);
      wifi.getIP(function(err,ip){
        console.log("Your IP address is http://" + ip);
      });
    }
    
    function onPageRequest(req, res) {
      console.log("Serving " + req.url);
      var r = url.parse(req.url, true);
      if (r.pathname == "/") {
        // controllo passaggio parametri
        if (r.method == "POST" && r.query && r.query.led)
          digitalWrite([LED2,LED1], r.query.led);
        console.log(r.method);
        // Onora la richiesta della pagina
        res.writeHead(200, {"Content-Type!": "text/html"});
        res.end(homepage);
      } else if (r.pathname == "/getTemp"){
        res.writeHead(200, {"Content-Type!": "text/html"});
        res.end('<html><head>'+
                '<meta http-equiv="refresh" content="2">'+
                '</head><body>'+E.getTemperature().toFixed(2)+
                '</body></html>');
      } else {
        res.writeHead(404);
        res.end("404 - Not Found");
      }
    }
    

    Unfortunately it doesn't work as it 'see' only GET as a method, not the POST, sorry for my english and my worst HTML knowledge ;-)

  • Did you paste the code into the editor (right hand pane in Espruino Web IDE) and upload it to the board?
    What board are you using?

    It should work, because it responds to the form post...

    The "led" field parameter is either 0, 1, 2 or 3. Line 51 writes the bits of the value to both LEDs. if value 0 = 0b00 comes, it writes 0 to both LEDs, if value 2 = 0b10 comes, green LED turns on and red LED turns off. You can validate this by entering into the console (left hand pane in Espruino Web IDE): digitalWrite([LED2,LED1], 2);

    If you just upload the code, nothing is starting it... Espruino interprets the code and establishes just variables and functions. Therefore type into the console:

    onInit();```
    

    To make life easier while you develop and experiment with variations of the code, add as lasts lines to the code:

    // remove this and next line line before saving code to flash
    setTimeout(onInit,1000);
    
  • Yes, i'm uploading via the code editor panel, after uploading it i write to the console the onInit(); command and it does connect and show me the IP, the "GET" version of this code does work without problems but NOT the "POST" one.

    This code:

        if (r.method == "POST" && r.query && r.query.led)
          digitalWrite([LED2,LED1], r.query.led);
        console.log(r.method);
    

    Line 1 (if ) never exeute the digitlWrite since it find always "GET" as the method and never the "POST"
    line 3 ALWAYS return "GET" not "POST" .
    maybe it is because of i'm loading this server in local ?

    Thanks !

  • ...Ic

    And you may have just found some interesting thing, may be an issue in the .parse(...).

    I did some deep digging in the example, because it fooled me nicely...

    Below my 'console talkative', working code. The main changes and detections are:

    • I made the method in the form submit a upper-case post... that solves the problem of asking the request req variable for the method before gong after the parsed request, which is called r. (Side note: I find it odd - to say the least - that lower-case url is a global that comes into play without definition... @Gordon?). But making that change still did not work, so I wanted to know and added all this console outputs, also did some renaming: upd - Url ParseD - for r... and - when 'consoling' that .parse(... return object, I got 'consoled' by the detection of the issue that, even though the request says it is a POST, the parsed url or request or what it is claims the request.POST as a GET. - See console output after the code...

    • I run it on a Espruino-WiFi... so some lines got commented and a few got added to take care of that...

      // bp246WifiESP8266.js
      // Test ESP8266 / Test Espruino-Wifi (book p. 246)
      var WIFI_NAME = "MYSSID";
      var WIFI_KEY =  "WIFIPWD";
      WIFI_NAME="ssid"; WIFI_KEY ="pw";
      var wifi;
      var json;
      var homepage = '<html><body>'+
      '<h1>My Espruino</h1>'+
      '<a href="/getTemp">Temperature</a></br></br>'+
      '<form action="/?led=0" method="POST">'+
      '<input type="submit" value="LEDS OFF"/></form>'+
      '<form action="/?led=1" method="POST">'+
      '<input type="submit" value="LED RED ON"/></form>'+
      '<form action="/?led=2" method="POST">'+
      '<input type="submit" value="LED GREEN ON"/></form>'+
      '<form action="/?led=3" method="POST">'+
      '<input type="submit" value="LED RED+GREEN ON"/></form>'+
      '</body></html>';
      function onInit() {
      USB.setConsole(true);
      //   Serial1.setup(115200, { tx:B6, rx: B7});
      //   wifi = require("ESP8266WiFi_0v25").connect(Serial1, 
      // function(err) {
      //    if(err) throw err;
      //    wifi.connect(WIFI_NAME, WIFI_KEY, function(err) {
      var WIFI_OPTIONS = { password: WIFI_KEY };
      wifi = require("EspruinoWiFi");
      console.log("Connecting to WiFi...");
      //    wifi.connect(WIFI_NAME, WIFI_KEY, function(err) {
      wifi.connect(WIFI_NAME, WIFI_OPTIONS, function(err) {
        if(err) {
          console.log("Connection error: "+err);
          return;
        }
        onConnected();
      });
      //  });
      }
      function onConnected() {
      console.log("Connected");
      require("http").createServer(onPageRequest).listen(80);
      //   wifi.getIP(function(err,ip){
      //     console.log("Your IP address is http://" + ip);
      wifi.getIP(function(err,ipInfo){
      console.log("ip info: " + JSON.stringify(ipInfo));
      });
      }
      function onPageRequest(req, res) {
      console.log(" 1) Serving:         " + req.url);
      console.log(" 2) method:          " + req.method);
      console.log(" 3) method:          " + JSON.stringify(req.method));
      console.log(" 4) typeof method:   " + (typeof req.method));
      var upd = url.parse(req.url, true);
      console.log(" 5) upd (url parsed:");
        console.log(upd);
      console.log(" 6) query:           " + JSON.stringify(upd.query));
      console.log(" 7) upd.query b:     " + ((upd.query) ? "true" : "false"));
      if (upd.query) {
      console.log(" 8) upd.query.led b: " + ((upd.query.led) ? "true" : "false"));
      }
      console.log(' 9) (req.method == "POST"): ');
      console.log("      " + ((req.method == "POST") ? "true" : "false"));
      console.log('10) (req.method === "POST"): ');
      console.log("      " + ((req.method == "POST") ? "true" : "false"));
      console.log('11) (req.method === "POST" && upd.query && upd.query.led): ');
      console.log("      "  + ((req.method == "POST" && upd.query && upd.query.led) ? "true" : "false"));
      if (upd.pathname == "/") {
      // controllo passaggio parametri
      if (req.method == "POST" && upd.query && upd.query.led) {
      //       digitalWrite([LED2,LED1], r.query.led);
        digitalWrite([LED2,LED1], upd.query.led);
      //      digitalWrite([LED2,LED1], parseInt(upd.query.led));
      }      
      // Onora la richiesta della pagina
      res.writeHead(200, {"Content-Type!": "text/html"});
      res.end(homepage);
      } else if (upd.pathname == "/getTemp"){
      res.writeHead(200, {"Content-Type!": "text/html"});
      res.end('<html><head>'+
              '<meta http-equiv="refresh" content="2">'+
              '</head><body>'+E.getTemperature().toFixed(2)+
              '</body></html>');
      } else {
      res.writeHead(404);
      res.end("404 - Not Found");
      }
      }
      
      // remove this and next line line before saving code to flash
      setTimeout(onInit,1000);
      

    In the next post is the 'chatty' console output, that shows that...

  • Here is the 'chatty' console output, that shows that the method in parsed request / url / or what ever is a "GET" (line 18) and NOT a "POST" as in req.method (line 13..15).... Lines 13..15 were 'progressively' figuring out of req.method returns really must the method as trimmed and as string... (because the logical expression - in original, first post's code line 50 and in my code 66 - just never made it to true).

     _____                 _
    |   __|___ ___ ___ _ _|_|___ ___
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v94 Copyright 2016 G.Williams
    >
    =undefined
    Connecting to WiFi...
    Connected
    ip info: {"ip":"192.168.0.101","mac":"5c:cf:7f:c0:10:63"}
     1) Serving:         /?led=2
     2) method:          POST
     3) method:          "POST"
     4) typeof method:   string
     5) upd (url parsed:
    {
      "method": "GET",
      "host": "",
      "path": "/?led=2",
      "pathname": "/",
      "search": "?led=2",
      "port": null,
      "query": {
        "led": "2"
       }
     }
     6) query:           {"led":"2"}
     7) upd.query b:     true
     8) upd.query.led b: true
     9) (req.method == "POST"):
          true
    10) (req.method === "POST"):
          true
    11) (req.method === "POST" && upd.query && upd.query.led):
          true
     1) Serving:         /getTemp
     2) method:          GET
     3) method:          "GET"
     4) typeof method:   string
     5) upd (url parsed:
    {
      "method": "GET",
      "host": "",
      "path": "/getTemp",
      "pathname": "/getTemp",
      "search": null, "port": null, "query": null }
     6) query:           null
     7) upd.query b:     false
     9) (req.method == "POST"):
          false
    10) (req.method === "POST"):
          false
    

    Another point (about the code in previous post - lines 71..73) I would like to make is:

    The statement (line 72)

          digitalWrite([LED2,LED1], upd.query.led);
    

    gets lucky just because of the fact that the characters 0, 1, 2 have the same two least significant bits in combination on and of as the integer values 0,1,2,3. With a different coding that ASCII, this fails, and even with ASCII* encoding, it fails for more than 4 output lines / LED's in the array. Therefore (line 73),

          digitalWrite([LED2,LED1], parseInt(upd.query.led));
    

    makes it clear, and works up to 31 output lines LEDs... again, a comment, such as: // "0..3..9" have same bits on in LNIB as 0..3..9 saves everyone's day - LNIB being Least significant NIBble (half-byte).

  • I think your issue might just be how you copied the example code? In your code you have:

    if (r.method == "POST" && r.query && r.query.led)
    

    But the actual code is:

    if (req.method=="POST" && r.query && r.query.led)
    

    I think it'll work fine for you if you do that? Unfortuntely with these big bits of code it's hard to copy everything out without errors. If it's some help, I made the original code available online at https://github.com/espruino/making-things-smart - specifically I think https://github.com/espruino/making-things-smart/blob/master/experiment32.js is what you're after?

  • ...in deed, that's how I got it working..., *BUT*, there seems to be an error in url.parse(): no matter what the method is - even if it is proven POST - the parsed object says for method: "GET".

  • var r = url.parse(req.url, true);

    As req.url is passed to url.parse, and not just req there is no way of determining the url.method.

  • @Wilberforce, ooops... see THE point... then may be the url.parse(req,...) would be the right approach? I see no reason why not...

    As mentioned earlier, it is anyway funny that lower-case url is a global...

  • global url? I'm not sure I follow... Sorry, I may have scanned through what you wrote a bit too quick.

  • Regarding the url symbol / variable: how come that it is available in (scope of) callback function function onPageRequest(req, res) {...} for url.parse(...) without any declaration?

  • It's available because it's built-in. I know it seems odd, but it's global in node.js, so that's what I do here for compatibility.

  • Ic. ...and understand, because I'm more a client-side/browser then a a/vi-vid node.js JavaScript user.

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

Testing SW from Espruino book

Posted by Avatar for L0cutus @L0cutus

Actions