mqtt
IoT
ESP32
MycroPython
ESP-WROOM-32

温度/湿度をモニターしてaws IOTを介して…

こちらの記事の続編です。たぶん全3回。

リクガメのおウチの温度/湿度をモニターしてawsに投げるのを1000円くらいでやる(予定)

今はこんな感じです。

まだモニターするとこまでしかやってないのでawsに投げるとこをやろうと思う。
でも他にも課題があります。

やりたい

  • aws iotに投げる(MQTT)
  • ESP32のLight sleepモード使う
  • とりあえずDynamoDBに入れる

Light-Sleep

まずLight Sleepモードから。
Deep Sleepモードが定番なんだけど、なんかお手軽っぽい所から。
参考になるのはこのへんかな。

http://docs.micropython.org/en/v1.9.2/esp8266/library/esp.html

ただ、ですね。。このライブラリはesp8266用なのか。esp32で使うとesp.sleep_type()ってやると、そんなんないって怒られます。結局うまくいかなかったので、あっさりとあきらめてesp8266が乗ってる、こういうやつに乗り換えました。

Rasbee OTA WeMos D1 CH340 WiFi 開発ボード ESP8266 ESP-12F For IDE UNO R3 Arduino用 1個 [並行輸入品]
https://www.amazon.co.jp/gp/aw/d/B0739YKWSH/

ちなみにこれだとセンサー合わせて1000円くらいになる。
あと白状するとesp32とesp8266の違いはあんましらんくて、ちょっと名前違うくらいやろ、としか思ってませんでした。micropythonのlibralyの対応が遅れてるのか、もしくは外部のライブラリを使えばなんとかなるのかわからんけど、ここはまた改めて。

で、RSTとPin16をつなぎつつ、だいたいこの通りにやったらうまくいったっぽい。加えたコードはこのへんですね。とりあえずお試しなので10秒だけsleep。

import esp
esp.sleep_type(esp.SLEEP_LIGHT)
esp.deepsleep(1000 * 1000 * 10)

MQTT

AWS IoT の使用開始
/ AWS IoT MQTT クライアントでデバイスの MQTT メッセージを確認する

というかmqttとはなんぞや。Message Queue Telemetry Transportのことらしい。なんとなく、とりあえずレシーブしてくれるものって思ってる。SQSがもっとsaas側に強化されたイメージかなあ。レシーブ後もいろいろ動作を指定できそう。まあ、投げとけばその先もよしなにできるんじゃね?って思うのでとりあえず進める。

このあたりの通りにやってみましょう。

24.png

ふむ。チュートリアル通りにやったらSNS経由でメールは受信できた。

次はmicropython側からなんか投げてみよう。aws iotになげる方法ググってみたけど、こういう感じでええんやろか。

https://forum.micropython.org/viewtopic.php?t=5166
umqtt/simple.pyはuPyCraftのlibraryにあったのでこれをコピります。

・・しかし何かうまくいかない。。
結局こんなとこにいきつく。

https://github.com/micropython/micropython/issues/2781
https://docs.micropython.org/en/latest/library/ussl.html

んー・・なんかうまくいかない。'module' object has no attribute 'CERT_REQUIRED'って言われたりとかinvalid keyっていわれたりとか。ファームウェアに乗ってるライブラリがssl対応してないとかなんとかなのか??
明日のアドベンドカレンダーに登録してしまったんやけど、このままやと間に合わん。。
というわけで別の方向に逃げてみる。いったんsleepモードとかの問題はおいといてesp32にまた戻る。

it works well right now between SSL Python Server and ESP32 Client

とは書いてあるしesp32ならきっと問題ないんだ。あといずれはESP-IDFとか使って自分で焼いてみたい。
(それとsleep問題はなんとかなるかな。machine.deepsleep(0)とかでいいっぽい。 https://forum.micropython.org/viewtopic.php?t=3900)

・・・

そんなわけで試行錯誤してソースごちゃごちゃになっていますが、ひとまずaws iotに届きました。バンザイ。getaddressinfoでうまくipアドレス取れてないのか、自前でとってやったらなんかうまくいった。
でも接続は不安定。。よく[Errno 12] ENOMEMって出るんですよね。Memoryがなんかアレなんだけどよくわかりません。

・・とまあ、本日はここで力尽きました。。記事もごちゃごちゃしててすみません。

25.png

test.py
import sys
import dht
import machine
import time
import ambient
from umqtt.simple import MQTTClient
import json
import usocket

# this is the mbedtls test RSA key; you must change it to your own for production!
key = """-----BEGIN RSA PRIVATE KEY-----
himitsu
-----END RSA PRIVATE KEY-----
"""

# this is the mbedtls test certificate; you must change it to your own for production!
cert = """-----BEGIN CERTIFICATE-----
himitsu
-----END CERTIFICATE-----
"""

ssid = ''
password = ''
channel_id = ''
write_key = ''

certificate_key_file = 'cert/private.pem.key'
certificate_cert_file = 'cert/certificate.pem.crt'
certificate_ca_file = 'cert/ca1.pem'
mqtt_endpoint = 'xxx.iot.ap-northeast-1.amazonaws.com'
mqtt_topic = 'kamekusa/DHT22'

def do_connect(ssid, password):
  import network
  sta_if = network.WLAN(network.STA_IF)
  if not sta_if.isconnected():
    print ('connecting ...')
    sta_if.active(True)
    sta_if.connect(ssid, password)
    timeout = 10
    while not sta_if.isconnected() and timeout > 0:
      print('.')
      time.sleep(3)
      timeout -= 1
  print(sta_if.ifconfig())

def mqttpub(tem,hum):
  a=usocket.getaddrinfo(mqtt_endpoint,8883)
  print ("Address infos:", a[0][-1][0])
  addr = a[0][-1][0]
  msg = '{"device_id":"ESP2866DHT22", "data":{"d1":"%3.1f", "d2":"%3.1f"}}' % (tem, hum)
  client = MQTTClient(client_id="ESP2866DHT22", server=addr, port=8883, keepalive=5000, ssl=True, ssl_params={ "key":key, "cert":cert, "server_side":False })
  client.DEBUG = True
  client.connect()
  print(str(client))

  loop = 10
  while loop > 1:
    print (".")
    try:
      res = client.publish(topic=mqtt_topic, msg=msg, qos=0)
      print('Sending: ' + msg)
      print(str(res))
      loop = 0
    except Exception as e:
      print('Could not establish MQTT connection')
      print (str(e))
      time.sleep(1)
      loop -= 1

def send_am(tem,hum):
    am = ambient.Ambient(channel_id, write_key)
    res = am.send({
      "d1": tem,
      "d2": hum
    })

    print(res.status_code)
    res.close()

def main(d):
  loop = 10
  while loop > 1:
    print(".")
    try:
      time.sleep(1)
      d.measure()
      loop = 0
    except:
      loop -= 1

  print("Temperature: %3.1f ℃" % d.temperature())
  print("   Humidity: %3.1f %%" % d.humidity())
  tem = d.temperature()
  hum = d.humidity()
  mqttpub(tem,hum)
  send_am(tem,hum)

  #print ("start sleep")
  #machine.deepsleep(1000 * 1000 * 600)

do_connect(ssid, password)
d = dht.DHT22(machine.Pin(4))
main(d)

ちょっとソース編集しました 1812252130

なんかいろいろ書いてあるな。。
2分待つの?

http://docs.micropython.org/en/v1.9.2/esp8266/esp8266/general.html