Using amazon mqtt to publish a button press from a esp8266

#1

I have the following code that prints to my serial console in mongoose os. I can see the device in amazon aws, and in mdash as online. I get back a 0 from the pub and it never sends a message to aws mqtt I have subscribed to the topic in the test seciton in mqtt so not sure what I am doing wrong

I followed every instruction here including the internet button video
https://mongoose-os.com/docs/mongoose-os/cloud/aws.md

load("api_gpio.js");
load("api_mqtt.js");
load("api_sys.js");
let pin = 0;
GPIO.set_button_handler(
  pin,
  GPIO.PULL_UP,
  GPIO.INT_EDGE_NEG,
  50,
  function (x) {
    let topic = "mOS/topic1";
    let message = JSON.stringify({
      total_ram: Sys.total_ram(),
      free_ram: Sys.free_ram(),
    });
    let ok = MQTT.pub(topic, message, message.length);
    let test = ok;
    let res = MQTT.pub("mOS/topic1", JSON.stringify({ a: 1, b: 2 }), 1);

    print(res);
    print("Published:", res ? "yes" : "no");
  },
  true
);
print("Flash button is configured on GPIO pin", pin);
print("Press the flash button now!");

MQTT.sub(
  "mOS/topic1",
  function (conn, topic, msg) {
    print("Topic:", topic, "message:", msg);
  },
  null
);

I am pretty sure I have fullfilled all these requirments

A valid connection

A valid and active certificate

A policy that allows the desired connection and operation

I have a mos-default policy with the following

{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:*",
      "Resource": "*"
    }
  ],
  "Version": "2012-10-17"
}

There is a mos.yml file of the following. And I do have aws.crt.pem and aws.key.pem files in the app.

author: mongoose-os
description: A JS-enabled demo Mongoose OS firmware
# arch: PLATFORM
version: 1.0
manifest_version: 2017-05-18
libs_version: ${mos.version}
modules_version: ${mos.version}
mongoose_os_version: ${mos.version}

config_schema:
  - ["mqtt.server", "iot.eclipse.org:1883"]
  - ["i2c.enable", true]

tags:
  - js

filesystem:
  - fs

libs:
  - origin: https://github.com/mongoose-os-libs/boards
  - origin: https://github.com/mongoose-os-libs/js-demo-bundle

conds:
  # It's not that we can't work with multicore
  # but we cannot afford it because of space (32K).
  - when: mos.platform == "esp32"
    apply:
      build_vars:
        ESP_IDF_SDKCONFIG_OPTS: >
          ${build_vars.ESP_IDF_SDKCONFIG_OPTS}
          CONFIG_FREERTOS_UNICORE=y
let connected = MQTT.isConnected();

print(connected);

returns false, I am not sure how to debug this

#2

I’m too lazy to check your code.
If you get .isConnected as false, then, you are not connected. That means you did not connect to your WiFi or you did not reach AWS IoT or your certs are wrong or your policy is not allowing you to connect. Besides being sure, you should (read ‘must’) check the validity of your assumptions. Your log will tel you, look at those informative pieces of text that come out the serial port while your device is booting, just type mos console.
BTW, your policy looks OK at first sight.

1 Like
#3

Ok it is working again, I needed to delete the device in amazon, and run the mos aws setup command again. ANother question is it normal for in the serial console MQTT to constantly be connecting and disconnecting, what may be causing that?

So it seems everytime I flash the device, it loses connection with AWS, it does stay connected in mDash. Does flashing the device reset some settings somehow? like if I flash it after doing the mos aws command.

So it seems i have to run the aws iot setup command again after flashing the device is this normal behaviour

#4

When you flash your device, you erase its flash memory. Besides your code, the private key that mos generated, the certificate that Amazon generated based on that key, and the Amazon CA certificate that mos downloaded for you and stored in the flash memory of your device, will also be erased.
When your device is initialized, mos also places your unique MQTT server address (endpoint) in your configuration (which you also lose when flashing).
You need to either save all this before re-flashing or re-initialize your device again.

If you can read spanish, I can point you to a doc with how to do all this (no time to re-publish it in english, sorry)

PS: Frequent reconections are not normal in MQTT. If you can run a network sniffer you can search for problems in your connection, otherwise check the log for hints on the disconnect reason, no, it is not normal.
PS PS: in Google GCP your device will periodically disconnect and reconnect because of the JWT expiration. AWS uses TLS and so it should stay stable.

#5

Awesome, I don’t read spanish unfortunately. But knowing this is the case, I can spend some time figuring it out. Just being in the dark about new tech makes it difficult to debug. Thanks

#6

Use mos call FS.List to get a directory listing of the files in your device
Use mos get to retrieve your credentials and save them locally in your fs dir.
E.g.:

$ mos get aws-esp32_807A98.key.pem > fs/aws-esp32_807A98.key.pem
$ mos get aws-esp32_807A98.crt.pem > fs/aws-esp32_807A98.crt.pem
$ mos get ca.pem > fs/ca.pem

Use mos config-get to read your config, or just copy from that verbose output you get when you initialize your device. Save those to mos.yml.
E.g.:

["aws.thing_name", ""]
["mqtt.enable", true]
["mqtt.server", "a1234b5678cde-ats.iot.us-east-2.amazonaws.com:8883"]
["mqtt.ssl_ca_cert", "ca.pem"]
["mqtt.ssl_cert", "aws-esp32_807A98.crt.pem"]
["mqtt.ssl_key", "aws-esp32_807A98.key.pem"]

So, when you re-flash, you re-write your credentials and configure your device with the same data again.

#7

If I am using mdash do I need ot also set the mdash token in the config schema?

as well as my wifi ssid and password in the config yaml

and should this part not be

note the fs, because I am getting a invalid ssl cert

[“mqtt.ssl_cert”, “fs/aws-esp32_807A98.crt.pem”]
[“mqtt.ssl_key”, “fs/aws-esp32_807A98.key.pem”]

and what is the difference between the fs directory and a directory listing of files on my device, is fs directory like a separate area I can store things

#8

I’m having trouble following you.
I know nothing about mdash
You may specify your configuration using mos.yml in a generic way or by using JSON files, there is a layered “system” so vendors can have different levels of control while allowing users to configure the device. There is a doc on this in the literature.
You must not put fs/ in your mos.yml (I did not do that in my example), the fs/ you see happens on the file redirection in the shell in order to write into the fs directory on your computer whatever mos get retrieves from your device.

The $ is the shell prompt, mos get aws-esp32_807A98.key.pem runs mos tool and retrieves that file from the device internal file system. Mongoose-OS provides a file system and you can see files and work with files. There is also documentation on this.
The > is a file redirection character typical from shells, including DOS. Whatever would be printed on screen (standard output of the command run, in this case the ‘mos get’) goes to the file specified next.

Whatever is in the fs directory on your project directory will be put in the flash image when you build and so will be flashed when you flash.
You can also put a file in your device by using mos put

#9

I think I understand what you are saying, and apologies if I am confusing, I am new to this. I have included a screenshot, but when I run the mos get aws-esp32_807A98.key.pem > fs/aws-esp32_807A98.key.pem with my key names it does not move them into the fs directory, if I am understanding you correctly should I just copy and paste them into the fs directory. You can see in the screen shot they exist at the root of the app folder but not inside the fs directory, I assumed the > would move or copy them into the fs directory. Is that correct?

#10

Well, I’m sorry but I don’t have the slightest idea whether Visual Studio Code would redirect or not, and if that depends on your particular OS.
If you want ‘mos build’ to put those files on your flash image, and you want that, then those files have to be inside the fs directory, that very same place where your init.js is.
Otherwise you can ‘mos put’ them later.
This is as far as I can go, good luck