NodeMCU + LUA simple temperature and humidity Web Thing

(Alessandro Paganelli) #1

Hi all,
I’m developing a very simple temperature and humidity Web Thing based on a NodeMCU board with NodeMCU firmware. LUA code for the project can be found on GitHub here.

Long story short: Mozilla Gateway cannot find my Thing during discovery and when I manually insert my thing’s URL.

I’ve followed a very naive approach in supporting REST APIs, consisting of a simple “manual” parsing of the request to identify the corresponding REST resource to manage, so it is possible that the root cause is somewhere here.

  • By accessing the thing from a browser using its URL (say: http://192.168.0.2) it correctly provides me the JSON of the Thing resource.
  • The Thing resource provides the links to the properties (e.g., “links”: [{ “href”: “/things/temphumi/properties/temperature” }]), so they should be there and accessible
  • Using the web browser to debug REST APIs I correctly see the expected results (JSON content).

I think I’m missing something very trivial here. Here are my questions:

  1. Is there any minimal reference REST reply that a Thing must provide to be correctly discovered by the Gateway?
  2. Is there any log file I can check on the Gateway to get more info about what is going wrong during the discovery? Is there any debug procedure I can check to understand if there is something in my thing’s reply that is not accepted by the Gateway?
  3. I’m using mDNS to advertise the presence of my node on the network. However, automatic discovery seems to fail, since I’m not seeing any request on the node (btw, I’m connected to the node by means of a serial line, so I can debug any received request), which suggests me that I’m also missing something on the automatic discovery part.

Any suggestion or comment is very welcome!

Kind regards,
Alessandro

0 Likes

(Michael Stegeman) #2

Hi,

This is very cool! I had considered building a webthing-lua library at one point, but never got around to it. A couple things:

  1. Your mDNS advertisement uses the old style. The new one is a _webthing._tcp service. For example, see here.
  2. Your thing description is missing a top-level @type array. It can be empty, but needs to be present, otherwise the gateway will fail to add it. This probably should not be a hard requirement in the gateway, but it currently is.
  3. If, after fixing those things, your thing is still not discovered, you can try to manually add it by clicking the “Add by URL” link on the “Add Things” page.
0 Likes

(Alessandro Paganelli) #3

Thanks for your input.
Unfortunately I had no luck :frowning:

  1. I guess that NodeMCU mDNS support does not completely provide me the ability to fully advertise my sensor as _webthing._tcp, since the API provides me only a generic “service”. I’m trying to investigate this a little bit more, anyway.
  2. Adding @type inside Thing resource does not change the error seen at the gateway level (i.e., “Web thing not found”).

By looking at the Gateway soruce code I see that this error may come due to a wrong reply or due to a Node exception. Is there a way to debug Gateway’s logic directly from the Raspberry?
Is there a setting to increase log verbosity from “info”?

Thanks

0 Likes

(Michael Stegeman) #4

For mDNS, it looks like the module will allow you to specify webthing for service, rather than http, and if you just add path='/', that should be the full mDNS service.

For debugging, you can go one of 2 routes.

  1. You can build/run the gateway yourself, rather than using our prebuilt image. The README should tell you everything you need to know.
  2. If you want to debug using the image we provide, you’ll need to do the following:
    a. SSH into the Raspberry Pi – username is pi, password is raspberry.
    b. cd ~/mozilla-iot/gateway
    c. npm i
    d. sudo systemctl stop mozilla-iot-gateway
    e. Make whatever changes you need
    f. npm start

If you need to debug the adapter, do the following:

  1. cd ~/.mozilla-iot/addons/thing-url-adapter
  2. mkdir .git
  3. Make whatever changes you need (any console logs will go to the gateway’s log)
  4. Either restart the gateway process, or Disable and then Enable the Web Thing add-on through Settings->Add-ons in the UI.
0 Likes

(Alessandro Paganelli) #5

Thanks a lot for your suggestion. I will try the approach you suggest asap! :slight_smile:

0 Likes

(Alessandro Paganelli) #6

@mstegeman, following your approach led me to find the instruction actually failing at the gateway side. Inside /home/pi/mozilla-iot/gateway/build/gateway.js, the logic of NewThingsController.post fails at:

const res = await fetch(url, { headers: {Accept: ‘application/json’}});

throwing an exception (“Parse error”).
BTW, I tried several possible URLs for the test, e.g.:

but the exception arises in all cases. Unfortunately I’m not very expert on JS, so I’m following a kind of try and repeat approach :sweat_smile:

0 Likes

(Michael Stegeman) #7

I wonder if it’s because your JSON responses are missing a Content-Length header?

0 Likes

(Alessandro Paganelli) #8

Ok, I finally solved it, so thanks a lot for your help and your suggestions @mstegeman :slight_smile:

The root cause of this was the wrong reply sent by my NodeMCU board, which was as in the following LUA code:

local thingReply = [[HTTP/1.0 200 OK\r\nContent-Type: application/json\r\n\r\n

Actually LUA supports escape sequences e.g., \r\n but it looks like they are not correctly escaped in multi-line strings (i.e., those enclosed in [[ ]]).
By replacing the above code with the following:

local thingReply = [[HTTP/1.0 200 OK
Content-Type: application/json

{
    "@context": "https://iot.mozilla.org/schemas/",

everything started to work as expected.

BTW, an approach I found to be useful to debug this was to run the fetch part of the gateway code into a smaller NodeJS script, so that I could easily test the response from my NodeMCU board without the whole gateway logic behind.

I will update my code on github asap :slight_smile:

0 Likes

(Michael Stegeman) #9

That’s great, glad you got it working!

1 Like