Implemented generic setup file and VL53L3CX Sensor
This commit is contained in:
parent
b85ee8ab25
commit
16ebe4a670
7 changed files with 105 additions and 55 deletions
|
@ -1,12 +1,10 @@
|
|||
from sensors.people_counter import PeopleCounter
|
||||
from sensors.vl53l1x_sensor import VL53L1XSensor
|
||||
import logging
|
||||
from setup import sensor
|
||||
|
||||
counter = PeopleCounter(VL53L1XSensor())
|
||||
counter = PeopleCounter(sensor)
|
||||
peopleCount = 0
|
||||
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
|
||||
def countChange(change: int) -> None:
|
||||
global peopleCount
|
||||
|
|
|
@ -1,30 +1,26 @@
|
|||
from sensors import Directions, VL53L1XSensor
|
||||
from sensors import Directions
|
||||
from time import sleep
|
||||
from setup import sensor
|
||||
import logging
|
||||
|
||||
|
||||
DELAY_SECONDS = 1
|
||||
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
|
||||
sensor = VL53L1XSensor()
|
||||
sensor.open()
|
||||
|
||||
try:
|
||||
while True:
|
||||
sensor.setDirection(Directions.INSIDE)
|
||||
distance_inside = sensor.getDistance()
|
||||
|
||||
|
||||
sensor.setDirection(Directions.OUTSIDE)
|
||||
distance_outside = sensor.getDistance()
|
||||
|
||||
|
||||
logging.info("----------")
|
||||
logging.info(f"Inside: {distance_inside} cm")
|
||||
logging.info(f"Outside: {distance_outside} cm")
|
||||
|
||||
|
||||
sleep(DELAY_SECONDS)
|
||||
|
||||
|
||||
finally:
|
||||
sensor.close()
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from sensors.vl53l1x_sensor import VL53L1XSensor
|
||||
from sensors.vl53l3cx_sensor import VL53L3CXSensor
|
||||
from sensors.people_counter import PeopleCounter
|
||||
from sensors.tof_sensor import Directions
|
||||
|
|
61
src/sensors/vl53l3cx_sensor.py
Normal file
61
src/sensors/vl53l3cx_sensor.py
Normal file
|
@ -0,0 +1,61 @@
|
|||
from sensors.tof_sensor import Directions, ToFSensor
|
||||
import VL53L1X
|
||||
|
||||
# Reference: https://github.com/pimoroni/vl53l1x-python
|
||||
#
|
||||
# Left, right, top and bottom are relative to the SPAD matrix coordinates,
|
||||
# which will be mirrored in real scene coordinates.
|
||||
# (or even rotated, depending on the VM53L1X element alignment on the board and on the board position)
|
||||
#
|
||||
# ROI in SPAD matrix coords:
|
||||
#
|
||||
# 15 top-left
|
||||
# | X____
|
||||
# | | |
|
||||
# | |____X
|
||||
# | bottom-right
|
||||
# 0__________15
|
||||
#
|
||||
|
||||
|
||||
class VL53L3CXSensor(ToFSensor):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
def open(self, ranging_mode: int = 3) -> None:
|
||||
self.sensor = VL53L1X.VL53L1X(i2c_bus=1, i2c_address=0x52)
|
||||
self.sensor.open()
|
||||
self.roi = VL53L1X.VL53L1xUserRoi()
|
||||
|
||||
# Optionally set an explicit timing budget
|
||||
# These values are measurement time in microseconds,
|
||||
# and inter-measurement time in milliseconds.
|
||||
# If you uncomment the line below to set a budget you
|
||||
# should use `tof.start_ranging(0)`
|
||||
# tof.set_timing(66000, 70)
|
||||
self.ranging = ranging_mode
|
||||
# 0 = Unchanged
|
||||
# 1 = Short Range
|
||||
# 2 = Medium Range
|
||||
# 3 = Long Range
|
||||
|
||||
def setDirection(self, direction: Directions) -> None:
|
||||
"""Configure sensor to pick up the distance in a specific direction."""
|
||||
direction_roi = {
|
||||
Directions.INSIDE: VL53L1X.VL53L1xUserRoi(6, 3, 9, 0),
|
||||
Directions.OUTSIDE: VL53L1X.VL53L1xUserRoi(6, 15, 9, 12),
|
||||
}
|
||||
|
||||
self.roi = direction_roi[direction]
|
||||
|
||||
def getDistance(self) -> float:
|
||||
"""Returns new distance in cm."""
|
||||
self.sensor.set_user_roi(self.roi)
|
||||
self.sensor.start_ranging(self.ranging)
|
||||
distance = self.sensor.get_distance()
|
||||
self.sensor.stop_ranging()
|
||||
|
||||
return distance / 10
|
||||
|
||||
def close(self) -> None:
|
||||
self.sensor.close()
|
28
src/setup.py
Normal file
28
src/setup.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
from sensors import VL53L1XSensor, VL53L3CXSensor
|
||||
from datetime import time
|
||||
import logging
|
||||
|
||||
LOG_FILE_PATH = "log.txt" # Path for logs
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
sensor = VL53L3CXSensor()
|
||||
|
||||
# Should lights already turn on where there is any kind of motion in the sensor
|
||||
ENABLE_MOTION_TRIGGERED_LIGHT = True
|
||||
|
||||
# Should lights change when a certain time in the schedule is reached
|
||||
ENABLE_SCHEDULE_TRIGGERS = (
|
||||
False # Not working correctly at the moment, so turned off by default
|
||||
)
|
||||
|
||||
# Schedule (Key is time after scene should be used. Value is scene name to be used.)
|
||||
# Needs to be sorted chronologically
|
||||
SCHEDULE: dict[time, str] = {}
|
||||
|
||||
# Philips Hue configuration
|
||||
hue_conf = {
|
||||
"bridge_ip": "",
|
||||
"transition_time": 10, # seconds
|
||||
"light_group": "",
|
||||
# If file exists, application is considered 'registered' at the bridge
|
||||
"registered_file": "smart_light_registered.bridge",
|
||||
} # Custom configuration for philips hue
|
|
@ -1,28 +1,15 @@
|
|||
from datetime import datetime
|
||||
from services.philips_hue import PhilipsHue
|
||||
from sensors.people_counter import PeopleCounter
|
||||
from sensors.vl53l1x_sensor import VL53L1XSensor
|
||||
import logging
|
||||
import json
|
||||
|
||||
|
||||
LOG_FILE_PATH = "log.txt" # Path for logs
|
||||
hue_conf = {
|
||||
"bridge_ip": "",
|
||||
"transition_time": 10, # seconds
|
||||
# Light group to control
|
||||
"light_group": "",
|
||||
# If file exists, application is considered 'registered' at the bridge
|
||||
"registered_file": "smart_light_registered.bridge",
|
||||
} # Custom configuration for philips hue
|
||||
from setup import sensor, hue_conf, LOG_FILE_PATH
|
||||
|
||||
|
||||
hue: PhilipsHue = PhilipsHue(hue_conf) # Light interface
|
||||
counter: PeopleCounter = PeopleCounter(VL53L1XSensor()) # Sensor object
|
||||
counter: PeopleCounter = PeopleCounter(sensor) # Sensor object
|
||||
peopleCount: int = 0 # Global count of people on the inside
|
||||
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
|
||||
def change_cb(countChange: int, directionState: dict):
|
||||
"""Handles basic logging of event data for later analysis.
|
||||
|
|
|
@ -1,36 +1,15 @@
|
|||
from datetime import datetime, time, timedelta
|
||||
from typing import Optional
|
||||
from services.philips_hue import PhilipsHue
|
||||
from sensors import PeopleCounter, Directions, VL53L1XSensor
|
||||
import logging
|
||||
import json
|
||||
from timeloop import Timeloop
|
||||
|
||||
|
||||
# Should lights already turn on where there is any kind of motion in the sensor
|
||||
ENABLE_MOTION_TRIGGERED_LIGHT = True
|
||||
|
||||
# Should lights change when a certain time in the schedule is reached
|
||||
ENABLE_SCHEDULE_TRIGGERS = (
|
||||
False # Not working correctly at the moment, so turned off by default
|
||||
)
|
||||
|
||||
# Schedule (Key is time after scene should be used. Value is scene name to be used.)
|
||||
# Needs to be sorted chronologically
|
||||
SCHEDULE: dict[time, str] = {}
|
||||
|
||||
|
||||
LOG_FILE_PATH = "log.txt" # Path for logs
|
||||
hue_conf = {
|
||||
"bridge_ip": "",
|
||||
"transition_time": 10, # seconds
|
||||
"light_group": "",
|
||||
# If file exists, application is considered 'registered' at the bridge
|
||||
"registered_file": "smart_light_registered.bridge",
|
||||
} # Custom configuration for philips hue
|
||||
from setup import sensor, hue_conf, LOG_FILE_PATH, SCHEDULE, ENABLE_SCHEDULE_TRIGGERS
|
||||
|
||||
|
||||
hue: PhilipsHue = PhilipsHue(hue_conf) # Light interface
|
||||
counter: PeopleCounter = PeopleCounter(VL53L1XSensor()) # Sensor object
|
||||
counter: PeopleCounter = PeopleCounter(sensor) # Sensor object
|
||||
peopleCount: int = 0 # Global count of people on the inside
|
||||
motion_triggered_lights = False # Is light on because of any detected motion
|
||||
timeloop: Timeloop = Timeloop() # Used for time triggered schedule
|
||||
|
@ -55,7 +34,7 @@ def time_minus_time(time_a: time, time_b: time) -> timedelta:
|
|||
return dt_a - dt_b
|
||||
|
||||
|
||||
def get_scene_for_time(time: time) -> str:
|
||||
def get_scene_for_time(time: time) -> Optional[str]:
|
||||
"""Determines the correct scene to activate for a given time.
|
||||
|
||||
Args:
|
||||
|
@ -185,7 +164,7 @@ def trigger_change(triggerState: dict):
|
|||
motion_triggered_lights = target_light_state
|
||||
|
||||
|
||||
def set_light_scene(target_scene: str) -> bool:
|
||||
def set_light_scene(target_scene: str) -> None:
|
||||
"""Sets the lights to the given scene, but only, if lights are already on. Does not correct count if lights are in an unexpected state.
|
||||
|
||||
Args:
|
||||
|
|
Loading…
Reference in a new issue