From 457f026dfe087241d122b373d1aba7f2ec7741a3 Mon Sep 17 00:00:00 2001 From: BenjiU <46675043+BenjiU@users.noreply.github.com> Date: Sat, 4 Jan 2020 19:11:31 +0000 Subject: [PATCH] rework interrupt handling --- config.example.yml | 3 +-- config.schema.yml | 12 ++++++++---- pi_mqtt_gpio/__init__.py | 12 ++++++++---- pi_mqtt_gpio/modules/__init__.py | 6 +++--- pi_mqtt_gpio/modules/lm75.py | 3 ++- pi_mqtt_gpio/server.py | 31 ++++++++++++++++++------------- setup.py | 2 +- 7 files changed, 41 insertions(+), 28 deletions(-) diff --git a/config.example.yml b/config.example.yml index 3a21171..9fcc900 100644 --- a/config.example.yml +++ b/config.example.yml @@ -36,8 +36,7 @@ digital_inputs: - name: button_left module: raspberrypi pin: 23 - on_payload: "ON" - off_payload: "OFF" + interrupt_payload: "trigger" pullup: no pulldown: yes interrupt: falling diff --git a/config.schema.yml b/config.schema.yml index 249a326..1769fa0 100644 --- a/config.schema.yml +++ b/config.schema.yml @@ -155,12 +155,16 @@ digital_inputs: empty: no on_payload: type: string - required: yes - empty: no + required: no + default: "ON" off_payload: type: string - required: yes - empty: no + required: no + default: "OFF" + interrupt_payload: + type: string + required: no + default: "INT" pullup: type: boolean required: no diff --git a/pi_mqtt_gpio/__init__.py b/pi_mqtt_gpio/__init__.py index fade115..b390be5 100644 --- a/pi_mqtt_gpio/__init__.py +++ b/pi_mqtt_gpio/__init__.py @@ -158,12 +158,16 @@ digital_inputs: empty: no on_payload: type: string - required: yes - empty: no + required: no + default: "ON" off_payload: type: string - required: yes - empty: no + required: no + default: "OFF" + interrupt_payload: + type: string + required: no + default: "INT" pullup: type: boolean required: no diff --git a/pi_mqtt_gpio/modules/__init__.py b/pi_mqtt_gpio/modules/__init__.py index c3127b3..69fff58 100644 --- a/pi_mqtt_gpio/modules/__init__.py +++ b/pi_mqtt_gpio/modules/__init__.py @@ -1,6 +1,7 @@ import abc from enum import Enum +from time import sleep BASE_SCHEMA = { @@ -54,13 +55,12 @@ class GenericGPIO(object): def interrupt_callback(self, pin): """ - This function should not be overloaded, but be called in the ISR + This function should not be overloaded, but be registered in the ISR of the module triggering the interrupt """ - value = self.get_pin(pin) callback = self.GPIO_INTERRUPT_CALLBACK_LOOKUP[pin].get("callback") handle = self.GPIO_INTERRUPT_CALLBACK_LOOKUP[pin].get("handle") - callback(handle, pin, value) + callback(handle, pin) def cleanup(self): """ diff --git a/pi_mqtt_gpio/modules/lm75.py b/pi_mqtt_gpio/modules/lm75.py index 303e099..18bde55 100644 --- a/pi_mqtt_gpio/modules/lm75.py +++ b/pi_mqtt_gpio/modules/lm75.py @@ -1,7 +1,8 @@ from pi_mqtt_gpio.modules import GenericSensor -"""REQUIREMENTS = ("smbus",)""" +REQUIREMENTS = ("smbus",) + CONFIG_SCHEMA = { "i2c_bus_num": {"type": "integer", "required": True, "empty": False}, "chip_addr": {"type": "integer", "required": True, "empty": False}, diff --git a/pi_mqtt_gpio/server.py b/pi_mqtt_gpio/server.py index b601ace..9cb5d94 100644 --- a/pi_mqtt_gpio/server.py +++ b/pi_mqtt_gpio/server.py @@ -45,9 +45,6 @@ OUTPUT_TOPIC = "output" INPUT_TOPIC = "input" SENSOR_TOPIC = "sensor" -_LOG = logging.getLogger("mqtt_gpio") - - class CannotInstallModuleRequirements(Exception): pass @@ -607,7 +604,7 @@ def sensor_timer_thread(SENSOR_MODULES, sensor_inputs, topic_prefix): sleep(max(0, next_call - time())) -def gpio_interrupt_callback(module, pin, value): +def gpio_interrupt_callback(module, pin): try: in_conf = GPIO_INTERRUPT_LOOKUP[module][pin] except KeyError as exc: @@ -618,21 +615,21 @@ def gpio_interrupt_callback(module, pin, value): module, exc ) - _LOG.info("Input %r state changed to %r", in_conf["name"], True if value else False) + _LOG.info("Interrupt: Input %r triggered", in_conf["name"]) - # publish the value + # publish the interrupt trigger client.publish( - "%s/%s/%s" % ( - topic_prefix, OUTPUT_TOPIC, in_conf["name"] - ), - payload=in_conf["on_payload" if value else "off_payload"], - retain=in_conf["retain"] + "%s/%s/%s" % (topic_prefix, INPUT_TOPIC, in_conf["name"]), + payload=in_conf["interrupt_payload"], + retain=in_conf["retain"], ) def main(args): global digital_outputs global client + + _LOG.info("Startup") with open(args.config) as f: config = yaml.safe_load(f) @@ -642,6 +639,10 @@ def main(args): sys.exit(1) config = validator.normalized(config) + # Remove all handlers associated with the root logger object. + for handler in logging.root.handlers[:]: + logging.root.removeHandler(handler) + # and load the new config from the config file logging.config.dictConfig(config["logging"]) digital_inputs = config["digital_inputs"] @@ -739,7 +740,7 @@ def main(args): if bool(gpio.get_pin(in_conf["pin"])) != state: continue if state != LAST_STATES[in_conf["name"]]: - _LOG.info("Input %r state changed to %r", in_conf["name"], state) + _LOG.info("Polling: Input %r state changed to %r", in_conf["name"], state) client.publish( "%s/%s/%s" % (topic_prefix, INPUT_TOPIC, in_conf["name"]), payload=( @@ -775,7 +776,11 @@ def main(args): _LOG.exception("Unable to execute cleanup routine for module %r:", name) -if __name__ == "__main__": +if __name__ == "__main__": + global _LOG + logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(name)s (%(levelname)s): %(message)s') + _LOG = logging.getLogger("mqtt_gpio") + p = argparse.ArgumentParser() p.add_argument("config") args = p.parse_args() diff --git a/setup.py b/setup.py index 83334ed..99bea2c 100644 --- a/setup.py +++ b/setup.py @@ -47,7 +47,7 @@ class SchemaCommand(Command): setup( name="pi_mqtt_gpio", - version="0.3.2", + version="0.3.2i", cmdclass={"insert_schema": SchemaCommand}, packages=find_packages( exclude=[ -- GitLab