diff --git a/booker/admin.py b/booker/admin.py index 8c38f3f..6822d8b 100644 --- a/booker/admin.py +++ b/booker/admin.py @@ -1,3 +1,4 @@ from django.contrib import admin +from .models import Scanner -# Register your models here. +admin.site.register(Scanner) diff --git a/booker/booker_fe_consumer.py b/booker/booker_fe_consumer.py new file mode 100644 index 0000000..0f7622c --- /dev/null +++ b/booker/booker_fe_consumer.py @@ -0,0 +1,54 @@ +from channels.generic.websocket import AsyncWebsocketConsumer +import json +import logging +from homelog import settings + +LOGGER = logging.getLogger(__name__) + + +class BookerFeConsumer(AsyncWebsocketConsumer): + + async def connect(self): + self.scanner_id = self.scope['url_route']['kwargs']['scanner_id'] + self.scanner_group_name = self.scanner_id + self.group_name = self.scanner_group_name + #self.group_name = settings.MQTT_CHANNEL_NAME + # join to group + await self.channel_layer.group_add(self.scanner_group_name, self.channel_name) + topic = f"barcodescanner/{self.scanner_id}/scan" + LOGGER.debug(f"send mqtt_subscribe topic {topic} to channel group {self.scanner_group_name} (my channel is {self.channel_name})") + await self.channel_layer.send(settings.MQTT_CHANNEL_NAME, { + "type": "mqtt.subscribe", + "topic": topic, + "group": self.scanner_group_name + }) + await self.accept() + + async def disconnect(self): + # leave group + await self.channel_layer.group_discard(self.group_name, self.channel_name) + LOGGER.debug(f"disconnect from channel group {self.group_name}") + + async def receive(self, text_data): + print('>>>', text_data) + msg = '{"message":"pong!"}' if text_data == '{"message":"ping"}' else text_data + print('<<<', msg) + await self.channel_layer.group_send( + self.scanner_group_name, + { + 'type': 'distribute', + 'text': msg + } + ) + + async def distribute(self, event): + valother = event['text'] + LOGGER.debug(f"distribute text={valother}") + await self.send(text_data=valother) + + async def mqtt_message(self, event): + message = event['message'] + topic = message['topic'] + payload = message['payload'] + LOGGER.debug(f"Received message with payload={payload}, topic={topic}") + await self.send(text_data=json.dumps({'message': payload, 'topic': topic})) diff --git a/booker/models.py b/booker/models.py index 71a8362..fb7ea0e 100644 --- a/booker/models.py +++ b/booker/models.py @@ -1,3 +1,18 @@ from django.db import models +from django.conf import settings +from homelog.system_user import get_deleted_user -# Create your models here. + +class Scanner(models.Model): + named_id = models.CharField(max_length=40, unique=True) + description = models.CharField(max_length=200) + lwt_topic = models.CharField(max_length=200) + last_online_ts = models.DateTimeField('last datetime this scanner has been online') + assigned_channel_name = models.CharField(max_length=200) + assigned_group_name = models.CharField(max_length=200) + created_ts = models.DateTimeField('datetime created', auto_now_add=True) + created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET(get_deleted_user), + related_name='created_scanners') + changed_ts = models.DateTimeField('datetime updated', auto_now=True) + changed_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET(get_deleted_user), + related_name='changed_scanners') diff --git a/booker/mqtt_collector.py b/booker/mqtt_collector.py deleted file mode 100644 index a49fea8..0000000 --- a/booker/mqtt_collector.py +++ /dev/null @@ -1,48 +0,0 @@ -from channels.generic.websocket import AsyncWebsocketConsumer -import json - -''' -class ScannerCollector(WebsocketConsumer): - def connect(self): - self.accept() - - def disconnect(self, close_code): - pass - - def receive(self, text_data): - text_data_json = json.loads(text_data) - message = text_data_json['message'] - - self.send(text_data=json.dumps({ - 'message': message - })) -''' - -class ScannerCollector(AsyncWebsocketConsumer): - - async def connect(self): - self.group_name = 'scanner' - # join to group - await self.channel_layer.group_add(self.group_name, self.channel_name) - await self.accept() - - async def disconnect(self): - # leave group - await self.channel_layer.group_discard(self.group_name, self.channel_name) - - async def receive(self, text_data): - print('>>>', text_data) - msg = '{"message":"pong!"}' if text_data == '{"message":"ping"}' else text_data - print('<<<', msg) - await self.channel_layer.group_send( - self.group_name, - { - 'type': 'distribute', - 'text': msg - } - ) - - async def distribute(self, event): - valother = event['text'] - await self.send(text_data=valother) - diff --git a/booker/scanner_announce_consumer.py b/booker/scanner_announce_consumer.py new file mode 100644 index 0000000..954aa8b --- /dev/null +++ b/booker/scanner_announce_consumer.py @@ -0,0 +1,77 @@ +import datetime +import logging +import re +import json +from channels.generic.websocket import AsyncWebsocketConsumer +from booker.models import Scanner +from asgiref.sync import sync_to_async +from channels.db import database_sync_to_async +from django.contrib.auth import get_user_model +from homelog.system_user import get_system_user +from homelog import settings +from django.core.exceptions import ObjectDoesNotExist + +LOGGER = logging.getLogger(__name__) + + +class ScannerAnnounceConsumer(AsyncWebsocketConsumer): + + async def connect(self): + self.group_name = 'scanner-announce' + # join to group + await self.channel_layer.group_add(self.group_name, self.channel_name) + LOGGER.debug(f"send mqtt_subscribe to channel layer {settings.MQTT_CHANNEL_NAME} to answer on channel {self.group_name} (my channel is {self.channel_name})") + await self.channel_layer.send(settings.MQTT_CHANNEL_NAME, { + "type": "mqtt.subscribe", + "topic": "barcodescanner/+/status", + "group": self.group_name + }) + LOGGER.debug("ScannerAnnounceConsumer initialized") + await self.accept() + + async def receive(self, mqtt_message): + pass + + async def disconnect(self, code): + await self.channel_layer.send(settings.MQTT_CHANNEL_NAME, { + "type": "mqtt.unsubscribe", + "topic": "barcodescanner/#/status", + "group": self.group_name + }) + LOGGER.debug(f"Disconnect from scanner-announce, unsubscribing topic; code={code}") + await self.channel_layer.group_discard(self.group_name, self.channel_name) + + async def distribute(self, event): + valother = event['text'] + await self.send(text_data=valother) + + @database_sync_to_async + def get_or_create_scanner(self, named_id, topic): + scanner, created = Scanner.objects.get_or_create(named_id=named_id, defaults={ + 'lwt_topic': topic, + 'last_online_ts': datetime.datetime.now(), + 'created_by': get_system_user(), + 'changed_by': get_system_user() + }) + if created: + LOGGER.debug(f"Created new scanner entry for {named_id}") + else: + LOGGER.debug(f"Updated scanner entry for {named_id}") + return scanner + + async def mqtt_message(self, event): + message = event['message'] + topic = message['topic'] + qos = message['qos'] + payload = message['payload'] + print('Received a message at topic: ', topic) + print('with payload ', payload) + print('and QOS ', qos) + named_id = 'invalid' + m = re.match(r'barcodescanner\/(barcodescan-[0-9,a-f]{6})\/status', topic) + if m: + named_id = m[1] + await self.send(text_data=json.dumps({'message': payload, 'scanner': named_id, 'topic': topic})) + LOGGER.debug(f"Got MQTT message from {topic} with payload {payload}") + if payload == 'Online' or payload == 'online': + scanner = await self.get_or_create_scanner(named_id=named_id, topic=topic) diff --git a/booker/templates/booker/index.html b/booker/templates/booker/index.html index 85dc6cd..4e6271c 100644 --- a/booker/templates/booker/index.html +++ b/booker/templates/booker/index.html @@ -4,21 +4,55 @@ {% block title %}Scanner Index{% endblock %} {% block content %} - What chat room would you like to enter?
-
- +
+
+

Booker

+

Choose a scanner you want to use to book assets and container into/outof containers.

+
+
+
+
- + + + +
+
+
{% endblock %} diff --git a/booker/templates/booker/scanner.html b/booker/templates/booker/scanner.html index 00c0611..f7cf5ed 100644 --- a/booker/templates/booker/scanner.html +++ b/booker/templates/booker/scanner.html @@ -7,15 +7,15 @@

- {{ scanner_id|json_script:"room-name" }} + {{ scanner_id|json_script:"scanner_id" }}