From 41ed321f90e6cfb71eb75571886ab756eac97004 Mon Sep 17 00:00:00 2001 From: cekk Date: Sat, 30 Nov 2019 22:08:22 +0100 Subject: [PATCH] initial commit --- .gitignore | 2 + Makefile | 7 +++ Pipfile | 14 ++++++ Pipfile.lock | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 3 ++ app.py | 82 ++++++++++++++++++++++++++++++ 6 files changed, 248 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100644 README.md create mode 100644 app.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6eee606 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +instance +.vscode diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..02e6205 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +.PHONY: install +install: + pipenv install + +.PHONY: dev +dev: + pipenv run python app.py \ No newline at end of file diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..03efea0 --- /dev/null +++ b/Pipfile @@ -0,0 +1,14 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[dev-packages] + +[packages] +flask = "*" +flask-mqtt = "*" +flask-restful = "*" + +[requires] +python_version = "3.7" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..a80421b --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,140 @@ +{ + "_meta": { + "hash": { + "sha256": "1579c8c1e9e57eaf3eb561988b2cdda36f11a8c90aee3b9cf93b2074f4a7cc84" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.7" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "aniso8601": { + "hashes": [ + "sha256:529dcb1f5f26ee0df6c0a1ee84b7b27197c3c50fc3a6321d66c544689237d072", + "sha256:c033f63d028b9a58e3ab0c2c7d0532ab4bfa7452bfc788fbfe3ddabd327b181a" + ], + "version": "==8.0.0" + }, + "click": { + "hashes": [ + "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", + "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" + ], + "version": "==7.0" + }, + "flask": { + "hashes": [ + "sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52", + "sha256:45eb5a6fd193d6cf7e0cf5d8a5b31f83d5faae0293695626f539a823e93b13f6" + ], + "index": "pypi", + "version": "==1.1.1" + }, + "flask-mqtt": { + "hashes": [ + "sha256:a12e982144fe5a5b0bd3501907c84c80c1cda9c5718eb473ecbd21431fff287e" + ], + "index": "pypi", + "version": "==1.0.5" + }, + "flask-restful": { + "hashes": [ + "sha256:ecd620c5cc29f663627f99e04f17d1f16d095c83dc1d618426e2ad68b03092f8", + "sha256:f8240ec12349afe8df1db168ea7c336c4e5b0271a36982bff7394f93275f2ca9" + ], + "index": "pypi", + "version": "==0.3.7" + }, + "itsdangerous": { + "hashes": [ + "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19", + "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749" + ], + "version": "==1.1.0" + }, + "jinja2": { + "hashes": [ + "sha256:74320bb91f31270f9551d46522e33af46a80c3d619f4a4bf42b3164d30b5911f", + "sha256:9fe95f19286cfefaa917656583d020be14e7859c6b0252588391e47db34527de" + ], + "version": "==2.10.3" + }, + "markupsafe": { + "hashes": [ + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" + ], + "version": "==1.1.1" + }, + "paho-mqtt": { + "hashes": [ + "sha256:e3d286198baaea195c8b3bc221941d25a3ab0e1507fc1779bdb7473806394be4" + ], + "version": "==1.5.0" + }, + "pytz": { + "hashes": [ + "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", + "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + ], + "version": "==2019.3" + }, + "six": { + "hashes": [ + "sha256:1f1b7d42e254082a9db6279deae68afb421ceba6158efa6131de7b3003ee93fd", + "sha256:30f610279e8b2578cab6db20741130331735c781b56053c59c4076da27f06b66" + ], + "version": "==1.13.0" + }, + "typing": { + "hashes": [ + "sha256:91dfe6f3f706ee8cc32d38edbbf304e9b7583fb37108fef38229617f8b3eba23", + "sha256:c8cabb5ab8945cd2f54917be357d134db9cc1eb039e59d1606dc1e60cb1d9d36", + "sha256:f38d83c5a7a7086543a0f649564d661859c5146a85775ab90c0d2f93ffaa9714" + ], + "version": "==3.7.4.1" + }, + "werkzeug": { + "hashes": [ + "sha256:7280924747b5733b246fe23972186c6b348f9ae29724135a6dfc1e53cea433e7", + "sha256:e5f4a1f98b52b18a93da705a7458e55afb26f32bff83ff5d19189f92462d65c4" + ], + "version": "==0.16.0" + } + }, + "develop": {} +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..778823f --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Roller Shutter + +TODO diff --git a/app.py b/app.py new file mode 100644 index 0000000..ae35405 --- /dev/null +++ b/app.py @@ -0,0 +1,82 @@ +from flask import Flask +from flask_restful import Resource, Api, reqparse +from flask_mqtt import Mqtt + +app = Flask(__name__, instance_relative_config=True) +app.config.from_pyfile("config.py") +api = Api(app) +mqtt = Mqtt(app) + +parser = reqparse.RequestParser() +parser.add_argument("command", type=str, help="") + + +@mqtt.on_connect() +def handle_connect(client, userdata, flags, rc): + mqtt.subscribe("shellies/command") + for blind in app.config.get("BLINDS", []): + # mqtt.subscribe("shellies/{id}".format(id=blind.get("id", ""))) + mqtt.subscribe("shellies/{id}/online".format(id=blind.get("id", ""))) + mqtt.subscribe("shellies/{id}/roller/0/pos".format(id=blind.get("id", ""))) + mqtt.subscribe("shellies/{id}/roller/0".format(id=blind.get("id", ""))) + + +@mqtt.on_message() +def handle_mqtt_message(client, userdata, message): + print("{} - {}".format(message.topic, message.payload)) + + +class HomePage(Resource): + def get(self): + return app.config.get("BLINDS", []) + + +class Announce(Resource): + def get(self): + # force all shellies to announce their status + mqtt.publish("shellies/command", "announce") + return "", 204 + + +class Update(Resource): + def get(self): + # force all shellies to announce their status + mqtt.publish("shellies/command", "update") + return "", 204 + + +class Open(Resource): + def get(self, id): + mqtt.publish("shellies/{id}/roller/0/command".format(id=id), "open") + return "", 204 + + +class Close(Resource): + def get(self, id): + mqtt.publish("shellies/{id}/roller/0/command".format(id=id), "close") + return "", 204 + + +class Stop(Resource): + def get(self, id): + mqtt.publish("shellies/{id}/roller/0/command".format(id=id), "stop") + return "", 204 + + +class Command(Resource): + def post(self): + args = parser.parse_args() + mqtt.publish("shellies/shellyswitch25-68E5F8/roller/0/command", "close") + return {todo_id: todos[todo_id]} + + +api.add_resource(HomePage, "/") +api.add_resource(Announce, "/announce") +api.add_resource(Update, "/update") +api.add_resource(Command, "/command") +api.add_resource(Close, "//close") +api.add_resource(Open, "//open") +api.add_resource(Stop, "//stop") + +if __name__ == "__main__": + app.run(debug=False)