''' Created on 22 août 2022 @author: denis ''' import logging import threading from . import gpiolib as gpio logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) class DeviceRegister: def __init__(self, register:dict): """ register must contain {'dev_type': 'None', 'index': 0, 'key': 'default', 'label': 'Default label', 'status': 0, 'active': 1} """ self.register = register.copy() @property def dev_type(self): return self.register.get('dev_type') @property def status(self): return self.register.get('status') @status.setter def status(self, v): self.register['status'] = int(v) @property def active_pin(self): return self.register.get('active') @property def key(self): return self.register.get('key') @property def label(self): return self.register.get('label') @property def index(self): return self.register.get('index') class Device(DeviceRegister): def __init__(self, pin, register=None, sens=gpio.IO_OUTPUT, initial=None, callback=None, edge=gpio.IO_FALLING, bouncetime=500, pull_up_down=None): super().__init__(register) self.pin = gpio.Pin(pin, sens=sens, initial=initial, callback=callback, edge=edge, bouncetime=bouncetime, pull_up_down=pull_up_down) self.sens = sens self.active = gpio.IO_HIGH if self.active_pin else gpio.IO_LOW self.not_active = gpio.IO_LOW if self.active_pin else gpio.IO_HIGH self.is_opened = self.is_on self.is_closed = self.is_off self.open = self.on self.close = self.off if self.sens == gpio.IO_OUTPUT: if initial==gpio.IO_HIGH: self.on() elif initial==gpio.IO_LOW: self.off() def state(self): return self.pin.read() def on(self): if self.sens == gpio.IO_OUTPUT: return self.pin.write(self.active) def off(self): if self.sens == gpio.IO_OUTPUT: return self.pin.write(self.not_active) def is_on(self): return self.state() == self.active def is_off(self): return self.state() == self.not_active def toggle(self): if self.is_on(): return self.off() if self.is_off(): return self.on() class Led(Device): def __init__(self, pin, register=None, initial=gpio.IO_LOW): super().__init__(pin, register=register, sens=gpio.IO_OUTPUT, initial=initial) class Relay(Device): def __init__(self, pin, register=None, initial=gpio.IO_LOW): super().__init__(pin, register=register, sens=gpio.IO_OUTPUT, initial=initial) class Switch(Device): def __init__(self, pin, register=None, callback=None, edge=gpio.IO_BOTH): super().__init__(pin, register=register, callback=callback, sens=gpio.IO_INPUT, edge=edge) def on(self): pass def off(self): pass class Button(Device): def __init__(self, pin, register=None, callback=None, bouncetime=500): super().__init__(pin, register=register, callback=callback, sens=gpio.IO_INPUT, edge=gpio.IO_FALLING, bouncetime=bouncetime) self._state = self.not_active def state(self): return self._state def on(self): self._state = self.active def off(self): self._state = self.not_active class InputDevice(Device): def __init__(self, pin, register=None, callback=None, pull_up_down=gpio.IO_PULL_UP): super().__init__(pin, register=register, callback=callback, sens=gpio.IO_INPUT, edge=gpio.IO_FALLING, pull_up_down=pull_up_down) def on(self): pass def off(self): pass class RelayFromShiftOut(DeviceRegister): def __init__(self, shift_out_register, register=None, relay_timeout=0, closed=True): super().__init__(register) self.shift_out_register = shift_out_register self.max_index = shift_out_register.datalen self.active = gpio.IO_HIGH if self.active_pin else gpio.IO_LOW self.not_active = gpio.IO_LOW if self.active_pin else gpio.IO_HIGH self.relay_timeout = 0 self.is_opened = self.is_on self.is_closed = self.is_off self.open = self.on self.close = self.off if closed: self.off() else: self.on() self.relay_timeout = relay_timeout logger.info(f'RelayShiftOut Init index {self.index}') def wait_after_event(self, timeout): if timeout: threading.Event().wait(timeout) def on(self): self.status = self.shift_out_register.set(self.index, self.active) self.wait_after_event(self.relay_timeout) # wait after opening logger.info(f'RelayShiftOut {self.index} on') return self.status def off(self): self.status = self.shift_out_register.set(self.index, self.not_active) self.wait_after_event(self.relay_timeout) # wait after closing logger.info(f'RelayShiftOut {self.index} off') return self.status def is_on(self): self.status = self.shift_out_register.get(self.index) == self.active return self.status def is_off(self): self.status = self.shift_out_register.get(self.index) == self.not_active return self.status def toggle(self): if self.is_on(): return self.off() if self.is_off(): return self.on()