From 40b1160bd909883a2293f99123bd8c77ed60d858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kal=C3=A9o?= Date: Tue, 25 Feb 2020 22:38:47 +0100 Subject: [PATCH] KALEOFR: implementing nabookd with RFID as trigger --- nabd/rfid.py | 6 +- nabrfid2server/__init__.py | 1 + nabrfid2server/apps.py | 5 + .../locale/fr_FR/LC_MESSAGES/django.mo | Bin 0 -> 1931 bytes .../locale/fr_FR/LC_MESSAGES/django.po | 80 ++++++++++++++ nabrfid2server/migrations/0001_initial.py | 23 ++++ nabrfid2server/migrations/__init__.py | 0 nabrfid2server/models.py | 11 ++ nabrfid2server/nabrfid2server.py | 74 +++++++++++++ nabrfid2server/nabrfid2server.service | 16 +++ .../templates/nabrfid2server/settings.html | 101 ++++++++++++++++++ nabrfid2server/urls.py | 6 ++ nabrfid2server/views.py | 30 ++++++ nabweb/settings.py | 3 +- 14 files changed, 352 insertions(+), 4 deletions(-) create mode 100644 nabrfid2server/__init__.py create mode 100644 nabrfid2server/apps.py create mode 100644 nabrfid2server/locale/fr_FR/LC_MESSAGES/django.mo create mode 100644 nabrfid2server/locale/fr_FR/LC_MESSAGES/django.po create mode 100644 nabrfid2server/migrations/0001_initial.py create mode 100644 nabrfid2server/migrations/__init__.py create mode 100644 nabrfid2server/models.py create mode 100644 nabrfid2server/nabrfid2server.py create mode 100644 nabrfid2server/nabrfid2server.service create mode 100644 nabrfid2server/templates/nabrfid2server/settings.html create mode 100644 nabrfid2server/urls.py create mode 100644 nabrfid2server/views.py diff --git a/nabd/rfid.py b/nabd/rfid.py index 1b6c3d6a..a1e60cc2 100644 --- a/nabd/rfid.py +++ b/nabd/rfid.py @@ -23,10 +23,10 @@ class TagFlags(IntFlag): 1: "nab8balld", 2: "nabairqualityd", 3: "nabblockly", - nabbookd.NABAZTAG_RFID_APPLICATION_ID: "nabbookd", # 4 + 4: "nabbookd", 5: "nabclockd", 6: "nabmastodond", - nabsurprised.NABAZTAG_RFID_APPLICATION_ID: "nabsurprised", # 7 + nabsurprised.NABAZTAG_RFID_APPLICATION_ID: "nabsurprised", nabtaichid.NABAZTAG_RFID_APPLICATION_ID: "nabtaichid", # 8 nabweatherd.NABAZTAG_RFID_APPLICATION_ID: "nabweatherd", # 9 } @@ -35,7 +35,7 @@ class TagFlags(IntFlag): class Rfid(object, metaclass=abc.ABCMeta): - """Interface for rfid reader""" + """ Interface for rfid reader """ @abc.abstractmethod def on_detect( diff --git a/nabrfid2server/__init__.py b/nabrfid2server/__init__.py new file mode 100644 index 00000000..8fc210b8 --- /dev/null +++ b/nabrfid2server/__init__.py @@ -0,0 +1 @@ +NABAZTAG_SERVICE_PRIORITY = 11 diff --git a/nabrfid2server/apps.py b/nabrfid2server/apps.py new file mode 100644 index 00000000..c9625aa9 --- /dev/null +++ b/nabrfid2server/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class Nabrfid2serverConfig(AppConfig): + name = "nabrfid2server" diff --git a/nabrfid2server/locale/fr_FR/LC_MESSAGES/django.mo b/nabrfid2server/locale/fr_FR/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..b9ac860e71be2c77ad6ebb8ca099be048341c6ca GIT binary patch literal 1931 zcmcIlO>g5w7&cI#gfFpx_&mI@hXqlGUBqEArCPIfOO~XmlC)wG(rRMAN!_()%y=dx zh!a9W`~WUUNZe4kbKsm4C;kDyV1ES9jI)~-i6fRKkL^D1%=3Oc?%$U-ehhFujrBU# zcUaG1-NSO%)rW%MdEhnRC13)40r(m48DI%~6!;Br1Nbe_-G7huKAtxo34-^49{`^M z7QknLbD-Pz2jENK{tSEt&%a|6r{gc+YruOzr)Lv~JPv#n_$2U6;7^Ea19$NJ=VJ|S zg5>n=178My0elf?fuQ?q6TeTa?ww|A;q!-t;9)Gczth^nau-4aY~NgQaVF+9)hshI zCrn06g9DzizWAyyi#bh{CM)ksbtXM;u-DloqiDz)0l|Q4Ho;KLI2f|A6^Wu&ep9Op zQWKgh>$Y{|Hr-a1QXwgqX<;+oqO%j$>^LNuGrVv3&83=g_Vzk#uN&_VeVDB( zr9BHJD1~viY|{3c8y_Av8se%#T19~j#&Z&`W=()oz2+arH$O!{`sf8A@F7vw1m84Q-X!40L zRNLItJ`ObxMyRRp#~6QZ0$iG|y~5W9g=<>p@;VxH+rfxyLnRaD;f(-qFb5c-er0fu zf4>xa8BebSG5op(O(A0(}=s7*L>`U_!{j%e?w+oglJm(X_7i#y#L z@$T**84hI>!y;1C61d{ z&|~;3^KMm$Tz*LDiO}%EM@OT*@cNqPWKCFyiA+_7L5}G9I5(}p>n+(B%)e2#rh;of zQkxI`G2;pVepz{AP6!<9z{_CQ|b>uW^Y? zLgTRU+){132_o9{2I9yHFT?26kZXADbohWGlvCnpO20a1!P_W%F@ literal 0 HcmV?d00001 diff --git a/nabrfid2server/locale/fr_FR/LC_MESSAGES/django.po b/nabrfid2server/locale/fr_FR/LC_MESSAGES/django.po new file mode 100644 index 00000000..8d7f032c --- /dev/null +++ b/nabrfid2server/locale/fr_FR/LC_MESSAGES/django.po @@ -0,0 +1,80 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-02-12 14:21+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: templates/nabrfid2server/settings.html:38 +msgid "RFID to Server" +msgstr "RFID vers Serveur" + +#: templates/nabrfid2server/settings.html:38 +msgid "Tags can be transmitted to a remote server by URL." +msgstr "Les Tags peuvent être envoyés à un serveur distant par URL." + +#: templates/nabrfid2server/settings.html:39 +msgid "Setup below the transmission mode that suits for you" +msgstr "Sélectionnez ci-dessous votre mode de transmission préféré" + +#: templates/nabrfid2server/settings.html:40 +msgid "" +"Setup also the url of your server. You can include, where you need in" +" your url the following tags:
#RFID_TAG# : uid of the tag" +"
#RFID_STATE# : state of the tag (detected, removed)" +"
#RFID_FLAGS# : supported, formatted,etc." +"
#RFID_APP# : App called by a formatted tag" +"
#RFID_PACK# : the whole RFID packet received" +"
#RFID_JEEPACK# : compatible RFID_PACK for Jeedom" +msgstr "" +"Configurez l'URL de votre serveur. Vous pouvez ajouter, où nécessaire " +" dans votre url les tags suivants:
#RFID_TAG# : uid du tag RFID" +"
#RFID_STATE# : état du tag (detected, removed)" +"
#RFID_FLAGS# : supported, formatted,etc." +"
#RFID_APP# : Application appelée par un tag programmé" +"
#RFID_PACK# : le paquet RFID reçu, au complet" +"
#RFID_JEEPACK# : le paquet RFID_PACK compatible avec Jeedom" + +#: templates/nabrfid2server/settings.html:10 +msgid "URL Send Option" +msgstr "Option d'envoie des Tags" + +#: templates/nabrfid2server/settings.html:13 +msgid "Never send the tag" +msgstr "Ne jamais transmettre de Tag" + +#: templates/nabrfid2server/settings.html:14 +msgid "Only for unknown tag" +msgstr "Seulement les tags inconnus" + +#: templates/nabrfid2server/settings.html:15 +msgid "Always send the tag" +msgstr "Transmettre tous les tags" + +#: templates/nabrfid2server/settings.html:15 +msgid "URL of your server:" +msgstr "URL de votre serveur:" + +#: templates/nabrfid2server/settings.html:22 +msgid "Test me now!" +msgstr "Envoyer une url test" + +#: templates/nabrfid2server/settings.html:29 +msgid "Save" +msgstr "Enregistrer" + +#: templates/nabrfid2server/settings.html:30 +msgid "Reset" +msgstr "Annuler" diff --git a/nabrfid2server/migrations/0001_initial.py b/nabrfid2server/migrations/0001_initial.py new file mode 100644 index 00000000..2e223f64 --- /dev/null +++ b/nabrfid2server/migrations/0001_initial.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.3 on 2020-02-27 10:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Config', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('rfid_2_server_test', models.BooleanField(default=False)), + ('rfid_2_server_mode', models.IntegerField(default=2)), + ('rfid_2_server_url', models.TextField(default='Ex: https://MY_SERVER/core/api/jeeApi.php?apikey=MY_API_KEY&type=scenario&id=MY_SCENARIO_ID&action=start&tags=rfid="#RFID_TAG#"%20etat="#RFID_STATE#"%20flags=#34;#RFID_FLAGS##34;%20app=#34;#RFID_APP##34;')), + ], + ), + ] diff --git a/nabrfid2server/migrations/__init__.py b/nabrfid2server/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/nabrfid2server/models.py b/nabrfid2server/models.py new file mode 100644 index 00000000..7a7a3307 --- /dev/null +++ b/nabrfid2server/models.py @@ -0,0 +1,11 @@ +from django.db import models +from nabcommon import singleton_model + + +class Config(singleton_model.SingletonModel): + rfid_2_server_test = models.BooleanField(default=False) + rfid_2_server_mode = models.IntegerField(default=2) + rfid_2_server_url = models.TextField(default="Ex: https://MY_SERVER/core/api/jeeApi.php?apikey=MY_API_KEY&type=scenario&id=MY_SCENARIO_ID&action=start&tags=rfid="#RFID_TAG#"%20etat="#RFID_STATE#"%20flags=#34;#RFID_FLAGS##34;%20app=#34;#RFID_APP##34;") + + class Meta: + app_label = "nabrfid2server" diff --git a/nabrfid2server/nabrfid2server.py b/nabrfid2server/nabrfid2server.py new file mode 100644 index 00000000..28c05d02 --- /dev/null +++ b/nabrfid2server/nabrfid2server.py @@ -0,0 +1,74 @@ +import sys +import json +import logging +import requests +from nabcommon.nabservice import NabService + + +class NabRfid2server(NabService): + DAEMON_PIDFILE = "/run/nabrfid2server.pid" + + def __init__(self): + super().__init__() + from . import models + + self.config = models.Config.load() + + async def reload_config(self): + from . import models + self.config = await models.Config.load_async() + + #logging.info("reload config: mode=" + str(self.config.rfid_2_server_mode) + " test="+str(self.config.rfid_2_server_test) + " url="+self.config.rfid_2_server_url) + if self.config.rfid_2_server_test : self.send_rfid_2_url("rfid_uid_test","event_test","app_test","support_test","packet_test") + + async def process_nabd_packet(self, packet): + if ( self.config.rfid_2_server_mode==0 or (packet["type"] != "rfid_event") ): return # Never send url + + if "app" not in packet: app = "none" + else: app = packet["app"] + if "support" not in packet: supp = "support unknown" + else: supp = packet["support"] + if "event" not in packet: _event = "no event" + else: _event = packet["event"] + + if (self.config.rfid_2_server_mode==1) and (supp=="formatted") and (app=="none") : return # Send only unknown tags + self.send_rfid_2_url(packet["uid"],_event,app,supp,packet) + + def send_rfid_2_url(self, uid,_event,app,supp,packet): + #logging.info("send rfid 2 url: mode=" + str(self.config.rfid_2_server_mode) + " test="+str(self.config.rfid_2_server_test) + " url="+self.config.rfid_2_server_url) + url_message = self.config.rfid_2_server_url.replace("#RFID_TAG#",uid) + url_message = url_message.replace("#RFID_APP#",app) + url_message = url_message.replace("#RFID_FLAGS#",supp) + url_message = url_message.replace("#RFID_STATE#",_event) + str_pack = json.dumps(packet); + url_message = url_message.replace("#RFID_PACK#",str_pack) + str_pack = str_pack.lower() + str_pack = str_pack.replace('\"','') + url_message = url_message.replace("#RFID_JEEPACK#",str_pack) + f = requests.get(url_message) + + async def client_loop(self): + try: + idle_packet = '{"type":"mode","mode":"idle","events":["rfid/*"]}\r\n' + self.writer.write(idle_packet.encode()) + while self.running and not self.reader.at_eof(): + line = await self.reader.readline() + if line != b"" and line != b"\r\n": + try: + packet = json.loads(line.decode("utf8")) + logging.debug(f"process nabd packet: {packet}") + await self.process_nabd_packet(packet) + except json.decoder.JSONDecodeError as e: + logging.error( + f"Invalid JSON packet from nabd: {line}\n{e}" + ) + self.writer.close() + await self.writer.wait_closed() + except KeyboardInterrupt: + pass + finally: + if self.running: + self.loop.stop() + +if __name__ == "__main__": + NabRfid2server.main(sys.argv[1:]) diff --git a/nabrfid2server/nabrfid2server.service b/nabrfid2server/nabrfid2server.service new file mode 100644 index 00000000..887495cf --- /dev/null +++ b/nabrfid2server/nabrfid2server.service @@ -0,0 +1,16 @@ +[Unit] +Description=Nabaztag Rfid to URL sender daemon +After=nabd.service +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +RestartSec=1 +User=root +WorkingDirectory=/home/pi/pynab +ExecStart=/home/pi/pynab/venv/bin/python -m nabrfid2server.nabrfid2server +PIDFile=/run/nabrfid2server.pid + +[Install] +WantedBy=multi-user.target diff --git a/nabrfid2server/templates/nabrfid2server/settings.html b/nabrfid2server/templates/nabrfid2server/settings.html new file mode 100644 index 00000000..c08d862b --- /dev/null +++ b/nabrfid2server/templates/nabrfid2server/settings.html @@ -0,0 +1,101 @@ +{% load i18n %} +
+
+ {% csrf_token %} +
+
{% trans "RFID to Server" %}
+
+
+
+

{% trans "Tags can be transmitted to a remote server by URL." %}

+

{% trans "Setup below the transmission mode that suits for you" %}

+

{% trans "Setup also the url of your server. You can include, where you need in your url the following tags:
#RFID_TAG# : uid of the tag
#RFID_STATE# : state of the tag (detected, removed)
#RFID_FLAGS# : supported, formatted,etc.
#RFID_APP# : App called by a formatted tag
#RFID_PACK# : the whole RFID packet received
#RFID_JEEPACK# : compatible RFID_PACK for Jeedom" %}

+ +
+ + +
+
+
+ {% trans "URL of your server:" %} +
+ +
+
+
+
+ +
+
+
+ +
+ +
diff --git a/nabrfid2server/urls.py b/nabrfid2server/urls.py new file mode 100644 index 00000000..a089a7fb --- /dev/null +++ b/nabrfid2server/urls.py @@ -0,0 +1,6 @@ +from django.urls import path +from .views import SettingsView + +urlpatterns = [ + path("settings", SettingsView.as_view()), +] diff --git a/nabrfid2server/views.py b/nabrfid2server/views.py new file mode 100644 index 00000000..18bb3585 --- /dev/null +++ b/nabrfid2server/views.py @@ -0,0 +1,30 @@ +from django.shortcuts import render +from django.views.generic import TemplateView +from django.http import JsonResponse +from .models import Config +from .nabrfid2server import NabRfid2server + +class SettingsView(TemplateView): + template_name = "nabrfid2server/settings.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["config"] = Config.load() + return context + + def post(self, request, *args, **kwargs): + config = Config.load() + config.rfid_2_server_test = request.POST["rfid_2_server_test"] == "true" + config.rfid_2_server_mode = int(request.POST["rfid_2_server_mode"]) + config.rfid_2_server_url = request.POST["rfid_2_server_url"] + config.save() + NabRfid2server.signal_daemon() + context = super().get_context_data(**kwargs) + context["config"] = config + return render(request, SettingsView.template_name, context=context) + + def put(self, request, *args, **kwargs): + config = Config.load() + config.save() + NabRfid2server.signal_daemon() + return JsonResponse({"status": "ok"}) diff --git a/nabweb/settings.py b/nabweb/settings.py index 9999ba89..7f79912e 100644 --- a/nabweb/settings.py +++ b/nabweb/settings.py @@ -50,6 +50,7 @@ "nabtaichid", "nabweatherd", "nabairqualityd", + "nabrfid2server", "nabweb", ] @@ -160,4 +161,4 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/2.1/howto/static-files/ -STATIC_URL = "/static/" +STATIC_URL = "/static/" \ No newline at end of file