Odoo IotBox allows to connect an external scale to Odoo. Unfortunately, altough infrastructure is coded to easily implement additional drivers, only drivers for two protocols are provided out-of-the-box ( Mettled Toledo 8217 and Adam AZExtra)
If you want to code your own driver, you will need to study your scale protocol, write a new python file and put in the drivers directory of the IotBox (/root_bypass_ramdisks/home/pi/odoo/addons/hw_drivers/iot_handlers/drivers/
for IotBox 21.10).
For example:
from collections import namedtuple
import logging
import re
import serial
import threading
import time
from odoo import http
from odoo.addons.hw_drivers.controllers.proxy import proxy_drivers
from odoo.addons.hw_drivers.event_manager import event_manager
from odoo.addons.hw_drivers.iot_handlers.drivers.SerialBaseDriver import SerialDriver, SerialProtocol, serial_connection
from odoo.addons.hw_drivers.iot_handlers.drivers.SerialScaleDriver import ScaleDriver
_logger = logging.getLogger(__name__)
# Only needed to ensure compatibility with older versions of Odoo
ACTIVE_SCALE = None
new_weight_event = threading.Event()
ScaleProtocol = namedtuple('ScaleProtocol', SerialProtocol._fields + ('zeroCommand', 'tareCommand', 'clearCommand', 'autoResetWeight'))
KernDEProtocol = ScaleProtocol(
name='Kern DE test driver',
baudrate=9600,
bytesize=serial.EIGHTBITS,
stopbits=serial.STOPBITS_ONE,
parity=serial.PARITY_NONE,
timeout=1,
writeTimeout=1,
measureRegexp=b"^[\sM][\s-]\s*([0-9.]+)\skg",
statusRegexp=None,
commandDelay=0.2,
measureDelay=0.5,
newMeasureDelay=0.2,
commandTerminator=b'',
measureCommand=b'w',
zeroCommand=None,
tareCommand=b't',
clearCommand=None,
emptyAnswerValid=False,
autoResetWeight=False,
)
class KernDEDriver(ScaleDriver):
"""Driver for the Kern DE serial scale."""
_protocol = KernDEProtocol
def __init__(self, identifier, device):
super(KernDEDriver, self).__init__(identifier, device)
self.device_manufacturer = 'Kern'
@classmethod
def supported(cls, device):
"""Checks whether the device, which port info is passed as argument, is supported by the driver.
:param device: path to the device
:type device: str
:return: whether the device is supported by the driver
:rtype: bool
"""
protocol = cls._protocol
try:
with serial_connection(device['identifier'], protocol, is_probing=True) as connection:
_logger.info('Try... device %s with protocol %s' % (device, protocol.name))
connection.write(b'w' + protocol.commandTerminator)
time.sleep(protocol.commandDelay)
answer = connection.read(18)
_logger.info('Answer: [%s] from device %s with protocol %s' % (answer, device, protocol.name))
if answer.find(b' kg \r\n')!=-1:
_logger.info('OK %s with protocol %s' % (device, protocol.name))
return True
except serial.serialutil.SerialTimeoutException:
_logger.exception('Serial Timeout %s with protocol %s' % (device, protocol.name))
pass
except Exception:
_logger.exception('Error while probing %s with protocol %s' % (device, protocol.name))
return False
Key parts of the above code are:
- protocol details (baudrate, bytesize, stopbits, parity)
- codes to write to the scale to read, zero, or tare (measureCommand, zeroCommand, tareCommand)
- regex expression to capture the response (measureRegexp)
- function
supported
that will be launched at start of odoo service and is needed to identify the scale model. If all identifications available fail (or the scale is powered off on the startup cycle of the IotBox), the scale will be marked by IotBox as as Adam AZExtra
You can take a look at https://github.com/ellery-it/odoo-serial-scale-drivers for more details and examples for two Kern scales
Disclaimer: I am the owner of the odoo-serial-scale-drivers github page