Skip to content

Commit

Permalink
KALEOFR: implementing nabookd with RFID as trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
kaleofr authored and Commit-La-Grenouille committed Apr 6, 2022
1 parent 4012a0d commit 40b1160
Show file tree
Hide file tree
Showing 14 changed files with 352 additions and 4 deletions.
6 changes: 3 additions & 3 deletions nabd/rfid.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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(
Expand Down
1 change: 1 addition & 0 deletions nabrfid2server/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NABAZTAG_SERVICE_PRIORITY = 11
5 changes: 5 additions & 0 deletions nabrfid2server/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class Nabrfid2serverConfig(AppConfig):
name = "nabrfid2server"
Binary file added nabrfid2server/locale/fr_FR/LC_MESSAGES/django.mo
Binary file not shown.
80 changes: 80 additions & 0 deletions nabrfid2server/locale/fr_FR/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
@@ -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 <EMAIL@ADDRESS>, 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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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:<br>#RFID_TAG# : uid of the tag"
"<br>#RFID_STATE# : state of the tag (detected, removed)"
"<br>#RFID_FLAGS# : supported, formatted,etc."
"<br>#RFID_APP# : App called by a formatted tag"
"<br>#RFID_PACK# : the whole RFID packet received"
"<br>#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:<br>#RFID_TAG# : uid du tag RFID"
"<br>#RFID_STATE# : état du tag (detected, removed)"
"<br>#RFID_FLAGS# : supported, formatted,etc."
"<br>#RFID_APP# : Application appelée par un tag programmé"
"<br>#RFID_PACK# : le paquet RFID reçu, au complet"
"<br>#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"
23 changes: 23 additions & 0 deletions nabrfid2server/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -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=&#34;#RFID_TAG#&#34;%20etat=&#34;#RFID_STATE#&#34;%20flags=#34;#RFID_FLAGS##34;%20app=#34;#RFID_APP##34;')),
],
),
]
Empty file.
11 changes: 11 additions & 0 deletions nabrfid2server/models.py
Original file line number Diff line number Diff line change
@@ -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=&#34;#RFID_TAG#&#34;%20etat=&#34;#RFID_STATE#&#34;%20flags=#34;#RFID_FLAGS##34;%20app=#34;#RFID_APP##34;")

class Meta:
app_label = "nabrfid2server"
74 changes: 74 additions & 0 deletions nabrfid2server/nabrfid2server.py
Original file line number Diff line number Diff line change
@@ -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:])
16 changes: 16 additions & 0 deletions nabrfid2server/nabrfid2server.service
Original file line number Diff line number Diff line change
@@ -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
101 changes: 101 additions & 0 deletions nabrfid2server/templates/nabrfid2server/settings.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
{% load i18n %}
<div class="card" id="nabrfid2server-settings">
<form action="/nabrfid2server/settings">
{% csrf_token %}
<div class="card-header">
<h5 class="card-title">{% trans "RFID to Server" %}</h5>
</div>
<div class="card-body">
<div class="form-group row">
<p>{% trans "Tags can be transmitted to a remote server by URL." %}</p>
<p>{% trans "Setup below the transmission mode that suits for you" %}</p>
<p>{% trans "Setup also the url of your server. You can include, where you need in your url the following tags:<br>#RFID_TAG# : uid of the tag<br>#RFID_STATE# : state of the tag (detected, removed)<br>#RFID_FLAGS# : supported, formatted,etc.<br>#RFID_APP# : App called by a formatted tag<br>#RFID_PACK# : the whole RFID packet received<br>#RFID_JEEPACK# : compatible RFID_PACK for Jeedom" %}</p>
<label for="modeSelect" class="col-6 col-form-label">{% trans "URL Send Option" %}</label>
<div class="col-6">
<input id="rfid_2_server_test" name="rfid_2_server_test" type="hidden" value="false" />
<select name="rfid_2_server_mode" id="modeSelect">
<option value="0"{% if config.rfid_2_server_mode == 0 %} selected{% endif %}>{% trans "Never send the tag" %}</option>
<option value="1"{% if config.rfid_2_server_mode == 1 %} selected{% endif %}>{% trans "Only for unknown tag" %}</option>
<option value="2"{% if config.rfid_2_server_mode == 2 %} selected{% endif %}>{% trans "Always send the tag" %}</option>
</select>
</div>
<div class="input-group input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text">{% trans "URL of your server:" %}</span>
</div>
<input name="rfid_2_server_url" type="text" class="form-control" id="rfid_2_server_urlSelect" size="150" value="{{ config.rfid_2_server_url }}"/>
</div>
</div>
<div class="form-group row">
<div class="offset-sm-6 col-sm-6">
<button type="button" class="btn btn-primary now-button">{% trans "Test me now!" %}</button>
</div>
</div>
</div>
<div class="card-footer">
<div class="row mb-2">
<div class="col-12">
<button type="submit" class="btn btn-primary disabled ml-2 float-right save-button">{% trans "Save" %}</button>
<button type="reset" class="btn btn-outline-primary disabled ml-2 float-right reset-button">{% trans "Reset" %}</button>
</div>
</div>
</div>
</form>
<script type="text/javascript">
$(function() {
var form = $('#nabrfid2server-settings form');
var saveBtn = form.find('button.save-button');
var resetBtn = form.find('button.reset-button');
var nowBtn = form.find('button.now-button');
var url = form.attr('action');
form.find('select').on('change', function() {
saveBtn.removeClass('disabled');
resetBtn.removeClass('disabled');
});
form.find('input').on('change', function() {
saveBtn.removeClass('disabled');
resetBtn.removeClass('disabled');
});
form.on('submit', function() {
var formdata = form.serialize();
//window.alert(formdata);
$.ajax({
url: url,
method: "POST",
data: formdata,
success: function (data) {
$("#nabrfid2server-settings").replaceWith(data);
}
});
return false;
});
resetBtn.on("click", function() {
$.get(url, function(data) {
$("#nabrfid2server-settings").replaceWith(data);
});
});
nowBtn.on("click", function() {
nowBtn.addClass('disabled');
document.getElementById("rfid_2_server_test").value = "true";
var formdata = form.serialize();
//window.alert(formdata);
$.ajax({
url: url,
method: "POST",
data: formdata,
success: function (data) {
$("#nabrfid2server-settings").replaceWith(data);
}
});
document.getElementById("rfid_2_server_testurl").value = "false";
nowBtn.removeClass('disabled');
return false;
});
resetBtn.on("click", function() {
$.get(url, function(data) {
$("#nabrfid2server-settings").replaceWith(data);
});
});
});
</script>
</div>
6 changes: 6 additions & 0 deletions nabrfid2server/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.urls import path
from .views import SettingsView

urlpatterns = [
path("settings", SettingsView.as_view()),
]
30 changes: 30 additions & 0 deletions nabrfid2server/views.py
Original file line number Diff line number Diff line change
@@ -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"})
3 changes: 2 additions & 1 deletion nabweb/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"nabtaichid",
"nabweatherd",
"nabairqualityd",
"nabrfid2server",
"nabweb",
]

Expand Down Expand Up @@ -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/"

0 comments on commit 40b1160

Please sign in to comment.