From f25199d66b800dca83f7fec4e186faddf398148c Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 31 Aug 2023 06:43:11 -0400 Subject: [PATCH] Minor update for v0.2.1-alpha Update install procedure. Update requirements. Remove stop_point setting, as it didn't really do anything. Configure stopping location of the vehicle with the range detector offset. --- CobraBay/bay.py | 34 +++------------------------------- CobraBay/config.py | 1 - CobraBay/detectors.py | 39 ++++++++++++++++++++++----------------- CobraBay/version.py | 2 +- README.md | 37 ++++++++++++++++++++++--------------- requirements.txt | 3 ++- 6 files changed, 50 insertions(+), 66 deletions(-) diff --git a/CobraBay/bay.py b/CobraBay/bay.py index 42a8817..e891a47 100644 --- a/CobraBay/bay.py +++ b/CobraBay/bay.py @@ -12,28 +12,6 @@ from collections import namedtuple from CobraBay.const import * -# Scan the detectors if we're asked for a property that needs a fresh and we haven't scanned recently enough. -# def scan_if_stale(func): -# @wraps(func) -# def wrapper(self, *args, **kwargs): -# time_delta = time.monotonic() - self._previous_scan_ts -# if time_delta > 1: # 1s is too long, read the sensor. -# do_scan = True -# self._logger.debug("Stale, do scan.") -# else: -# do_scan = False -# self._logger.debug("Not stale, no scan needed.") -# -# # If flag is set, read the sensor and put its value into the history. -# if do_scan: -# self._scan_detectors() -# self._previous_scan_ts = time.monotonic() -# -# # Send whichever value it is into the function. -# return func(self) -# -# return wrapper - def log_changes(func): @wraps(func) def wrapper(self, *args, **kwargs): @@ -59,7 +37,6 @@ class CBBay: def __init__(self, id, name, depth, - stop_point, motion_timeout, longitudinal, lateral, @@ -73,8 +50,6 @@ def __init__(self, id, :type name: str :param depth: Absolute distance of the bay, from the range sensor to the end. Must be a linear Quantity. :type depth: Quantity(Distance) - :param stop_point: Distance from the sensor where the vehicle should stop - :type stop_point: Quantity(Distance) :param motion_timeout: During a movement, how long the bay must be still to be considered complete. :type motion_timeout: Quantity(Time) :param system_detectors: Dictionary of detector objects available on the system. @@ -100,7 +75,6 @@ def __init__(self, id, # Save the remaining parameters. self._name = name self._depth = depth - self._stop_point = stop_point self.motion_timeout = motion_timeout self._detectors = None self._cbcore = cbcore @@ -121,9 +95,6 @@ def __init__(self, id, self._occupancy = None self._previous = {} - # Calculate the adjusted depth. - self._adjusted_depth = self._depth - self._stop_point - # Create a unit registry. self._ureg = UnitRegistry @@ -316,9 +287,10 @@ def range_pct(self): # If it's not a Quantity, just return zero. self._logger.debug("Calculating range percentage") self._logger.debug("Range value: {} ({})".format(self.range.value,type(self.range.value))) - self._logger.debug("Adjusted depth: {} ({})".format(self._adjusted_depth,type(self._adjusted_depth))) + adjusted_depth = self._depth - self._detectors[self._selected_range].offset + self._logger.debug("Adjusted depth: {}".format(adjusted_depth)) if isinstance(self.range.value, Quantity): - range_pct = self.range.value.to('cm') / self._adjusted_depth.to('cm') + range_pct = self.range.value.to('cm') / adjusted_depth.to('cm') # Singe this is dimensionless, just take the value and make it a Python scalar. range_pct = range_pct.magnitude return range_pct diff --git a/CobraBay/config.py b/CobraBay/config.py index 6d13720..47ec4c5 100644 --- a/CobraBay/config.py +++ b/CobraBay/config.py @@ -174,7 +174,6 @@ class CBConfig: 'name': { 'type': 'string' }, 'motion_timeout': { 'type': 'quantity', 'dimensionality': '[time]', 'coerce': pint.Quantity }, 'depth': { 'type': 'quantity', 'dimensionality': '[length]', 'coerce': pint.Quantity }, - 'stop_point': { 'type': 'quantity', 'dimensionality': '[length]', 'coerce': pint.Quantity }, 'longitudinal': { 'type': 'dict', 'allow_unknown': True, diff --git a/CobraBay/detectors.py b/CobraBay/detectors.py index 71508c3..0c27771 100644 --- a/CobraBay/detectors.py +++ b/CobraBay/detectors.py @@ -332,36 +332,40 @@ def value_raw(self): @property @read_if_stale def quality(self): - self._logger.debug( - "Creating quality from latest value: {} ({})".format(self._history[0][0], type(self._history[0][0]))) - self._logger.debug("90% of bay depth is: {}".format(self.bay_depth * .9)) - current_value = self._history[0][0] - self._logger.debug("Evaluating longitudinal quality for value '{}' ({})".format(current_value, type(current_value))) - self._logger.debug("Evaluation targets: Bay Depth - {}, Critical - {}, Warn - {}". - format(self.bay_depth, self._dist_crit, self._dist_warn)) - - if isinstance(current_value, Quantity): + # Pull the current value for evaluation. + current_raw_value = self.value_raw + self._logger.debug("Evaluating current raw value '{}' for quality".format(current_raw_value)) + if isinstance(self.value_raw, Quantity): + # Make an adjusted value as well. + current_adj_value = current_raw_value - self.offset # Actual reading, evaluate. - if current_value < Quantity("2 in"): + if current_raw_value < Quantity("2 in"): return DETECTOR_QUALITY_EMERG - elif (self.bay_depth * 0.90) <= current_value: + elif (self.bay_depth * 0.90) <= current_raw_value: + # Check the actual distance. If more than 90% of the bay distance is clear, probably nothing there. self._logger.debug( "Reading is more than 90% of bay depth ({})".format(self.bay_depth * .9)) return DETECTOR_QUALITY_NOOBJ # Now consider the adjusted values. - elif current_value < 0 and abs(current_value) > self.spread_park: + elif current_adj_value < 0 and abs(current_adj_value) > self.spread_park: + # Overshot stop point and too far to be considered an okay park, backup. return DETECTOR_QUALITY_BACKUP - elif abs(current_value) < self.spread_park: + elif abs(current_adj_value) < self.spread_park: + # Just short of stop point, but within allowed range, parked. return DETECTOR_QUALITY_PARK - elif current_value <= self._dist_crit: + elif current_adj_value <= self._dist_crit: + # Within critical range, this is "final" return DETECTOR_QUALITY_FINAL - elif current_value <= self._dist_warn: + elif current_adj_value <= self._dist_warn: + # within warning range, this is "base" return DETECTOR_QUALITY_BASE else: + # Too far to be in another status, but reading something, so this is the general 'OK' state. return DETECTOR_QUALITY_OK - elif current_value == SENSOR_VALUE_WEAK: + # Handle non-Quantity values from the reading. + elif current_raw_value == SENSOR_VALUE_WEAK: return DETECTOR_QUALITY_DOOROPEN - elif current_value in (SENSOR_VALUE_FLOOD, SENSOR_VALUE_STRONG): + elif current_raw_value in (SENSOR_VALUE_FLOOD, SENSOR_VALUE_STRONG): return DETECTOR_NOREADING else: return GEN_UNKNOWN @@ -447,6 +451,7 @@ def bay_depth(self): @check_ready def bay_depth(self, depth): self._bay_depth = self._convert_value(depth) + self._adjusted_bay_depth = self._bay_depth - self.offset @property def spread_park(self): diff --git a/CobraBay/version.py b/CobraBay/version.py index eb507a6..7257cd1 100644 --- a/CobraBay/version.py +++ b/CobraBay/version.py @@ -1 +1 @@ -__version__ = "0.2.0-alpha" \ No newline at end of file +__version__ = "0.2.1-alpha" \ No newline at end of file diff --git a/README.md b/README.md index 8986c3b..de3023c 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,18 @@ Raspberry Pi OS Lite 64-bit. Any other Pi with Raspberry Pi OS should work. * Serial port hardware enabled -> YES * reboot (should prompt when done) -### CobraBay +### Install CobraBay + +Note: I have not yet made this a PIPable repository. Maybe some day. For now, you need to download the package manually +and do a local install. +* Login as 'pi' +* Download the [latest release](https://github.com/chrisgilldc/cobrabay/releases/latest) and extract. + ```wget https://github.com/chrisgilldc/cobrabay/archive/refs/tags/v0.2.0-alpha.tar.gz``` +* Extract the archive. + ```tar -xzf v0.2.0-alpha.tar.gz``` +* PIP install for the Pi user from the archive + ```pip install --user ./v0.2.0-alpha.tar.gz``` -* Copy 'cobrabay' to _device_/lib/cobrabay -* Copy 'code.py' to _device_/code.py ### Hardware System has been built and tested with the following hardware: @@ -200,7 +208,6 @@ future multiple bays may be possible. | name | No | str | Bay ID | Friendly name of the bay, used for Home Assistant discovery. If not defined, defaults to the bay ID. | | motion_timeout | Yes | time quantity | None | After this amount of time, consider a dock or undock complete. Prevents premature termination. | | depth | Yes | distance quantity | None | Total distance from the longitudinal sensor point to the garage door. | -| stop_point | Yes | distance quantity | None | Where the vehicle should stop, as distance from the longitudinal sensor point. | | longitudinal | Yes | dict | None | Longitudinal detectors for this bay. | | lateral | Yes | dict | None | Lateral detectors for this bay. | @@ -215,17 +222,17 @@ Within each role, settings are prioritized like so: -| Options | Required? | Defaultable? | Valid Options | Default | Lat | Long | Description | -|-------------|-----------|--------------|-------------------|---------|-----|------|---------------------------------------------------------------------------------------------| -| offset | No | Yes | distance quantity | 0" | Yes | Yes | Where the zero-point for this detector should be. | -| pct_warn | No | Yes | number | 70 | No | Yes | Switch to 'warn' once this percentage of the bay distance is covered | -| pct_crit | No | Yes | number | 90 | No | Yes | Switch to 'crit' once this percentage of the bay distance is covered | -| spread_park | No | Yes | distance quantity | 2" | No | Yes | Maximum deviation from the stop point that can still be considered "OK" | -| spread_ok | No | Yes | distance quantity | 1" | Yes | No | Maximum deviation from the offset point that can still be considered "OK" | -| spread_warn | No | Yes | distance_quantity | 3" | Yes | No | Maximum deviation from the offset point that be considered a "WARN" | -| limit | No | Yes | distance_quantity | 96" | Yes | No | Reading limit of the lateral sensor. Any reading beyond this will be treated as "no_object" | -| side | Yes | Yes | L, R | None | Yes | No | Which side of the bay, looking out the garage door, the detector is mounted on. | -| intercept | Yes | No | distance_quantity | None | Yes | No | Absolute distance from the longitudinal detector where this detector crosses the bay. | +| Options | Required? | Defaultable? | Valid Options | Default | Lat | Long | Description | +|-------------|-----------|--------------|-------------------|---------|-----|------|---------------------------------------------------------------------------------------------------------------------------------| +| offset | No | Yes | distance quantity | 0" | Yes | Yes | Where the zero-point for this detector should be. On Longitudinal sensors, the offset indicates where the vehicle should stop. | +| pct_warn | No | Yes | number | 70 | No | Yes | Switch to 'warn' once this percentage of the bay distance is covered | +| pct_crit | No | Yes | number | 90 | No | Yes | Switch to 'crit' once this percentage of the bay distance is covered | +| spread_park | No | Yes | distance quantity | 2" | No | Yes | Maximum deviation from the stop point that can still be considered "OK" | +| spread_ok | No | Yes | distance quantity | 1" | Yes | No | Maximum deviation from the offset point that can still be considered "OK" | +| spread_warn | No | Yes | distance_quantity | 3" | Yes | No | Maximum deviation from the offset point that be considered a "WARN" | +| limit | No | Yes | distance_quantity | 96" | Yes | No | Reading limit of the lateral sensor. Any reading beyond this will be treated as "no_object" | +| side | Yes | Yes | L, R | None | Yes | No | Which side of the bay, looking out the garage door, the detector is mounted on. | +| intercept | Yes | No | distance_quantity | None | Yes | No | Absolute distance from the longitudinal detector where this detector crosses the bay. | diff --git a/requirements.txt b/requirements.txt index 1aa586e..47612bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,4 +13,5 @@ gpiozero~=1.6.2 rpi_bad_power pyserial~=3.5 pid~=3.0.4 -PyYAML>=6.0 \ No newline at end of file +PyYAML>=6.0 +cerberus>=1.3.4 \ No newline at end of file