modify: IN2 DI 输入监听
This commit is contained in:
@@ -14,7 +14,6 @@
|
||||
import errno
|
||||
import glob
|
||||
import os
|
||||
import select # noqa: F401 (留给上层使用)
|
||||
import struct
|
||||
import time
|
||||
|
||||
@@ -42,9 +41,11 @@ class Backend:
|
||||
raise NotImplementedError
|
||||
|
||||
def read(self):
|
||||
"""非阻塞读一次,返回 (level, ts) 或 None。
|
||||
"""非阻塞读一次,返回本批事件列表 [(level, ts), ...];无事件返回 []。
|
||||
|
||||
level 是原始电平 0/1,尚未做 active_low 翻转。
|
||||
同一批数据里的多个事件必须全部返回,不能只留最后一个,
|
||||
否则快速抖动(一次 read 里按下+释放)会丢失中间跳变。
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -125,15 +126,15 @@ class EventBackend(Backend):
|
||||
|
||||
# ---- 读取 ----
|
||||
def read(self):
|
||||
"""返回 (level, ts) 或 None;只汇报关心的 key。"""
|
||||
"""返回 [(level, ts), ...];只汇报关心的 key,批内事件按序全部返回。"""
|
||||
if self.fd is None:
|
||||
return None
|
||||
return []
|
||||
try:
|
||||
data = os.read(self.fd, EVENT_STRUCT.size * 64)
|
||||
except OSError:
|
||||
return None
|
||||
return []
|
||||
self.buf += data
|
||||
result = None
|
||||
events = []
|
||||
while len(self.buf) >= EVENT_STRUCT.size:
|
||||
chunk = self.buf[:EVENT_STRUCT.size]
|
||||
self.buf = self.buf[EVENT_STRUCT.size:]
|
||||
@@ -147,8 +148,8 @@ class EventBackend(Backend):
|
||||
if value not in (VALUE_RELEASE, VALUE_PRESS):
|
||||
continue
|
||||
ts = sec + usec / 1e6
|
||||
result = (value, ts)
|
||||
return result
|
||||
events.append((value, ts))
|
||||
return events
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -165,6 +166,7 @@ class SysfsBackend(Backend):
|
||||
self.interval = interval
|
||||
self._cand = None
|
||||
self._cand_n = 0
|
||||
self._reported = None # 上次上报的稳定值(跳变只报一次)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
@@ -193,13 +195,14 @@ class SysfsBackend(Backend):
|
||||
|
||||
# ---- 带抗抖的读取 ----
|
||||
def read(self):
|
||||
"""返回 (level, ts) 或 None。
|
||||
"""返回 [(level, ts)];抗抖未确认或电平未变化时返回 []。
|
||||
|
||||
level 为抗抖确认后的稳定值;None 表示还没确认跳变。
|
||||
连续 debounce 次采样一致才确认稳定值;确认值与上次上报不同
|
||||
(真实跳变)才上报一次,避免稳态期间每个抗抖周期重复产出事件。
|
||||
"""
|
||||
v = self.read_raw()
|
||||
if v is None:
|
||||
return None
|
||||
return []
|
||||
ts = time.time()
|
||||
|
||||
if self._cand is None or v == self._cand:
|
||||
@@ -209,10 +212,13 @@ class SysfsBackend(Backend):
|
||||
self._cand = v
|
||||
self._cand_n = 1
|
||||
|
||||
if self._cand_n >= self.debounce:
|
||||
self._cand_n = 0 # 复位,避免重复上报
|
||||
return (int(v), ts)
|
||||
return None
|
||||
if self._cand_n < self.debounce:
|
||||
return []
|
||||
confirmed = int(v)
|
||||
if self._reported == confirmed:
|
||||
return []
|
||||
self._reported = confirmed
|
||||
return [(confirmed, ts)]
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -161,9 +161,8 @@ class DIChannel:
|
||||
break
|
||||
timeout = int(min(remain, 0.5) * 1000)
|
||||
poller.poll(timeout)
|
||||
got = self.backend.read()
|
||||
if got:
|
||||
raw, ts = got
|
||||
# read() 返回本批全部事件,按序处理,快速抖动不丢中间跳变
|
||||
for raw, ts in self.backend.read():
|
||||
if self.on_event:
|
||||
self.on_event(ts, raw)
|
||||
self._emit(self._to_level(raw), ts)
|
||||
@@ -173,13 +172,10 @@ class DIChannel:
|
||||
while not self._stop:
|
||||
if deadline and time.time() >= deadline:
|
||||
break
|
||||
got = self.backend.read()
|
||||
if got:
|
||||
raw, ts = got
|
||||
lvl = self._to_level(raw)
|
||||
for raw, ts in self.backend.read():
|
||||
if self.on_event:
|
||||
self.on_event(ts, raw)
|
||||
self._emit(lvl, ts)
|
||||
self._emit(self._to_level(raw), ts)
|
||||
time.sleep(interval)
|
||||
|
||||
def request_stop(self):
|
||||
|
||||
Reference in New Issue
Block a user