Python x MQTT x WebsocketでThingSpeakにPublish

# 背景
ThingSpeakにHTTP GETでデータを渡すのも飽きてきた。

[ThingSpeakに登録してcurlでデータを送ってグラフを表示するまで - Qiita](https://qiita.com/iton/items/f7c83e5ded25db983586)
[Nature Remoで測定した室温をThingSpeakに渡して表示。 - Qiita](https://qiita.com/iton/items/e88121525ddb6ad6e13a)
[MESH温度・湿度タグで冷蔵庫の温度を取得＋MESH SDKとThingSpeakでグラフ表示 - Qiita](https://qiita.com/iton/items/679930653ab476bcc65a)

せっかくなんでMQTTでやってみようと思った。パブリッシュしたい。

あと、いままで、OpenWeatherMap使ってたけど、他のも使ってみようと思ってLivedoorのん使ってみた。シンプル。

[お天気Webサービス仕様 - Weather Hacks - livedoor 天気情報](http://weather.livedoor.com/weather_hacks/webservice)


# 環境
- GCP f1-micro（vCPU x 1、メモリ 0.6 GB）
- Ubuntu 16.04.3 LTS
- Python 3.6.3 :: Anaconda, Inc.
- ThingSpeak

# 準備
paho-mqttをインストール
```pip install paho-mqtt```

[paho-mqtt · PyPI](https://pypi.org/project/paho-mqtt/)

# 実装
ThingSpeakにパブリッシュするところは、MathWorksのをそのまま使った。
client IDをランダムにする意図がよくわからない。
```__future__```はpython3でやるのでいらない。

[Raspberry Pi 上の Python で WebSocket を使用したパブリッシュ - MATLAB & Simulink - MathWorks 日本](https://jp.mathworks.com/help/thingspeak/use-raspberry-pi-board-that-runs-python-websockets-to-publish-to-a-channel.html)

天気はLivedoorのいう通りアクセスしたらすぐ動いた。

[お天気Webサービス仕様 - Weather Hacks - livedoor 天気情報](http://weather.livedoor.com/weather_hacks/webservice)

```python
# for mqtt                                                                                                                                                                       
# from __future__ import print_function
import paho.mqtt.publish as publish
import string
import random

# for Forecasts                                                                                                                                                                  
import requests
import json

import time

# Forecasts                                                                                                                                                                      
city_id = "280010" # Kobe                                                                                                                                                        
url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=" + str(city_id)

# MQTT                                                                                                                                                                           
string.alphanum='1234567890avcdefghijklmnopqrstuvwxyzxABCDEFGHIJKLMNOPQRSTUVWXYZ'

channelID = "aaa"
writeAPIKey = "bbb"
mqttHost = "mqtt.thingspeak.com"

mqttUsername = "ccc"
mqttAPIKey = "ddd"

tTransport = "websockets"
tPort = 80

topic = "channels/" + channelID + "/publish/" + writeAPIKey

while(1):

    clientID=''

    for x in range(1,16):
        clientID+=random.choice(string.alphanum)

    response = requests.get(url)
    data = response.json()
    temp_max = data['forecasts'][1]['temperature']['max']['celsius']
    temp_min = data['forecasts'][1]['temperature']['min']['celsius']
    print(temp_max)
    print(temp_min)
    payload = "field1=" + str(temp_max) + "&field2=" + str(temp_min)

    try:
        publish.single(topic, payload, hostname=mqttHost, transport=tTransport, port=tPort, auth={'username':mqttUsername, 'password':mqttAPIKey})
        print("Max temperature =", temp_max, " Min temperature=", temp_min, " to host: ", mqttHost, " clientID= ", clientID)

    except (KeyboardInterrupt):
        break

    except:
        print("There was an error while publishing the data.")

    time.sleep(2)
```

# 結果
当たり前だけど、天気予報はすぐには変化ない…。グラフ書く意味ないな。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/184221/707a6bf6-dfe4-ddbb-03ef-fbaa44b67340.png)

# 次したいこと
MQTTで通信してる実感がない。REST API? Web API?との違いがわかりにくい。
Wiresharkでパケットのやりとり見てみようかな。