M5StickC × MicroPythonでLINE通知を試してみた話(失敗例)


# M5StickCで通知

[前回](https://qiita.com/ryo_naka/items/8b3e203592dd06216168)、初期設定をしたので、これを使ってとりあえず押したボタンに応じてどのボタンを押したかを通知する仕組みを目指す。

※注記：最終的には上手くいっていないです。


## VS Codeで実装
エクステンション「vscode-m5stack-mpy」をインストール

しばらくアップデートしてなかったVSCodeのままだと、インストールできなかったのでアップデートしてからインストール


## USB接続モードに変更

以下を参考に変更。
https://kitto-yakudatsu.com/archives/7143#toc11

１．電源OFFにする
２．Aを押しながら電源ON
３．選択画面が表示されたら、「Setup」にする（Bで選択、Aで決定）
４．「USB Mode」にする（Bで選択、Aで決定）
USB接続っぽい画面（USBコードが表示されている）になったらOK

## VSCで接続
VSC上で「Add M5Stack」を押下して、ポート選択すると、「M5STACK DEVICE」に指定したデバイスの中身が表示される。

雰囲気的にはappsフォルダの中にpythonファイルを格納すると本体側で実行できる感じっぽい。
コード上で右クリックすると実行できる模様。これがデバッグ用かな。


### 現在時刻を表示したい
ふつうに処理/表示する分には特に悩みポイントはなかったのだが、
NTPで同期させた現在時刻を取得するとことで悩んだので残しておく。

大体どこを見ても、ampy でアップロードしろと書いてあるが、上記手順でVSCで参照できるようになっていれば、単純にVSCで＋やアップロードボタンからアップロードするだけでOK。コマンド不要。楽ちんだ。

時刻取得処理そのものは以下を参照
https://qiita.com/inasawa/items/a1830266c1eceb714884

※自分で使うだけならOffsetやhostは以下のヤツを直接書き換えた方が使う際にはシンプルかもしれない
https://github.com/micropython/micropython/blob/master/ports/esp8266/modules/ntptime.py



``` python
# 何かしらで通信接続
import wifiCfg
wifiCfg.autoConnect(lcdShow=True)

# アップロードしたntptimeを使う
import ntptime, utime

offset = 9 * 3600
ntptime.host = 'ntp.nict.jp'
ntptime.settime(offset)

now = utime.localtime() #現在時刻の取得
print(utime.localtime()) #(YYYY, MM, DD, HH, MM, SS, MS)
```

### 横向きにいろいろと表示
+ 現在時刻の表示（1秒ごと）
+ Aボタン押下でバッテリーの状況とWifi接続の表示

``` python 
from m5stack import *
from m5ui import *
from uiflow import *

import _thread

# WiFi接続：時間をNTPで同期させようと思ったら通信が必要
import wifiCfg
wifiCfg.autoConnect(lcdShow=True)

# 時刻同期
import ntptime, utime
offset = 9 * 3600
ntptime.host = 'ntp.nict.jp'
ntptime.settime(offset)

# 画面初期設定
lcd.clear()
setScreenColor(0x111111)
lcd.setRotation(1)
lcd.line(10, 15, 150, 15, lcd.LIGHTGREY)

label1 = M5TextBox(10, 20, "", lcd.FONT_DefaultSmall,0x17f8ab, rotate=0)
label2 = M5TextBox(10, 30, "", lcd.FONT_DefaultSmall,0x17f8ab, rotate=0)
label3 = M5TextBox(10, 40, "", lcd.FONT_DefaultSmall,0xcac8c8, rotate=0)
label4 = M5TextBox(10, 50, "", lcd.FONT_DefaultSmall,0xcac8c8, rotate=0)


def time_count():
    while True:
        fc = lcd.RED
        lcd.font(lcd.FONT_DefaultSmall, rotate = 0)
        lcd.print('{}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}'.format(*time.localtime()[:6]), 20, 0, fc)
        utime.sleep(1)

# 時刻表示スレッド
_thread.start_new_thread(time_count , ())


def buttonA_wasPressed():
    M5Led.on()
    # time_count()
    label1.setText("BatCurrent : {}".format(str(axp.getBatCurrent())))
    label2.setText("BatVoltage : {}".format(str(axp.getBatVoltage())))
    label3.setText("ChargeState : {}".format(str(axp.getChargeState())))
    if wifiCfg.wlan_sta.isconnected():
        label4.setText("Wifi Connected")
    else:
        label4.setText("Wifi Not Connected")


    wait(3)
    # 見えなくする
    M5Led.off()
    label1.setText("")
    label2.setText("")
    label3.setText("")
    label4.setText("")
    lcd.rect(10 , 20, 160, 50, lcd.BLACK, lcd.BLACK)

# ボタン検出スレッド
btnA.wasPressed(buttonA_wasPressed)
```


## 通知したい
本題の一つ手前。
とりあえずGetを試してみる。
ここだけでかなり時間がかった。

以下よりAPIで天気を取得することができるので、通信先として利用。
https://openweathermap.org/


``` python 
import urequests as requests 
import ujson

def send_text():
    if wifiCfg.wlan_sta.isconnected():
        pass
    try:
        _url = 'http://api.openweathermap.org/data/2.5/weather?q=kawasaki,jp&appid=<APP ID>'
        res = requests.get(url=_url)

        json = res.json()
        main = json['main']
        temp = main['temp']
        label2.setText("{}".format(temp))
        pressure = main['pressure']
        label3.setText("{}".format(pressure))
        humidity = main['humidity']
        label4.setText("{}".format(humidity))
        temp_min = main['temp_min']
        label5.setText("{}".format(temp_min))
        temp_max = main['temp_max']

    except Exception as e:
        label4.setText("Error")
        pass
```

上記の天気取得だとうまくいくのだが、失敗するURLがあってよくわからない。
PythonならできるのでMicroPythonの部分で何かしら差があるのかもしれない。

ともあれ、これをもとにどこかへ通知を試してみる

## Line Notify
シンプルにLINE Notifyを使うことにする。

https://notify-bot.line.me/ja/

+ ログインする
+ マイページから「トークンを発行する」を選択
+ 通知するルームと送信者名を設定

トークンが発行されるので、メモしておく





``` python 

import requests

def send_line(token, message):
    url = "https://notify-api.line.me/api/notify"
    access_token = token
    headers = {'Authorization': 'Bearer ' + access_token}
    payload = {'message': message}
    r = requests.post(url, headers=headers, params=payload,)
```

参考
https://qiita.com/moriita/items/5b199ac6b14ceaa4f7c9



と、ここまで試してみたけど、送信できず。
本題ではないここに時間をかけすぎるのはアレなので、MicroPythonでの実装はいったん諦める。Arduinoでやっている人に比べて少ないので、わからないときの手掛かりが少なすぎる。
なので、Arduino でやることにした。MicroPythonの方が書きやすいから、こっちで完結できればこっちがよかったんだけどな。