Skip to content

Instantly share code, notes, and snippets.

@erichiggins
Created June 28, 2022 07:49
Show Gist options
  • Select an option

  • Save erichiggins/d808c7029d101ba728826d70e315d31b to your computer and use it in GitHub Desktop.

Select an option

Save erichiggins/d808c7029d101ba728826d70e315d31b to your computer and use it in GitHub Desktop.

Revisions

  1. erichiggins created this gist Jun 28, 2022.
    84 changes: 84 additions & 0 deletions basic_scale_class.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    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)