Verbinden Sie SORACOM mit Haushaltsgeräten und LINE Bot [Python / Flask / Raspberry Pi]

Einführung

Dieser Artikel ist Kapitel 4 eines Artikels mit vier Kapiteln.

  1. SORACOM Summer Challenge 2020
  2. Senden Sie eine Push-Nachricht an LINE Bot, wenn die LTE-M-Taste gedrückt wird [SORACOM]
  3. [Raspberry Pi] Wenn der menschliche Sensor dies erkennt, speichern Sie den Zeitstempel in der Firebase-Echtzeitdatenbank
  4. SORACOM mit Haushaltsgeräten und LINE Bot [Python / Flask / Raspberry Pi] verknüpfen ** Alle Quellen veröffentlicht **: arrow_backward: Jetzt hier

Sie können das Operationsbild auf YouTube überprüfen.

Auslösen

Ich wollte in der Lage sein, die von SORACOM-Geräten gesammelten Daten interaktiv zu überprüfen und Haushaltsgeräte mit LINE zu betreiben, das von 80 Millionen Menschen in Japan verwendet wird und mit der Benutzeroberfläche vertraut ist.

Was ich benutzt habe

Umgebung

Installation

$ pip install flask
$ pip install line-bot-sdk
$ pip install firebase-admin
$ pip install pillow
$ pip install paramiko

Hauptfunktionen

Ich werde jeden von ihnen zusammen mit dem Quellcode erklären.

Zuerst vom großen Bild

Es wird die gesamte Quelle sein. Bitte beachten Sie, dass die Import- und Zugriffstoken-Teile des Moduls danach nicht mehr veröffentlicht werden.

Quellcode

** Zum Öffnen klicken **

line_bot.py


from flask import Flask, request, abort
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import MessageEvent, TextMessage, TextSendMessage, FlexSendMessage
import subprocess
import os
import json
import time
import datetime
import base64
import requests
import ast
import paramiko
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
from PIL import ImageFont, Image, ImageDraw
from image import add_text_to_image #Selbstgemachtes Modul

app = Flask(__name__)

# LINE Messaging API Settings
LINE_BOT_ACCESS_TOKEN = os.environ["LINE_BOT_ACCESS_TOKEN"]
LINE_BOT_CHANNEL_SECRET = os.environ["LINE_BOT_CHANNEL_SECRET"]

line_bot_api = LineBotApi(LINE_BOT_ACCESS_TOKEN)
handler = WebhookHandler(LINE_BOT_CHANNEL_SECRET)

user_id = "U0..." #ID des Benutzers, der die Nachricht sendet

FQDN = 'https://xxx.ngrok.io' #ngrok URL

# Firebase Settings
cred = credentials.Certificate("<secret key file>.json")
firebase_admin.initialize_app(cred, {
    'databaseURL': 'https://xxx.firebaseio.com/'
})

ref = db.reference('data')

# ssh settings
HOST = '192.168.11.xxx'
PORT = 22
USER = 'username'
KEY_FILE = '../.ssh/<secret_key_file>' #Relativer Pfad

@app.route("/webhook", methods=['POST'])
def webhook():
    print(json.dumps(request.get_json(), indent=2))
    object = request.get_json()
    if object['title'] == "[Alerting] Emergency alert":
        json_message = {
            "type": "bubble",
            "hero": {
                "type": "image",
                "url": "https://xxxx.ngrok.io/static/sos.png ",
                "size": "full",
                "aspectRatio": "16:9",
                "aspectMode": "cover"
            },
            "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                {
                    "type": "text",
                    "text": "Der Notfallknopf wurde gedrückt",
                    "weight": "bold",
                    "size": "lg",
                    "color": "#E9462B",
                    "align": "center"
                },
                {
                    "type": "box",
                    "layout": "vertical",
                    "margin": "lg",
                    "spacing": "sm",
                    "contents": [
                    {
                        "type": "box",
                        "layout": "baseline",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "text",
                            "text": "Ort",
                            "color": "#aaaaaa",
                            "size": "sm",
                            "flex": 1
                        },
                        {
                            "type": "text",
                            "text": "Umkleideraum",
                            "wrap": True,
                            "color": "#666666",
                            "size": "sm",
                            "flex": 5
                        }
                        ]
                    },
                    {
                        "type": "box",
                        "layout": "vertical",
                        "margin": "lg",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "box",
                            "layout": "baseline",
                            "spacing": "sm",
                            "contents": [
                            {
                                "type": "text",
                                "text": "Ich habe die Haustür als Notfallmaßnahme aufgeschlossen",
                                "color": "#4764a6",
                                "size": "md",
                                "flex": 1,
                                "wrap": True
                            }
                            ]
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            "footer": {
                "type": "box",
                "layout": "vertical",
                "spacing": "sm",
                "contents": [
                {
                    "type": "button",
                    "style": "primary",
                    "height": "sm",
                    "action": {
                    "type": "message",
                    "label": "Erste Hilfe",
                    "text": "Erste Hilfe"
                    },
                    "color": "#E9462B"
                },
                {
                    "type": "spacer",
                    "size": "sm"
                }
                ],
                "flex": 0
            }
        }
        messages = FlexSendMessage(alt_text='[SOS]Der Notfallknopf wurde gedrückt', contents=json_message)
        line_bot_api.push_message(user_id, messages=messages)

        key = paramiko.ECDSAKey.from_private_key_file(KEY_FILE)
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(HOST, PORT, USER, pkey=key)
        ssh.exec_command('python3 key_open.py')

    elif object['title'] == "[Alerting] Temperature & Humidity alert":
        current_time = int(time.time()*1000)
        fifteen_minutes_ago = current_time - 900000

        data = ref.order_by_key().limit_to_last(1).get()
        for key, val in data.items():
            if val['timestamp']  >= fifteen_minutes_ago:
                json_message = {
                    "type": "bubble",
                    "hero": {
                        "type": "image",
                        "url": "https://xxx.ngrok.io/static/aircon.png ",
                        "size": "full",
                        "aspectRatio": "16:9",
                        "aspectMode": "cover"
                    },
                    "body": {
                        "type": "box",
                        "layout": "vertical",
                        "contents": [
                        {
                            "type": "text",
                            "text": "Ich schaltete die Klimaanlage ein",
                            "weight": "bold",
                            "size": "xl",
                            "color": "#7077BE"
                        },
                        {
                            "type": "box",
                            "layout": "vertical",
                            "contents": [
                            {
                                "type": "text",
                                "text": "Temperatur und Luftfeuchtigkeit mit hohem Hitzschlagrisiko.",
                                "size": "xs",
                                "wrap": True
                            },
                            {
                                "type": "text",
                                "text": "Da der menschliche Sensor innerhalb von 15 Minuten reagierte, entschied ich, dass ich zu Hause war und schaltete die Klimaanlage ein.",
                                "size": "xs",
                                "wrap": True
                            }
                            ],
                            "margin": "sm"
                        }
                        ]
                    },
                    "footer": {
                        "type": "box",
                        "layout": "vertical",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "button",
                            "style": "primary",
                            "height": "sm",
                            "action": {
                            "type": "message",
                            "label": "Siehe aktuelle Temperatur / Luftfeuchtigkeit",
                            "text": "Temperatur Feuchtigkeit"
                            },
                            "color": "#6fb1bf"
                        },
                        {
                            "type": "button",
                            "style": "primary",
                            "height": "sm",
                            "action": {
                            "type": "uri",
                            "label": "Erkundigen Sie sich bei SORACOM Lagoon",
                            "uri": "https://jp.lagoon.soracom.io/"
                            },
                            "color": "#34CDD7"
                        },
                        {
                            "type": "button",
                            "style": "secondary",
                            "height": "sm",
                            "action": {
                            "type": "message",
                            "label": "Schalten Sie die Klimaanlage aus",
                            "text": "Schalten Sie die Klimaanlage aus"
                            },
                            "color": "#DDDDDD"
                        },
                        {
                            "type": "spacer",
                            "size": "sm"
                        }
                        ],
                        "flex": 0
                    }
                    }
                messages = FlexSendMessage(alt_text='Ich schaltete die Klimaanlage ein', contents=json_message)
                line_bot_api.push_message(user_id, messages=messages)
                subprocess.run("python3 IR-remocon02-commandline.py t `cat filename4.dat`", shell = True, cwd="/home/pi/I2C0x52-IR")

        
    return request.get_data()

@app.route("/callback", methods=['POST'])
def callback():
    signature = request.headers['X-Line-Signature']

    body = request.get_data(as_text=True)
    app.logger.info("Request body: " + body)

    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        abort(400)
    
    return 'OK'


@handler.add(MessageEvent, message=TextMessage)
def handle_message(event):
    
    password = os.environ["soracom_pass"]

    if event.message.text == "Temperatur Feuchtigkeit":
        headers = {
            'Content-Type': 'application/json',
        }

        data = '{"email": "[email protected]", "password": "' + password + '"}'

        response = requests.post('https://api.soracom.io/v1/auth', headers=headers, data=data)

        apikey = response.json()['apiKey']
        token  = response.json()['token']

        current_time = int(time.time()*1000)
        headers = {
            'Accept': 'application/json',
            'X-Soracom-API-Key': apikey,
            'X-Soracom-Token': token,
        }

        params = (
            ('to', current_time),
            ('sort', 'desc'),
            ('limit', '1'),
        )

        response = requests.get('https://api.soracom.io/v1/data/Subscriber/44xxxxxxxxxxxxx', headers=headers, params=params)
        request_body = response.json()

        content = [d.get('content') for d in request_body]

        payload = content[0]
        payload_dic = ast.literal_eval(payload)
        message = base64.b64decode(payload_dic['payload']).decode()
        temp = ast.literal_eval(message)['temp']
        humi = ast.literal_eval(message)['humi']
        
        base_image_path = './image.png'
        base_img = Image.open(base_image_path).copy()
        base_img = base_img.convert('RGB')

        temperature = str(temp)
        font_path = "/usr/share/fonts/downloadfonts/DSEG7-Classic/DSEG7Classic-Regular.ttf"
        font_size = 80
        font_color = (255, 255, 255)
        height = 90
        width = 180
        img = add_text_to_image(base_img, temperature, font_path, font_size, font_color, height, width)

        humidity = str(humi)
        height = 330
        img = add_text_to_image(base_img, humidity, font_path, font_size, font_color, height, width)

        img_path = 'static/{}.png'.format(datetime.datetime.now().strftime('%H-%M-%S'))
        img.save(img_path)

        json_message = {
            "type": "bubble",
            "hero": {
                "type": "image",
                "url": FQDN + '/' + img_path,
                "size": "full",
                "aspectRatio": "1:1",
                "aspectMode": "fit",
            },
            "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                {
                    "type": "text",
                    "text": "Temperatur&Feuchtigkeit",
                    "weight": "bold",
                    "size": "xl",
                    "color": "#6fb1bf"
                },
                {
                    "type": "box",
                    "layout": "vertical",
                    "margin": "lg",
                    "spacing": "sm",
                    "contents": [
                    {
                        "type": "box",
                        "layout": "baseline",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "text",
                            "text": "Temperatur",
                            "color": "#aaaaaa",
                            "size": "sm",
                            "flex": 1
                        },
                        {
                            "type": "text",
                            "text": temperature + '℃',
                            "wrap": True,
                            "color": "#666666",
                            "size": "sm",
                            "flex": 5
                        }
                        ]
                    },
                    {
                        "type": "box",
                        "layout": "baseline",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "text",
                            "text": "Feuchtigkeit",
                            "color": "#aaaaaa",
                            "size": "sm",
                            "flex": 1
                        },
                        {
                            "type": "text",
                            "text": humidity + "%",
                            "wrap": True,
                            "color": "#666666",
                            "size": "sm",
                            "flex": 5
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            "footer": {
                "type": "box",
                "layout": "vertical",
                "spacing": "sm",
                "contents": [
                {
                    "type": "button",
                    "style": "primary",
                    "height": "sm",
                    "action": {
                    "type": "uri",
                    "label": "Erkundigen Sie sich bei SORACOM Lagoon",
                    "uri": "https://jp.lagoon.soracom.io/"
                    },
                    "color": "#34CDD7"
                },
                {
                    "type": "button",
                    "style": "secondary",
                    "height": "sm",
                    "action": {
                    "type": "message",
                    "label": "Menschlicher Sensor",
                    "text": "Menschlicher Sensor"
                    },
                    "color": "#DDDDDD"
                },
                {
                    "type": "spacer",
                    "size": "sm"
                }
                ],
                "flex": 0
            }
        }

        messages = FlexSendMessage(alt_text='Temperatur&Feuchtigkeit', contents=json_message)
        line_bot_api.reply_message(event.reply_token, messages)
        
    elif event.message.text == "Menschlicher Sensor":
        current_time = int(time.time()*1000)
        one_hour_ago = current_time - 3600000

        data = ref.order_by_key().limit_to_last(1).get()
        for key, val in data.items():
            timestamp = datetime.datetime.fromtimestamp(int(val['timestamp']/1000))
            last_time = timestamp.strftime('%m Monat%d Tag%Uhr%M Minuten')
        count = 0
        data = ref.order_by_key().get()
        for key, val in data.items():
            timestamp = val['timestamp']
            if timestamp >= one_hour_ago:
                count += 1
        json_message = {
            "type": "bubble",
            "hero": {
                "type": "image",
                "url": "https://xxx.ngrok.io/static/sensors.png ",
                "size": "full",
                "aspectRatio": "16:9",
                "aspectMode": "cover"
            },
            "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                {
                    "type": "text",
                    "text": "Menschlicher Sensor",
                    "weight": "bold",
                    "size": "xl",
                    "color": "#72D35B"
                },
                {
                    "type": "box",
                    "layout": "vertical",
                    "margin": "lg",
                    "spacing": "sm",
                    "contents": [
                    {
                        "type": "box",
                        "layout": "baseline",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "text",
                            "text": "Anzahl der Erkennungen innerhalb von 1 Stunde",
                            "color": "#aaaaaa",
                            "size": "sm",
                            "flex": 10
                        },
                        {
                            "type": "text",
                            "text": str(count) + "Mal",
                            "wrap": True,
                            "color": "#666666",
                            "size": "sm",
                            "flex": 4,
                            "align": "end"
                        }
                        ]
                    },
                    {
                        "type": "box",
                        "layout": "baseline",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "text",
                            "text": "Letzte erkannte Zeit",
                            "color": "#aaaaaa",
                            "size": "sm",
                            "flex": 5
                        },
                        {
                            "type": "text",
                            "text": last_time,
                            "wrap": True,
                            "color": "#666666",
                            "size": "sm",
                            "flex": 5,
                            "align": "end"
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            "footer": {
                "type": "box",
                "layout": "vertical",
                "spacing": "sm",
                "contents": [
                {
                    "type": "spacer",
                    "size": "sm"
                }
                ],
                "flex": 0
                }
            }
        messages = FlexSendMessage(alt_text='Menschlicher Sensor', contents=json_message)
        line_bot_api.reply_message(event.reply_token, messages)

    elif event.message.text == "Erste Hilfe":
        messages = "Beruhige dich und rufe 119 an"
        line_bot_api.reply_message(event.reply_token, TextSendMessage(text=messages))

    elif event.message.text == "Schalten Sie die Klimaanlage aus":
        messages = "Ich habe die Klimaanlage ausgeschaltet"
        line_bot_api.reply_message(event.reply_token, TextSendMessage(text=messages))
        subprocess.run("python3 IR-remocon02-commandline.py t `cat filename5.dat`", shell = True, cwd="/home/pi/I2C0x52-IR")
  

if __name__ == "__main__":
    port = int(os.getenv("PORT", 6000))
    app.run(host="0.0.0.0", port=port)

➊ Temperatur und Luftfeuchtigkeit anzeigen

[SORACOM Harvest](https://soracom.jp/services/harvest/) speichert die vom SORACOM-Gerät gesendeten Daten. Sie können diese Daten mit der API abrufen.

Holen Sie sich den Schlüssel und das Token, die für die Verwendung der API im folgenden Teil erforderlich sind. Das Passwort wird für alle Fälle als Umgebungsvariable festgelegt.

line_bot.py


password = os.environ["soracom_pass"]
headers = {
            'Content-Type': 'application/json',
        }

data = '{"email": "[email protected]", "password": "' + password + '"}'

response = requests.post('https://api.soracom.io/v1/auth', headers=headers, data=data)

apikey = response.json()['apiKey']
token  = response.json()['token']

Und erhalten Sie die neueste Temperatur und Luftfeuchtigkeit. Wenn Sie andere APIs verwenden möchten, können Sie unter API-Referenz darauf verweisen. Da der Befehl cURL geschrieben ist, konvertieren Sie ihn unter dieser Site in das Python-Format. Da request_body als Liste zurückgegeben wird, nehmen Sie content heraus und konvertieren payload in ein Wörterbuch mit einem Modul namens ast. Sie können die Temperatur und Luftfeuchtigkeit ermitteln, indem Sie die Nachricht mit base64 dekodieren.

line_bot.py


current_time = int(time.time()*1000)
headers = {
    'Accept': 'application/json',
    'X-Soracom-API-Key': apikey,
    'X-Soracom-Token': token,
}

params = (
    ('to', current_time),
    ('sort', 'desc'),
    ('limit', '1'),
)

response = requests.get('https://api.soracom.io/v1/data/Subscriber/44xxxxxxxxxxxxx', headers=headers, params=params)
request_body = response.json()

content = [d.get('content') for d in request_body]

payload = content[0]
payload_dic = ast.literal_eval(payload)
message = base64.b64decode(payload_dic['payload']).decode()
temp = ast.literal_eval(message)['temp']
humi = ast.literal_eval(message)['humi']

Sobald Sie die Daten haben, verwenden Sie Pillow, um ein Bild mit der Temperatur und Luftfeuchtigkeit zu erstellen. Ich habe auf [diesen Artikel] verwiesen (https://qiita.com/xKxAxKx/items/2599006005098dc2e299). Erstellen Sie das folgende Basisbild mit PowerPoint und schreiben Sie die Temperatur und Luftfeuchtigkeit mit der Schriftart DSEG hinein.

line_bot.py


temperature = str(temp)
font_path = "/usr/share/fonts/downloadfonts/DSEG7-Classic/DSEG7Classic-Regular.ttf"
font_size = 80
font_color = (255, 255, 255)
height = 90
width = 180
img = add_text_to_image(base_img, temperature, font_path, font_size, font_color, height, width)

humidity = str(humi)
height = 330
img = add_text_to_image(base_img, humidity, font_path, font_size, font_color, height, width)

img_path = 'static/{}.png'.format(datetime.datetime.now().strftime('%H-%M-%S'))
img.save(img_path)

image.py


from PIL import ImageFont, Image, ImageDraw

def add_text_to_image(img, text, font_path, font_size, font_color, height, width, max_length=740):
    position = (width, height)
    font = ImageFont.truetype(font_path, font_size)
    draw = ImageDraw.Draw(img)
    if draw.textsize(text, font=font)[0] > max_length:
        while draw.textsize(text + '…', font=font)[0] > max_length:
            text = text[:-1]
        text = text + '…'

    draw.text(position, text, font_color, font=font)

    return img

Senden Sie abschließend eine Flex-Nachricht. Mit dem Flex Message Simulator (https://developers.line.biz/flex-simulator/) ist das Erstellen einfach.

Achtung
Der Flex Message Simulator sagt "true", aber in Python beginnt er mit dem oberen Buchstaben "True". Seien Sie also vorsichtig.

line_bot.py


json_message = {
            "type": "bubble",
            "hero": {
                "type": "image",
                "url": FQDN + '/' + img_path,
                "size": "full",
                "aspectRatio": "1:1",
                "aspectMode": "fit",
            },
            "body": {
                "type": "box",
                "layout": "vertical",
                "contents": [
                {
                    "type": "text",
                    "text": "Temperatur&Feuchtigkeit",
                    "weight": "bold",
                    "size": "xl",
                    "color": "#6fb1bf"
                },
                {
                    "type": "box",
                    "layout": "vertical",
                    "margin": "lg",
                    "spacing": "sm",
                    "contents": [
                    {
                        "type": "box",
                        "layout": "baseline",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "text",
                            "text": "Temperatur",
                            "color": "#aaaaaa",
                            "size": "sm",
                            "flex": 1
                        },
                        {
                            "type": "text",
                            "text": temperature + '℃',
                            "wrap": True,
                            "color": "#666666",
                            "size": "sm",
                            "flex": 5
                        }
                        ]
                    },
                    {
                        "type": "box",
                        "layout": "baseline",
                        "spacing": "sm",
                        "contents": [
                        {
                            "type": "text",
                            "text": "Feuchtigkeit",
                            "color": "#aaaaaa",
                            "size": "sm",
                            "flex": 1
                        },
                        {
                            "type": "text",
                            "text": humidity + "%",
                            "wrap": True,
                            "color": "#666666",
                            "size": "sm",
                            "flex": 5
                        }
                        ]
                    }
                    ]
                }
                ]
            },
            "footer": {
                "type": "box",
                "layout": "vertical",
                "spacing": "sm",
                "contents": [
                {
                    "type": "button",
                    "style": "primary",
                    "height": "sm",
                    "action": {
                    "type": "uri",
                    "label": "Erkundigen Sie sich bei SORACOM Lagoon",
                    "uri": "https://jp.lagoon.soracom.io/"
                    },
                    "color": "#34CDD7"
                },
                {
                    "type": "button",
                    "style": "secondary",
                    "height": "sm",
                    "action": {
                    "type": "message",
                    "label": "Menschlicher Sensor",
                    "text": "Menschlicher Sensor"
                    },
                    "color": "#DDDDDD"
                },
                {
                    "type": "spacer",
                    "size": "sm"
                }
                ],
                "flex": 0
            }
        }

messages = FlexSendMessage(alt_text='Temperatur&Feuchtigkeit', contents=json_message)
line_bot_api.reply_message(event.reply_token, messages)

➋ Menschliche Sensordaten anzeigen

Rufen Sie den Wert aus der Firebase-Echtzeitdatenbank ab. Der Server-Zeitstempel ist die UNIX-Zeit (Millisekunden) und wird daher entsprechend konvertiert. Um den Wert von Firebase zu erhalten, habe ich auf [Offizielles Dokument](https://firebase.google.com/docs/database/admin/retrieve-data?hl=ja) verwiesen.

line_bot.py


current_time = int(time.time()*1000)
one_hour_ago = current_time - 3600000

data = ref.order_by_key().limit_to_last(1).get()
    for key, val in data.items():
        timestamp = datetime.datetime.fromtimestamp(int(val['timestamp']/1000))
        last_time = timestamp.strftime('%m Monat%d Tag%Uhr%M Minuten')
    count = 0
    data = ref.order_by_key().get()
    for key, val in data.items():
        timestamp = val['timestamp']
        if timestamp >= one_hour_ago:
            count += 1

Der Flex Message-Teil ist lang, daher habe ich ihn weggelassen, aber er ist der gleiche wie ➊.

➌ Senden Sie im Notfall eine Push-Nachricht

Sie können den Inhalt des von SORACOM Lagoon empfangenen Webhooks mit `` object = request.get_json () `` sehen. Hier klicken für Details]() In der nächsten Zeile steht `` if object ['title'] == "[Alerting] Emergency alert": ``, was auch ein Webhook ist, wenn Lagoon zu [No Data] oder [OK] wechselt. Dies ist zu senden.

Ich habe auch Paramiko verwendet, um in einen anderen Raspberry Pi zu SSH und Befehle in Python auszuführen. Ändern Sie den Teil ECDSAKey in den Schlüsseltyp, den Sie entsprechend festgelegt haben. Sie sollten entweder RSA oder Ed25519 verwenden können.

line_bot.py


key = paramiko.ECDSAKey.from_private_key_file(KEY_FILE)
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(HOST, PORT, USER, pkey=key)
ssh.exec_command('python3 key_open.py')

key_open.py ist ein einfaches Programm, das nur den Servomotor dreht.

key_open.py


import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)

p = GPIO.PWM(4, 50)

p.start(0.0)
p.ChangeDutyCycle(3.0)
time.sleep(0.4)
p.ChangeDutyCycle(0.0)

GPIO.cleanup()

➍ Klimaanlagensteuerung

Die Klimaanlage wird automatisch eingeschaltet, wenn die Bedingungen "Temperatur 30 ° C, Luftfeuchtigkeit 60% oder mehr" und "Menschlicher Sensor reagiert innerhalb von 15 Minuten" erfüllt sind. Das Programm zur Bedienung der Fernbedienung kann von der offiziellen Website von [Bit Trade One](https://bit-trade-one.co.jp/blog/20180515/) heruntergeladen werden.

line_bot.py


current_time = int(time.time()*1000)
fifteen_minutes_ago = current_time - 900000

data = ref.order_by_key().limit_to_last(1).get()
for key, val in data.items():
if val['timestamp']  >= fifteen_minutes_ago:
    #Flex-Nachrichtenteil weggelassen
    subprocess.run("python3 IR-remocon02-commandline.py t cat `filename4.dat`", shell = True, cwd="/home/pi/I2C0x52-IR")

Zusammenfassung

Ich konnte Daten durchsuchen und Haushaltsgeräte bedienen, indem ich die Dienste von LINE Bot und SORACOM, zwei Raspberry Pis und anderen externen Modulen voll ausnutzte. Ich habe nicht viele Artikel über das Berühren der SORACOM-API in Python oder das Verknüpfen von SORACOM mit LINE Bot gesehen, daher hoffe ich, dass es jemandem hilft. Wenn Sie Anregungen oder Fragen haben, können Sie diese gerne kommentieren.

Referenzseite

Recommended Posts