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?
-
-
+
Choose a scanner you want to use to book assets and container into/outof containers.
+