Created
June 28, 2022 07:49
-
-
Save erichiggins/d808c7029d101ba728826d70e315d31b to your computer and use it in GitHub Desktop.
Boilerplate scale class for the Open Trickler. Fill out the sections labeled with TODOs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class BasicScale: | |
"""Class for controlling a basic scale scale.""" | |
# TODO(you): Update the default values, such as baudrate, to match your scale. | |
def __init__(self, memcache, port='/dev/ttyUSB0', baudrate=19200, timeout=0.1, _version=1, **kwargs): | |
"""Controller.""" | |
self._memcache = memcache | |
self._serial = serial.Serial(port=port, baudrate=baudrate, timeout=timeout, **kwargs) | |
# Set default values, which should be overwritten quickly. | |
self.raw = b'' | |
# TODO(you): Change this to match the default unit of measure of your scale. | |
self.unit = Units.GRAINS | |
# TODO(you): Change this to match the resolution of your scale. | |
self.resolution = decimal.Decimal(0.02) | |
# TODO(you): Change this to match the default weight & resolution of your scale given the default unit. | |
self.weight = decimal.Decimal('0.00') | |
atexit.register(self._graceful_exit) | |
def _graceful_exit(self): | |
"""Graceful exit, closes serial port.""" | |
logging.debug('Closing serial port...') | |
self._serial.close() | |
def change_unit(self): | |
"""Changes the unit of weight on the scale.""" | |
logging.debug('changing weight unit on scale from: %r', self.unit) | |
# TODO(you): Change this to match the command that you can send to your | |
# scale via serial connection that will change the unit of measure. | |
# If your scale doesn't have this capability, then you can just remove | |
# or comment out the self._serial.write line below. But, this could make | |
# things buggy. Just make sure you start on the settings you want and don't | |
# change the unit within the mobile app. | |
# Send Mode button command. | |
self._serial.write(b'U\r\n') | |
# Sleep 1s and wait for change to take effect. | |
time.sleep(1) | |
# Run update fn to set latest values. | |
self.update() | |
@property | |
def is_stable(self): | |
"""Returns True if the scale is stable, otherwise False.""" | |
# TODO(you): Basic scales may not include a status. Change this to just return True. | |
return self.status == self.StatusMap.STABLE | |
def update(self): | |
"""Read from the serial port and update an instance of this class with the most recent values.""" | |
# Note: The input buffer can fill up, causing latency. Clear it before reading. | |
self._serial.reset_input_buffer() | |
raw = self._serial.readline() | |
self.raw = raw | |
logging.debug(raw) | |
try: | |
line = raw.strip().decode('utf-8') | |
except UnicodeDecodeError: | |
logging.debug('Could not decode bytes to unicode.') | |
else: | |
self._stable_unstable(line) | |
def _stable_unstable(self, line): | |
"""Update the scale when status is stable or unstable.""" | |
# TODO(you): Change this line to parse the weight value, with +/-. | |
weight = line[3:12].strip() | |
self.weight = decimal.Decimal(weight) | |
# TODO(you): Change this line to parse the unit of measure. | |
unit = line[12:15].strip() | |
self.unit = UNIT_MAP[unit] | |
resolution = {} | |
# TODO(you): Change these to match the resolutions for each unit your scale supports. | |
resolution[Units.GRAINS] = decimal.Decimal(0.02) | |
resolution[Units.GRAMS] = decimal.Decimal(0.001) | |
self.resolution = resolution[self.unit] | |
# Update memcache values. | |
self._memcache.set(constants.SCALE_STATUS, self.status) | |
self._memcache.set(constants.SCALE_WEIGHT, self.weight) | |
self._memcache.set(constants.SCALE_UNIT, self.unit) | |
self._memcache.set(constants.SCALE_RESOLUTION, self.resolution) | |
self._memcache.set(constants.SCALE_IS_STABLE, self.is_stable) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment