From 1d065e580db8561e1a7d1b03347860d440692f01 Mon Sep 17 00:00:00 2001 From: Dirk Jahnke Date: Mon, 28 Dec 2020 16:59:33 +0100 Subject: [PATCH] Added mqtt status message for output pins; moved output init to beginning of setup --- README.md | 31 +++++++++++++++++++++++++++---- src/main.cpp | 48 +++++++++++++++++++++++++++++++++--------------- 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 3d99f49..7799f6e 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,34 @@ Based on - Arduino Uno -- Ethernet interface +- Ethernet interface using MQTT Watchout for GPIO changes as triggers for - door bell input -- post box observer (post entry) -- post box observer (takeout posts) -- ... +- mailbox observer (post entry) +- mailbox observer (takeout posts) +- light requests (button) + +Serve outputs (using relays to trigger) for + +- turn light on at mailbox +- turn bell sound on + +MQTT messages: + +- doorBellTopic = "doorBellGW/doorbell" + --> issued when pushbutton pressed: trigger / re-trigger / release +- postboxFlapTopic = "doorBellGW/mailboxFlap" + --> issued, when flap is opened to enter mail: trigger / re-trigger / release +- postboxDoorTopic = "doorBellGW/mailboxDoor" + --> issued, when mailbox door is opened to remove mail: trigger / re-trigger / release +- doorBellTriggerSoundTopic = "doorBellGW/doorbellTrigger" + --> listens to this message and turns on relay for a short time to trigger the bell/gong +- doorLightRequestTopic = "doorBellGW/lightRequest" + --> issued, when light pushbutton is pressed: trigger / re-trigger / release; light is turned on for 30 seconds +- postboxLightTopic = "doorBellGW/light" + --> listens to this message and turns light on at mailbox for 30 seconds +- postboxLightStatusTopic = "doorBellGW/light/status" + --> issued, when light at mailbox is turned on/off: on / off + diff --git a/src/main.cpp b/src/main.cpp index 5aedadf..1c2fd43 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,8 +44,9 @@ const char *doorBellTopic = "doorBellGW/doorbell"; const char *postboxFlapTopic = "doorBellGW/mailboxFlap"; const char *postboxDoorTopic = "doorBellGW/mailboxDoor"; const char *doorBellTriggerSoundTopic = "doorBellGW/doorbellTrigger"; -const char *postboxLightTopic = "doorBellGW/light"; const char *doorLightRequestTopic = "doorBellGW/lightRequest"; +const char *postboxLightTopic = "doorBellGW/light"; +const char *postboxLightStatusTopic = "doorBellGW/light/status"; EthernetClient ethClient; EthernetServer server(80); @@ -66,7 +67,7 @@ struct { const unsigned long quietAfterTriggerFor_ms; unsigned long lastTrigger_ts; bool isTriggered; - const char *topic; + const char *topic; // sends changes: trigger / re-trigger, / release const uint8_t triggerOutputPin; } myInputs[] = { { DOOR_BELL_BUTTON_PIN, 500, 0 , false, doorBellTopic, DOOR_BELL_BUZZER_PIN }, @@ -83,9 +84,10 @@ struct { bool isTriggered; unsigned long lastTrigger_ts; const char *listenTopic; // can be triggered by mqtt message as well + const char *statusTopic; // sends on/off status } myOutputs[] = { - { DOOR_BELL_BUZZER_PIN, 500, false, 0, doorBellTriggerSoundTopic}, - { POSTBOX_LIGHT_PIN, 30000, false, 0, postboxLightTopic} + { DOOR_BELL_BUZZER_PIN, 500, false, 0, doorBellTriggerSoundTopic, NULL }, + { POSTBOX_LIGHT_PIN, 30000, false, 0, postboxLightTopic, postboxLightStatusTopic } }; #define NUM_OUTPUTS (sizeof(myOutputs) / sizeof(myOutputs[0])) @@ -109,6 +111,13 @@ void switchOutputOn(unsigned int outputNumber) { digitalWrite(myOutputs[outputNumber].pin, LOW); myOutputs[outputNumber].isTriggered = true; myOutputs[outputNumber].lastTrigger_ts = millis(); + if (myOutputs[outputNumber].statusTopic != NULL) { + sendMqttMessage(myOutputs[outputNumber].statusTopic, "on"); + } +} + +void switchOutputOffHWOnly(unsigned int outputNumber) { + digitalWrite(myOutputs[outputNumber].pin, HIGH); } void switchOutputOff(unsigned int outputNumber) { @@ -118,8 +127,11 @@ void switchOutputOff(unsigned int outputNumber) { Serial.print(myOutputs[outputNumber].pin); Serial.print(F(") topic ")); Serial.println(myOutputs[outputNumber].listenTopic); - digitalWrite(myOutputs[outputNumber].pin, HIGH); + switchOutputOffHWOnly(outputNumber); myOutputs[outputNumber].isTriggered = false; + if (myOutputs[outputNumber].statusTopic != NULL) { + sendMqttMessage(myOutputs[outputNumber].statusTopic, "off"); + } } void checkOutputAutoOff() { @@ -209,7 +221,7 @@ void reconnect() { void sendMqttMessage(const char *topic, const char *message) { reconnect(); - mqttClient.publish(topic, message); + mqttClient.publish_P(topic, message, true); } void setup() @@ -220,6 +232,20 @@ void setup() Serial.println(F("DoorbellGW Copyright (C) 2020 Dirk Jahnke")); Serial.println(F("Door Bell MQTT Gateway started.")); + // setup the input and output pins + for (unsigned int i = 0; i < NUM_INPUTS; i++) { + pinMode(myInputs[i].pin, INPUT_PULLUP); + } + + // Setup the output pins : + for (unsigned int i=0; i < NUM_OUTPUTS; ++i) { + pinMode(myOutputs[i].pin, OUTPUT); + switchOutputOffHWOnly(i); + } + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, ledState); + + // setup MQTT mqttClient.setServer(mqttServerIP, 1883); mqttClient.setCallback(mqttReceiveMessage); @@ -235,18 +261,10 @@ void setup() Serial.print(F("Please connect to http://")); Serial.println(Ethernet.localIP()); - // setup the input and output pins - for (unsigned int i = 0; i < NUM_INPUTS; i++) { - pinMode(myInputs[i].pin, INPUT_PULLUP); - } - - // Setup the output pins : + // Setup the output pins logically: for (unsigned int i=0; i < NUM_OUTPUTS; ++i) { - pinMode(myOutputs[i].pin, OUTPUT); switchOutputOff(i); } - pinMode(LED_PIN, OUTPUT); - digitalWrite(LED_PIN, ledState); }