IPアドレスが変わっても配信し続けるサーバー
いくつかのラズパイのmjpg-streamer経由で画像を配信→HTMLファイルを作ってまとめて閲覧できるようにしていたが、
再起動時にIPアドレスが変わってそのたびにHTMLファイルのIPアドレスを確認、変更するのがめちゃくちゃ億劫だった。
なのでIPアドレスを通知するスクリプトを作って再起動時にIPアドレスをSlackに通知するようにした。
しかし結局Slackの通知を確認してわざわざHTMLを変更するのがめちゃんこメンドイことに気づく。
WEBアプリ化してしまえばよくね?て思った。←今ココ
①HTMLファイル置いているNGINXのサーバーにFlask走らせてPOSTリクエストを受け付けるようにする。
③合わせてその都度IPアドレスを書き換えるようにする。
まずは準備
①【サーバー側】Flaskの用意
flaskがちゃんと動いてるか確認する。一番大変なのはスクリプティングよりもポートの開放だったりしたのでここをしっかりできれば後がスゴイ早い
②【ラズパイ側】mjpg-streamerが使えるようにしておく
こちらでmjpg-streamerを準備する。
こちらでもポートの開放を忘れないようにする
そしてcrontab -e
の@reboot
オプションで起動時にmjpg-streamerとIPアドレスのスクリプトを走らせるようにしておくこと。
以下ソース
【ラズパイ側のスクリプト】
以前書いたスクリプトを若干変更する。requestsモジュールを利用するのでもしなければ
pip install requests
しておく。
import slackweb import ipget import time import requests import re def post_to_slack(): try: post() except: time.sleep(10) post_to_slack() def post(): slack = slackweb.Slack(url = "【slackのWebohookURL】") ip = ipget.ipget() ipaddress = ip.ipaddr("eth0") try: ipaddress = ipaddress[:re.search("/",ipaddress).start()] except: pass ips = {"machine":"frontcam","ip":ipaddress} slack.notify(text="hello,i am camera RPi and my IP is :%s" % ipaddress) try: requests.post('【WEBサーバーのIPアドレス】/post',params = ips) except: print("POST できんかった・・") if __name__ == '__main__': post_to_slack()
【サーバー側のスクリプトなど】
ディレクトリ構造
root/ ├ app.py ├ control/ ├ __init__.py ├ views.py ├ config.py ├ models.py ├ static/ │ ├ address.db │ ├ jquery.js │ ├ kube.css │ └ kube.js └ templates/ └ layout.html
app.py
from control import app if __name__ == '__main__': app.run(debug=True)
__init__.py
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config.from_object('control.config') db = SQLAlchemy(app) import control.views
config.py
SQLALCHEMY_DATABASE_URI = 'sqlite:///./static/address.db' SECRET_KEY = '【お好みのKey】' SQLALCHEMY_TRACK_MODIFICATIONS = True
models.py
from control import db class Entry(db.Model): __tablename__ = 'address' __table_args__ = {'extend_existing': True} id = db.Column(db.Integer,primary_key = True) machine = db.Column(db.Text) ipaddress = db.Column(db.Text) comment = db.Column(db.Text) def __repr__(self): return 'entry id = {id} machine = {machine} ipaddress = {ipaddress} comment = {comment}'\ .format(id = self.id , machine = self.machine , ipaddress=self.ipaddress,comment = self.comment) def init(): db.create_all()
views.py
from flask import Flask, render_template, request, url_for,redirect from control import app,db from control.models import Entry @app.route('/') def index(): try: entry = Entry.query.filter_by(machine = "frontcam").first() machine = entry.machine address = entry.ipaddress return render_template("layout.html",machine = machine,ip = address) except: return "エラー1" @app.route('/post',methods =['POST']) def resisteripaddress(): # print(request.values.getlist("machine")[0]) if request.values.getlist("machine")[0] == "frontcam": entry = Entry.query.filter_by(machine = "frontcam").first() entry.ipaddress = request.values.getlist("ip")[0] db.session.add(entry) db.session.commit() return url_for('index') else: print("machineじゃなかった") return "エラー2"
layout.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <!--Import materialize.css--> <link type="text/css" rel="stylesheet" href="../static/kube.css" media="screen,projection"/> <title>カメラ</title> </head> <br> <div class = "container"> <div class = "row gutters"> <div class = "col col-4"> <figure> <img src="http://{{ip}}:8494/?action=stream" /> <figcaption> フロント </figcaption> </figure> </div> <div class = "col col-4"> <figure> <img src="http://{{ip}}:8495/?action=stream" /> <figcaption> 外 </figcaption> </figure> </div> </div> </div> </body> <!--Import jQuery before materialize.js--> <script type="text/javascript" src="../jquery-3.2.1.js"></script> <script type="text/javascript" src="../static/kube.js"></script> <style> @import url(http://fonts.googleapis.com/earlyaccess/notosansjp.css); body { font-family: 'Noto Sans JP', sans-serif; font-size: 100%; } div.container{margin:30px} </style> </html>