[IMP] iot: Enable multiple printing per report via WebSocket
-Implemented a WebSocket service to facilitate communication with the IoT box. This enables printing reports on a network different from the browser. Before it was a long polling connection -Implemented the ability to link multiple printers to a single report. Before it was possible to link only one printer er report -When multiple printers are linked, a pop-up will prompt the user to select the preferred printers. -The user's printer selection will be stored in the browser's local storage. -Additionally, a reset button has been added to clear the printer selection. task-3193258 closes odoo/odoo#129164 Related: odoo/enterprise#44398 Signed-off-by: Quentin Lejeune (qle) <qle@odoo.com>
This commit is contained in:
@@ -9,3 +9,4 @@ from . import exception_logger
|
||||
from . import http
|
||||
from . import interface
|
||||
from . import main
|
||||
from . import websocket_client
|
||||
|
||||
@@ -10,6 +10,7 @@ import time
|
||||
import urllib3
|
||||
|
||||
from odoo.addons.hw_drivers.tools import helpers
|
||||
from odoo.addons.hw_drivers.websocket_client import WebsocketClient
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -25,7 +26,7 @@ iot_devices = {}
|
||||
|
||||
|
||||
class Manager(Thread):
|
||||
def send_alldevices(self):
|
||||
def send_alldevices(self, iot_client):
|
||||
"""
|
||||
This method send IoT Box and devices informations to Odoo database
|
||||
"""
|
||||
@@ -57,7 +58,7 @@ class Manager(Thread):
|
||||
urllib3.disable_warnings()
|
||||
http = urllib3.PoolManager(cert_reqs='CERT_NONE')
|
||||
try:
|
||||
http.request(
|
||||
resp = http.request(
|
||||
'POST',
|
||||
server + "/iot/setup",
|
||||
body=json.dumps(data).encode('utf8'),
|
||||
@@ -66,6 +67,7 @@ class Manager(Thread):
|
||||
'Accept': 'text/plain',
|
||||
},
|
||||
)
|
||||
iot_client.iot_channel = json.loads(resp.data).get('result', '')
|
||||
except Exception as e:
|
||||
_logger.error('Could not reach configured server')
|
||||
_logger.error('A error encountered : %s ' % e)
|
||||
@@ -85,9 +87,10 @@ class Manager(Thread):
|
||||
_logger.warning("An error happened when trying to get the HTTPS certificate: %s",
|
||||
certificate_details)
|
||||
|
||||
iot_client = WebsocketClient(helpers.get_odoo_server_url())
|
||||
# We first add the IoT Box to the connected DB because IoT handlers cannot be downloaded if
|
||||
# the identifier of the Box is not found in the DB. So add the Box to the DB.
|
||||
self.send_alldevices()
|
||||
self.send_alldevices(iot_client)
|
||||
helpers.download_iot_handlers()
|
||||
helpers.load_iot_handlers()
|
||||
|
||||
@@ -100,6 +103,8 @@ class Manager(Thread):
|
||||
except Exception as e:
|
||||
_logger.error("Error in %s: %s", str(interface), e)
|
||||
|
||||
#Setup the websocket connection
|
||||
iot_client.start()
|
||||
# Check every 3 secondes if the list of connected devices has changed and send the updated
|
||||
# list to the connected DB.
|
||||
self.previous_iot_devices = []
|
||||
@@ -107,7 +112,7 @@ class Manager(Thread):
|
||||
try:
|
||||
if iot_devices != self.previous_iot_devices:
|
||||
self.previous_iot_devices = iot_devices.copy()
|
||||
self.send_alldevices()
|
||||
self.send_alldevices(iot_client)
|
||||
time.sleep(3)
|
||||
except Exception:
|
||||
# No matter what goes wrong, the Manager loop needs to keep running
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
import websocket
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import urllib3
|
||||
|
||||
from threading import Thread
|
||||
from odoo.addons.hw_drivers import main
|
||||
from odoo.addons.hw_drivers.tools import helpers
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
def send_to_controller(print_id, device_identifier):
|
||||
server = helpers.get_odoo_server_url()
|
||||
try:
|
||||
urllib3.disable_warnings()
|
||||
http = urllib3.PoolManager(cert_reqs='CERT_NONE')
|
||||
http.request(
|
||||
'POST',
|
||||
server + "/iot/printer/status",
|
||||
body=json.dumps(
|
||||
{'params': {
|
||||
'print_id': print_id,
|
||||
'device_identifier': device_identifier,
|
||||
}}).encode('utf8'),
|
||||
headers={
|
||||
'Content-type': 'application/json',
|
||||
'Accept': 'text/plain',
|
||||
},
|
||||
)
|
||||
except Exception as e:
|
||||
_logger.error('Could not reach configured server')
|
||||
_logger.error('A error encountered : %s ', e)
|
||||
|
||||
|
||||
def on_message(ws, messages):
|
||||
"""
|
||||
When a message is receive, this function is triggered
|
||||
The message is load and if its type is 'print', is sent to the printer
|
||||
"""
|
||||
messages = json.loads(messages)
|
||||
for document in messages:
|
||||
if (document['message']['type'] == 'print'):
|
||||
payload = document['message']['payload']
|
||||
if helpers.get_mac_address() in payload['iotDevice']['iotIdentifiers']:
|
||||
#send box confirmation
|
||||
for device in payload['iotDevice']['identifiers']:
|
||||
if device['identifier'] in main.iot_devices:
|
||||
main.iot_devices[device["identifier"]]._action_default(payload)
|
||||
send_to_controller(payload['print_id'], device['identifier'])
|
||||
|
||||
|
||||
def on_error(ws, error):
|
||||
_logger.error(error)
|
||||
|
||||
class WebsocketClient(Thread):
|
||||
iot_channel = ""
|
||||
|
||||
def on_open(self, ws):
|
||||
"""
|
||||
When the client is setup, this function send a message to subscribe to the iot websocket channel
|
||||
"""
|
||||
ws.send(
|
||||
'{"event_name":"subscribe","data":{"channels":["' + self.iot_channel + '"],"last":0}}'
|
||||
)
|
||||
|
||||
def __init__(self, url):
|
||||
if url:
|
||||
self.url = url.replace("http", "ws")
|
||||
Thread.__init__(self)
|
||||
|
||||
def start_client(self):
|
||||
self.ws = websocket.WebSocketApp(self.url + "/websocket",
|
||||
on_open=self.on_open, on_message=on_message,
|
||||
on_error=on_error)
|
||||
while 1:
|
||||
self.ws.run_forever()
|
||||
time.sleep(10)
|
||||
|
||||
def run(self):
|
||||
self.start_client()
|
||||
@@ -119,7 +119,8 @@ PIP_TO_INSTALL="
|
||||
PyKCS11 \
|
||||
vcgencmd \
|
||||
RPi.GPIO \
|
||||
rjsmin==1.1.0"
|
||||
rjsmin==1.1.0 \
|
||||
websocket-client==1.6.3"
|
||||
|
||||
mkdir venv
|
||||
python3 -m venv venv
|
||||
|
||||
Reference in New Issue
Block a user