You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On the side door, I've noticed a number of times where the latch sensor detection logic misses state changes. I originally wasn't sure if this was a hardware or software issue, but I tested by running a second script that just reads the latch sensor pin in a tight loop [^1] while flipping the latch sensor by hand and watching the output from both this script and rfidclient. Sure enough, on a number of occasions, I noticed state changes that rfidclient missed, even when making sure to toggle the sensor at intervals longer than the current 100ms debounce time.
I'm pretty sure that this is being caused by the current ... sub-optimal... threading when a latch sensor is present, i.e. we're already running the wiegand-reading binary and reading its STDOUT and then using new scans to notify the scan_worker daemon thread, but when I added the latch sensor, I just put that in its own daemon thread. That's using .when_pressed and .when_released callbacks on gpiozero.Button(), but RPi doesn't support (?) hardware interrupts for GPIO; under the hood, when_pressed and when_released are just using their own worker thread to poll for state changes. The result of all this is that it really doesn't play well with Python's multithreading approach and the GIL, and especially when doing network IO for the fob scans, it feels likely that we're losing short state changes from the latch sensor.
The simple solution here, which I'm starting work on soon, is to just run a separate daemon for reading latch sensor state and exposing that to Prometheus. That should solve the two immediate problems, (1) ensuring we have accurate data on when the latch is opened and closed and what state it's currently in, and (2) giving us valid data to compare against to identify when rfidclient is missing events.
That being said, with the addition of the latch sensor support, the right answer here is probably to overhaul rfidclient and move to multiprocessing, or something else that's more suited to reacting to two external inputs (wiegand reader, and latch sensor) without losing any input or state changes (even if the state changes are short in duration, as the latch sensor can be).
[1]: Test script:
#!/usr/bin/env python3
import logging
import os
from dotenv import load_dotenv
AUTH_TIMEOUT = 2
DOOR_OPEN_SECONDS = 10
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s %(levelname)s:%(name)s:%(message)s'
)
load_dotenv(dotenv_path="/etc/default/rfidclient")
CONTACT_PIN: int = int(os.getenv("CONTACT_PIN", "0"))
import gpiozero
door_contact = gpiozero.Button(
CONTACT_PIN, pull_up=True, bounce_time=0.1
)
logging.debug('Reading door contact on pin %s', CONTACT_PIN)
contact_state = door_contact.is_pressed
logging.info('Contact state is: %s', contact_state)
while True:
if (new_state := door_contact.is_pressed) != contact_state:
logging.info('Contact state changed to %s', new_state)
contact_state = new_state
The text was updated successfully, but these errors were encountered:
On the side door, I've noticed a number of times where the latch sensor detection logic misses state changes. I originally wasn't sure if this was a hardware or software issue, but I tested by running a second script that just reads the latch sensor pin in a tight loop [^1] while flipping the latch sensor by hand and watching the output from both this script and
rfidclient
. Sure enough, on a number of occasions, I noticed state changes that rfidclient missed, even when making sure to toggle the sensor at intervals longer than the current 100ms debounce time.I'm pretty sure that this is being caused by the current ... sub-optimal... threading when a latch sensor is present, i.e. we're already running the wiegand-reading binary and reading its STDOUT and then using new scans to notify the
scan_worker
daemon thread, but when I added the latch sensor, I just put that in its own daemon thread. That's using.when_pressed
and.when_released
callbacks ongpiozero.Button()
, but RPi doesn't support (?) hardware interrupts for GPIO; under the hood,when_pressed
andwhen_released
are just using their own worker thread to poll for state changes. The result of all this is that it really doesn't play well with Python's multithreading approach and the GIL, and especially when doing network IO for the fob scans, it feels likely that we're losing short state changes from the latch sensor.The simple solution here, which I'm starting work on soon, is to just run a separate daemon for reading latch sensor state and exposing that to Prometheus. That should solve the two immediate problems, (1) ensuring we have accurate data on when the latch is opened and closed and what state it's currently in, and (2) giving us valid data to compare against to identify when rfidclient is missing events.
That being said, with the addition of the latch sensor support, the right answer here is probably to overhaul rfidclient and move to multiprocessing, or something else that's more suited to reacting to two external inputs (wiegand reader, and latch sensor) without losing any input or state changes (even if the state changes are short in duration, as the latch sensor can be).
[1]: Test script:
The text was updated successfully, but these errors were encountered: