wifi.setHostname, or setIp on Espy WIFI

Posted on
  • Hi guys--

    I'm writing an application to control an analog tape recorder (Otari MTR-90 MK2, if you're curious.). We created a successful alpha with Arduino UNO and some complex add-on shields, and it's basically working, but we think Espruino Wifi can we do everything we need, and keep it all happily in the land of JS. Plus it's way smaller.

    However, we will need to set a hostname, or at the very least an ip address. The Espy will be mounted to the machine and derive power from a voltage regulator fed by the machine-- so basically, it'll boot up when the machine is powered on. There's no direct feedback to the user. I can get a little hello world going, but I can't get the DNS to set.

    This is working code, below. Any attempt at setHostname or setIp causes various failures. I'm on firmware 2v05.

    THANKS!

    const wifi = require("Wifi");
    const ws = require("ws");
    
    const WIFI_NAME = "MeowNetJr";
    const WIFI_OPTIONS = { password : "cookiejr" };
    const connectToWifi = () => {
    	wifi.connect(WIFI_NAME, WIFI_OPTIONS, (err)  => {
    		if (err) {
    		  console.log("Connection error: " + err);
    		  return;
    		} else {
    			console.log("Wifi Connected!");
    
                //wifi.setHostname("my-espy");
                //wifi.save();
    			
                wifi.getIP((err, info) => {
    
    				if (info && info.ip) {
    					console.log("IP Address: " + info.ip );
                        startServer();
    
                       
    				}
    			});
    		}
    	});
    };
    
    var page = '<html><body><script>var ws;setTimeout(function(){';
    page += 'const ws = new WebSocket("ws://" + location.host);';
    page += 'ws.onmessage = function (event) { console.log("MSG:"+event.data); };';
    page += 'setTimeout(function() { ws.send("Hello to Espruino!"); }, 1000);';
    page += '</script><p>something</p></body></html>­';
    
    const onHttpRequest = (request, response) => {
        console.log("Processing request");
        response.writeHead(200, { 'Content-Type': 'text/html' });
        response.end(page);
    };
    
    const startServer = () => {
        console.log("Starting Server");
        ws
            .createServer(onHttpRequest)
            .listen(80)
            .on("websocket", (socket) => {
                console.log("websocket connection");
                socket.on("message", (msg) => {
                    console.log("websocket message: " + msg);
                    socket.send("pong");
                })
            });
    
    };
    
    function onInit() {
    	connectToWifi();
    }
    onInit();
    
    
  • If it's not clear, the user turns on the tape recorder, Espy boots, they go to a local domain or IP they know, and we have a front end JS app served from there. That JS app essentially controls the output pins of the Espy which control the tape recorder.

  • That looks great! If it helps, you can use a templated string for the HTML...

    var page =`<html><body><script>var ws;setTimeout(function(){
    ...
    </script><p>something</p></body></html>`­;
    

    Which makes things tidier.

    Setting a DNS name is much harder I'm afraid. It is possible to update the ESP8266 (wifi module) firmware to enable this, but out of the box it isn't supported. setHostname is just the WiFi access point name.

    The easiest thing you can do is to set the IP address. You should be able to replace the wifi.getIP line with:

    var info = {ip:"192.168.1.9"};
    wifi.setIP(info, (err) => {
    })
    

    And then you'll always have the ESP8266 at a set IP address.

  • If you're interested, info on enabling MDNS with new WiFi firmwares is in: http://forum.espruino.com/conversations/­293972/#14954189

  • Actually stand by. I want to make sure I am doing this right.

  • I'm on firmware 2v05 I believe-- I updated yesterday in fact.

  • Okay Gordon, I'm really not getting it. Here is the Github for what we got goin:

    https://github.com/giokincade/autolocato­rjs.git

    The current file I am deploying is mw-test.js. The relevant code is:

    const connectToWifi = () => {
    	wifi.connect(WIFI_NAME, WIFI_OPTIONS, (err)  => {
    		if (err) {
    		  console.log("Connection error: " + err);
    		  return;
    		} else {
    			console.log("Wifi Connected!");
    			
    			var info = {
    				ip: "192.168.1.9"
    			};
    			
    			wifi.setIP(info, wifi.getIP((err) => {
    				console.log("IP set!");
    				startServer();
    			}));
    		}
    	});
    };
    

    I checked that it's syntactically valid, etc.-- seems fine. But the Espy is throwing an error w underlying code, I believe. And it is looping the upload process. Here's one cycle. Also, I'm including my deploy process as well. I'm a newbie so some basic mistake is totally possible.

    Matts-MacBook-Pro:autolocatorjs mattwalsh$ ./script/deploy
    + set -e
    + source script/env
    +++ espruino --list
    +++ grep usbmodem
    +++ awk '{print $1}'
    +++ head -1
    (node:2022) Warning: N-API is an experimental feature and could change at any time.
    ++ BOARD_PORT=/dev/tty.usbmodem1421
    + echo /dev/tty.usbmodem1421
    /dev/tty.usbmodem1421
    + espruino --port /dev/tty.usbmodem1421 --board board.json --watch src/mw-test.js
    Espruino Command-line Tool 0.1.31
    -----------------------------------
    
    Explicit board JSON supplied: "board.json"
    Connecting to '/dev/tty.usbmodem1421'
    (node:2026) Warning: N-API is an experimental feature and could change at any time.
    Connected
    Module Wifi not found
    
     ____                 _ 
    |  __|___ ___ ___ _ _|_|___ ___ 
    |  __|_ -| . |  _| | | |   | . |
    |____|___|  _|_| |___|_|_|_|___|
             |_| espruino.com
     2v05 (c) 2019 G.Williams
    
    >
    >Upload Complete
    Wifi Connected!
    IP set!
    Starting Server
    Uncaught Error: Function "b" not found!
     at line 1 col 12
    if("OK"==a)b(null);else return b("setIP failed: "+(a?a:"Time...
               ^
    in function "c" called from line 1 col 25
    g=void 0;var b;c&&(b=c(a))?(g=e,c=b):clearTimeout(d);­void 0=...
                            ^
    in function "g" called from line 2 col 4
    g(f)}b=b.substr(a+1);if(p&&d)return q("");"\n"==b[0]&&(b=b.s...
       ^
    in function called from system
    Uncaught Error: Function "b" not found!
     at line 1 col 32
    ...OK"==a)b(null);else return b("setIP failed: "+(a?a:"Timeout"...
                                  ^
    in function "c" called from line 1 col 15
    g=void 0;c&&c();void 0===g&&0<k.length&&f.cmd.apply(f,k.shif.­..
                  ^
    in function called from system
    

    What am I doing wrong here? For what it's worth, our initial test.js works:

    >Upload Complete
    Wifi Connected!
    IP Address: 192.168.1.158
    Starting Server
    Processing request
    Processing request
    

    The setIP part of this is causing the failure. I don't get it. Any ideas?

  • Sorry, that's totally my fault - a copy/paste error. You actually needed:

    var info = {ip:"192.168.1.9"};
    wifi.setIP(info, (err) => {
    })
    

    So without the extra getIP in there. I think if you do that it should be ok. I guess you might find you need to specify the gateway/netmask in setIP (https://www.espruino.com/WiFi#reference) but for a server I don't think that's really needed.

  • Cool. Now it works! Thank you Gordon!

    So, what were you saying earlier about templating the HTML?

  • Great... So literally just:

    // you had this
    var page = '<html><body><script>var ws;setTimeout(function(){';
    page += 'const ws = new WebSocket("ws://" + location.host);';
    page += 'ws.onmessage = function (event) { console.log("MSG:"+event.data); };';
    page += 'setTimeout(function() { ws.send("Hello to Espruino!"); }, 1000);';
    page += '</script><p>something</p></body></html>­';
    // You can do this:
    var page = `<html><body><script>var ws;setTimeout(function(){
    const ws = new WebSocket("ws://" + location.host);
    ws.onmessage = function (event) { console.log("MSG:"+event.data); };
    setTimeout(function() { ws.send("Hello to Espruino!"); }, 1000);
    </script><p>something</p></body></html>`­;
    

    It's just tidier, and especially if you're writing more HTML it'll make things a lot easier :)

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

wifi.setHostname, or setIp on Espy WIFI

Posted by Avatar for mattw @mattw

Actions