second commit
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
'''
|
||||
Devices
|
||||
|
||||
Created on 23 août 2022
|
||||
|
||||
@author: denis@e-educ.fr
|
||||
|
||||
Flow and Frequency output of the YF-S201
|
||||
|
||||
Flow(L/H) Frequency(Hz)
|
||||
120 16
|
||||
240 32.5
|
||||
360 49.3
|
||||
480 65.5
|
||||
600 82
|
||||
720 90.2
|
||||
|
||||
F = 7.5 Q Q: l/mn
|
||||
'''
|
||||
import logging, threading, random
|
||||
from modules import sensors as dev, utils, gpiolib as gpio
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
|
||||
class YF_S201(dev.InputDevice):
|
||||
waterflow_timeout = 2
|
||||
pulse_counter = 0
|
||||
start_counter = False
|
||||
stop_counter = None
|
||||
|
||||
def __init__(self, pin, register=None, publish=None):
|
||||
super().__init__(pin, register=register, callback=self.on_count_pulse, pull_up_down=gpio.IO_PULL_UP,)
|
||||
self.publish = publish
|
||||
threading.Thread(target=self.waterflow_process, args=()).start()
|
||||
|
||||
def waterflow_publish(self, flow=None):
|
||||
if self.publish is not None:
|
||||
self.publish(dict(
|
||||
uuid=self.key,
|
||||
topic="waterflow",
|
||||
ts=utils.ts_now(),
|
||||
flow=flow,
|
||||
)
|
||||
)
|
||||
|
||||
def on_count_pulse(self, channel):
|
||||
if self.start_counter:
|
||||
self.pulse_counter += 1
|
||||
|
||||
def wait_for_counts(self, timeout):
|
||||
self.pulse_counter = 0
|
||||
self.start_counter = True
|
||||
threading.Event().wait(timeout)
|
||||
self.start_counter = False
|
||||
|
||||
def waterflow_process(self):
|
||||
self.stop_counter = threading.Event()
|
||||
while not self.stop_counter.is_set():
|
||||
self.wait_for_counts(self.waterflow_timeout)
|
||||
flow = self.pulse_counter / 7.5
|
||||
if flow:
|
||||
logger.info(f'\nwaterflow_process flow = {flow}')
|
||||
self.waterflow_publish(flow)
|
||||
|
||||
def stop(self):
|
||||
self.stop_counter.set()
|
||||
|
||||
|
||||
class Relay(dev.RelayFromShiftOut):
|
||||
|
||||
def __init__(self, shift_out_register, register=None, publish=None):
|
||||
super().__init__(shift_out_register, register, relay_timeout=1.0)
|
||||
self.publish = publish
|
||||
self.start_time, self.end_time = 0, 0
|
||||
self.started = False
|
||||
self.duration_timer = threading.Event()
|
||||
self.water_flow_timer = threading.Event()
|
||||
|
||||
self.flow, self.rate = 0.00, 0.00
|
||||
self.flow_meter_start()
|
||||
self.relay_publish('init', index=self.index, label=self.label, dev_type=self.dev_type)
|
||||
|
||||
def now(self):
|
||||
return utils.ts_now_s()
|
||||
|
||||
def relay_publish(self, topic, **kwargs):
|
||||
if self.publish is not None:
|
||||
self.publish(topic, **dict(
|
||||
uuid=self.key,
|
||||
ts=utils.ts_now_s(),
|
||||
relay_state=self.is_on(),
|
||||
elapsed=self.time_elapsed(),
|
||||
remaining=self.time_remaining(),
|
||||
flow=self.flow,
|
||||
rate=self.rate,
|
||||
**kwargs
|
||||
)
|
||||
)
|
||||
|
||||
def time_elapsed(self):
|
||||
elapsed = self.now() - self.start_time
|
||||
if self.start_time <= 0 or elapsed <= 0:
|
||||
elapsed = 0
|
||||
return elapsed
|
||||
|
||||
def time_remaining(self):
|
||||
remaining = self.end_time - self.now()
|
||||
if remaining < 0:
|
||||
remaining = 0
|
||||
return remaining
|
||||
|
||||
def is_it_over(self, timeout):
|
||||
elapsed = self.now() - self.start_time
|
||||
if elapsed > timeout:
|
||||
self.duration_timer.set()
|
||||
|
||||
def _open(self, timeout):
|
||||
self.duration_timer = threading.Event()
|
||||
self.started = True
|
||||
while not self.duration_timer.is_set():
|
||||
try:
|
||||
if self.started:
|
||||
self.is_it_over(timeout)
|
||||
threading.Event().wait(1.0)
|
||||
except Exception as e:
|
||||
logger.error(f'run error {e}')
|
||||
self.start_time = 0
|
||||
self.relay_stop()
|
||||
|
||||
def relay_start(self, duration=0):
|
||||
self.start_time = self.now()
|
||||
self.end_time = self.start_time + duration
|
||||
self.open()
|
||||
if duration > 0:
|
||||
threading.Thread(target=self._open, args=(duration, )).start()
|
||||
self.rate, self.flow = 0.00, 0.00
|
||||
self.begin = self.now()
|
||||
self.water_flow_timer.set()
|
||||
self.relay_publish('start')
|
||||
|
||||
def relay_stop(self):
|
||||
self.duration_timer.set()
|
||||
self.close()
|
||||
self.started = False
|
||||
self.water_flow_timer.clear()
|
||||
self.relay_publish('stop')
|
||||
|
||||
def relay_halt(self):
|
||||
if self.is_on():
|
||||
self.started = False
|
||||
|
||||
def relay_restart(self):
|
||||
if self.is_on():
|
||||
self.started = True
|
||||
|
||||
def relay_status(self):
|
||||
self.relay_publish('status')
|
||||
|
||||
def _flow_meter(self):
|
||||
while True:
|
||||
try:
|
||||
self.water_flow_timer.wait()
|
||||
elapsed = (self.now() - self.begin)/60
|
||||
self.flow = random.randint(1050, 1065)/100 * elapsed
|
||||
self.rate = self.flow / elapsed if elapsed > 0 else 0.00
|
||||
threading.Event().wait(1.0)
|
||||
except Exception as e:
|
||||
logger.error(f'flow_meter_process error {e}')
|
||||
threading.Event().wait(1.0)
|
||||
|
||||
def flow_meter_start(self):
|
||||
self.begin = self.now()
|
||||
threading.Thread(target=self._flow_meter).start()
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user