Skip to content

Commit

Permalink
Merge pull request #4 from chrisgilldc/bugfix
Browse files Browse the repository at this point in the history
Minor update for v0.2.1-alpha
  • Loading branch information
chrisgilldc committed Aug 31, 2023
2 parents 6fb4d86 + f25199d commit 7494525
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 66 deletions.
34 changes: 3 additions & 31 deletions CobraBay/bay.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -59,7 +37,6 @@ class CBBay:
def __init__(self, id,
name,
depth,
stop_point,
motion_timeout,
longitudinal,
lateral,
Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion CobraBay/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
39 changes: 22 additions & 17 deletions CobraBay/detectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):
Expand Down
2 changes: 1 addition & 1 deletion CobraBay/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.2.0-alpha"
__version__ = "0.2.1-alpha"
37 changes: 22 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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. |

Expand All @@ -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. |



Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ gpiozero~=1.6.2
rpi_bad_power
pyserial~=3.5
pid~=3.0.4
PyYAML>=6.0
PyYAML>=6.0
cerberus>=1.3.4

0 comments on commit 7494525

Please sign in to comment.