Files
garagesensor/lib/HomieNodes/RelayNode.cpp
2020-03-08 22:49:22 +01:00

186 lines
3.3 KiB
C++

/*
* RelayNode.cpp
* Homie Node for a Relay with optional status indicator LED
*
* Version: 1.1
* Author: Lübbe Onken (http://github.com/luebbe)
*/
#include "RelayNode.hpp"
RelayNode::RelayNode(const char *name, const int relayPin, const int ledPin, const bool reverseSignal)
: HomieNode(name, "RelayNode", "actor")
{
_relayPin = relayPin;
_ledPin = ledPin;
if (reverseSignal)
{
_relayOnValue = LOW;
_relayOffValue = HIGH;
}
else
{
_relayOnValue = HIGH;
_relayOffValue = LOW;
}
advertise("on")
.setDatatype("boolean")
.settable();
advertise("timeout")
.setDatatype("integer")
.settable();
}
HomieInternals::Uptime relayUptime;
bool RelayNode::handleOnOff(const String &value)
{
if (value == "true" || value == "false" || value == "toggle")
{
if (value == "toggle")
{
bool current = getRelayState();
setRelay(!current);
}
else
setRelay(value == "true");
return true;
}
else
{
return false;
}
}
#define IS_INTEGER(s) (s == String(s.toInt()))
bool RelayNode::handleTimeout(const String &value)
{
if (IS_INTEGER(value))
{
long timeout = value.toInt();
if (timeout > 0)
{
setRelay(true, timeout);
return true;
}
}
return false;
}
bool RelayNode::handleInput(const HomieRange &range, const String &property, const String &value)
{
Homie.getLogger() << "Message: " << property << " " << value << endl;
if (property.equals("on"))
{
return handleOnOff(value);
}
else if (property.equals("timeout"))
{
return handleTimeout(value);
}
else
{
return false;
}
}
void RelayNode::printCaption()
{
Homie.getLogger() << cCaption << endl;
}
void RelayNode::setLed(bool on)
{
if (_ledPin > DEFAULTPIN)
{
digitalWrite(_ledPin, on ? LOW : HIGH); // LOW = LED on
}
}
void RelayNode::setRelay(bool on, long timeoutSecs)
{
printCaption();
if (_relayPin > DEFAULTPIN)
{
setRelayState(on);
if (on && timeoutSecs > 0)
{
_timeout = relayUptime.getSeconds() + timeoutSecs;
}
else
{
_timeout = 0;
}
sendState();
}
else
{
Homie.getLogger() << cIndent << "No Relay Pin!" << endl;
}
setLed(on);
}
void RelayNode::sendState()
{
bool on = getRelayState();
Homie.getLogger() << cIndent << "Relay is " << (on ? "on" : "off") << endl;
if (Homie.isConnected())
{
setProperty("on").send(on ? "true" : "false");
setProperty("timeout").send(String(long(_timeout)));
}
}
void RelayNode::setRelayState(bool on)
{
digitalWrite(_relayPin, on ? _relayOnValue : _relayOffValue);
}
bool RelayNode::getRelayState()
{
return digitalRead(_relayPin) == _relayOnValue;
}
void RelayNode::toggleRelay()
{
setRelay(!getRelayState());
}
void RelayNode::setupRelay()
{
pinMode(_relayPin, OUTPUT);
}
void RelayNode::setup()
{
printCaption();
Homie.getLogger() << cIndent << "Relay Pin: " << _relayPin << endl
<< cIndent << "Led Pin : " << _ledPin << endl;
if (_ledPin > DEFAULTPIN)
{
pinMode(_ledPin, OUTPUT);
setLed(false);
}
if (_relayPin > DEFAULTPIN)
{
setupRelay();
setRelay(false);
}
}
void RelayNode::loop()
{
relayUptime.update();
if ((_timeout > 0) && getRelayState() && (_timeout < relayUptime.getSeconds()))
{
setRelay(false);
}
}