diff --git a/Makefile.am b/Makefile.am
index 6afa99a0..938c3dae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,3 +1,3 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4 -I cfg
-SUBDIRS = basic-logic comment debug function gpio light link mqtt passthrough timers tls-config variable
+SUBDIRS = basic-logic comment debug function gpio light link mqtt passthrough template timers tls-config variable
diff --git a/basic-logic/switch/MyNode.cpp b/basic-logic/switch/MyNode.cpp
index 89d84bd0..1d7c942c 100644
--- a/basic-logic/switch/MyNode.cpp
+++ b/basic-logic/switch/MyNode.cpp
@@ -76,8 +76,9 @@ void MyNode::convertType(Flows::PVariable& value, Flows::VariableType vt)
{
if(vt == Flows::VariableType::tInteger)
{
- value->setType(vt);
+ value->setType(Flows::VariableType::tInteger64);
value->integerValue = Flows::Math::getNumber(value->stringValue);
+ value->integerValue64 = value->integerValue;
}
else if(vt == Flows::VariableType::tInteger64)
{
@@ -230,6 +231,11 @@ bool MyNode::match(Rule& rule, Flows::PVariable& value)
{
try
{
+ if(value->type == Flows::VariableType::tInteger)
+ {
+ value->setType(Flows::VariableType::tInteger64);
+ value->integerValue64 = value->integerValue;
+ }
if(rule.previousValue)
{
rule.v = _previousInputValue;
diff --git a/comment/comment.hni b/comment/comment.hni
index 64fb3e28..0c3ef07b 100644
--- a/comment/comment.hni
+++ b/comment/comment.hni
@@ -22,7 +22,7 @@
diff --git a/light/locales/en-US/light b/light/locales/en-US/light
index 77e57549..852ebdcc 100644
--- a/light/locales/en-US/light
+++ b/light/locales/en-US/light
@@ -13,9 +13,15 @@
"name": "Name",
"lighttype": "Light type",
"switch": "Switch",
+ "dimmerstate": "Dimmer state",
"dimmer": "Dimmer",
"offvalue": "Value off",
"onvalue": "Value on",
+ "minvalue": "Min. value",
+ "maxvalue": "Max. value",
+ "step": "Min. step",
+ "factor": "Factor",
+ "interval": "Interval",
"twoinputs": "2-channel input"
},
"paletteHelp": "
Switches a light or a socket.
",
diff --git a/mqtt/mqtt-broker/MyNode.cpp b/mqtt/mqtt-broker/MyNode.cpp
index 1b2f70df..f84e40d7 100644
--- a/mqtt/mqtt-broker/MyNode.cpp
+++ b/mqtt/mqtt-broker/MyNode.cpp
@@ -153,6 +153,24 @@ void MyNode::waitForStop()
}
}
+Flows::PVariable MyNode::getConfigParameterIncoming(std::string name)
+{
+ try
+ {
+ auto settingsIterator = _nodeInfo->info->structValue->find(name);
+ if(settingsIterator != _nodeInfo->info->structValue->end()) return settingsIterator->second;
+ }
+ catch(const std::exception& ex)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return std::make_shared();
+}
+
//{{{ RPC methods
Flows::PVariable MyNode::publish(Flows::PArray& parameters)
{
diff --git a/mqtt/mqtt-broker/MyNode.h b/mqtt/mqtt-broker/MyNode.h
index a44a56b0..9a53d13a 100644
--- a/mqtt/mqtt-broker/MyNode.h
+++ b/mqtt/mqtt-broker/MyNode.h
@@ -46,6 +46,8 @@ class MyNode: public Flows::INode
virtual bool start();
virtual void stop();
virtual void waitForStop();
+
+ virtual Flows::PVariable getConfigParameterIncoming(std::string name);
private:
Flows::PNodeInfo _nodeInfo;
std::unique_ptr _mqtt;
diff --git a/passthrough/passthrough.hni b/passthrough/passthrough.hni
index 001ac52e..304e6310 100644
--- a/passthrough/passthrough.hni
+++ b/passthrough/passthrough.hni
@@ -19,7 +19,7 @@
+
+
diff --git a/timers/Makefile.am b/timers/Makefile.am
index a0d7de02..aa82c69b 100644
--- a/timers/Makefile.am
+++ b/timers/Makefile.am
@@ -6,7 +6,7 @@ LIBS += -Wl,-Bdynamic -lhomegear-node
libdir = $(localstatedir)/lib/homegear/flows/nodes/timers
-lib_LTLIBRARIES = clock.la interval.la delay.la timer.la sun-position.la
+lib_LTLIBRARIES = clock.la interval.la delay.la timer.la slow-pwm.la sun-position.la
clock_la_SOURCES = clock/Factory.cpp clock/MyNode.cpp
clock_la_LDFLAGS =-module -avoid-version -shared
@@ -20,17 +20,21 @@ delay_la_LDFLAGS =-module -avoid-version -shared
timer_la_SOURCES = timer/Factory.cpp timer/MyNode.cpp timer/SunTime.cpp
timer_la_LDFLAGS =-module -avoid-version -shared
+slow_pwm_la_SOURCES = slow-pwm/Factory.cpp slow-pwm/MyNode.cpp
+slow_pwm_la_LDFLAGS =-module -avoid-version -shared
+
sun_position_la_SOURCES = sun-position/Factory.cpp sun-position/MyNode.cpp sun-position/SunTime.cpp
sun_position_la_LDFLAGS =-module -avoid-version -shared
timers_ladir = $(libdir)
-timers_la_DATA = clock/clock.hni interval/interval.hni delay/delay.hni timer/timer.hni sun-position/sun-position.hni
+timers_la_DATA = clock/clock.hni interval/interval.hni delay/delay.hni timer/timer.hni slow-pwm/slow-pwm.hni sun-position/sun-position.hni
locale_en_usdir = $(libdir)/locales/en-US
-locale_en_us_DATA = clock/locales/en-US/clock interval/locales/en-US/interval delay/locales/en-US/delay timer/locales/en-US/timer sun-position/locales/en-US/sun-position
+locale_en_us_DATA = clock/locales/en-US/clock interval/locales/en-US/interval delay/locales/en-US/delay timer/locales/en-US/timer slow-pwm/locales/en-US/slow-pwm sun-position/locales/en-US/sun-position
install-exec-hook:
rm -f $(DESTDIR)$(libdir)/clock.la
rm -f $(DESTDIR)$(libdir)/interval.la
rm -f $(DESTDIR)$(libdir)/delay.la
rm -f $(DESTDIR)$(libdir)/timer.la
+ rm -f $(DESTDIR)$(libdir)/slow-pwm.la
rm -f $(DESTDIR)$(libdir)/sun-position.la
diff --git a/timers/interval/MyNode.cpp b/timers/interval/MyNode.cpp
index 1884c151..76058740 100644
--- a/timers/interval/MyNode.cpp
+++ b/timers/interval/MyNode.cpp
@@ -34,6 +34,7 @@ namespace MyNode
MyNode::MyNode(std::string path, std::string nodeNamespace, std::string type, const std::atomic_bool* frontendConnected) : Flows::INode(path, nodeNamespace, type, frontendConnected)
{
+ _enabled = true;
_stopThread = true;
}
@@ -205,9 +206,9 @@ void MyNode::input(Flows::PNodeInfo info, uint32_t index, Flows::PVariable messa
{
try
{
+ _inputTime = Flows::HelperFunctions::getTime();
if(index == 0)
{
- _inputTime = Flows::HelperFunctions::getTime();
_enabled = message->structValue->at("payload")->booleanValue;
setNodeData("enabled", std::make_shared(_enabled));
Flows::PVariable status = std::make_shared(Flows::VariableType::tStruct);
@@ -223,16 +224,14 @@ void MyNode::input(Flows::PNodeInfo info, uint32_t index, Flows::PVariable messa
_stopThread = false;
_timerThread = std::thread(&MyNode::timer, this);
}
- Flows::PVariable message = std::make_shared(Flows::VariableType::tStruct);
- message->structValue->emplace("payload", std::make_shared(true));
- output(1, message);
}
- else if(index == 1 && _enabled && message->structValue->at("payload")->booleanValue)
+ else if(index == 1 && _enabled && message->structValue->at("payload"))
{
std::lock_guard timerGuard(_timerMutex);
_stopThread = true;
if(_timerThread.joinable()) _timerThread.join();
_tick = 0;
+ _startTimeAll = Flows::HelperFunctions::getTime();
_stopThread = false;
_timerThread = std::thread(&MyNode::timer, this);
}
diff --git a/timers/interval/MyNode.h b/timers/interval/MyNode.h
index 0c0deb03..20a88e67 100644
--- a/timers/interval/MyNode.h
+++ b/timers/interval/MyNode.h
@@ -48,7 +48,7 @@ class MyNode: public Flows::INode
virtual void stop();
virtual void waitForStop();
private:
- bool _enabled = true;
+ std::atomic_bool _enabled;
int64_t _startTimeAll = 0;
int64_t _tick = 0;
int64_t _inputTime = 0;
diff --git a/timers/interval/locales/en-US/interval b/timers/interval/locales/en-US/interval
index f7c5b501..c505b22a 100644
--- a/timers/interval/locales/en-US/interval
+++ b/timers/interval/locales/en-US/interval
@@ -11,9 +11,9 @@
"input1Description": "Set to true
to enable the timer and to false
to disable it.",
"input2Description": "Set to true
to reset the timer. Setting EN
to false also resets the timer.",
"output1Description": "Outputs the number of ticks since the timer was started.",
- "output2Description": "Outputs true
when the timer is finished.",
+ "output2Description": "Outputs true
when the timer is finished after the time defined in \"Reset after\" is up.",
"paletteHelp": "Generates an periodic event in constant intervals.
",
- "help": "This node generates events in constant intervals. Set EN
to \"true\" to enable the timer. You can set \"Reset after\" to automatically disable the timer."
+ "help": "This node generates events in constant intervals. Set EN
to \"true\" to enable the timer. You can set \"Reset after\" to automatically disable the timer. When the timer is stopped after the time defined in \"Reset after\", output f
is set to \"true\"."
}
}
}
diff --git a/timers/slow-pwm/Factory.cpp b/timers/slow-pwm/Factory.cpp
new file mode 100644
index 00000000..6304ad24
--- /dev/null
+++ b/timers/slow-pwm/Factory.cpp
@@ -0,0 +1,42 @@
+/* Copyright 2013-2017 Sathya Laufer
+ *
+ * Homegear is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Homegear is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "Factory.h"
+#include "MyNode.h"
+#include "../config.h"
+
+Flows::INode* MyFactory::createNode(std::string path, std::string nodeNamespace, std::string type, const std::atomic_bool* frontendConnected)
+{
+ return new MyNode::MyNode(path, nodeNamespace, type, frontendConnected);
+}
+
+Flows::NodeFactory* getFactory()
+{
+ return (Flows::NodeFactory*) (new MyFactory);
+}
diff --git a/timers/slow-pwm/Factory.h b/timers/slow-pwm/Factory.h
new file mode 100644
index 00000000..6e79b886
--- /dev/null
+++ b/timers/slow-pwm/Factory.h
@@ -0,0 +1,44 @@
+/* Copyright 2013-2017 Sathya Laufer
+ *
+ * Homegear is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Homegear is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef FACTORY_H
+#define FACTORY_H
+
+#include
+#include "MyNode.h"
+
+class MyFactory : Flows::NodeFactory
+{
+public:
+ virtual Flows::INode* createNode(std::string path, std::string nodeNamespace, std::string type, const std::atomic_bool* frontendConnected);
+};
+
+extern "C" Flows::NodeFactory* getFactory();
+
+#endif
diff --git a/timers/slow-pwm/MyNode.cpp b/timers/slow-pwm/MyNode.cpp
new file mode 100644
index 00000000..0f9217dc
--- /dev/null
+++ b/timers/slow-pwm/MyNode.cpp
@@ -0,0 +1,234 @@
+/* Copyright 2013-2017 Sathya Laufer
+ *
+ * Homegear is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Homegear is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#include "MyNode.h"
+
+namespace MyNode
+{
+
+MyNode::MyNode(std::string path, std::string nodeNamespace, std::string type, const std::atomic_bool* frontendConnected) : Flows::INode(path, nodeNamespace, type, frontendConnected)
+{
+ _stopThread = true;
+ _enabled = true;
+}
+
+MyNode::~MyNode()
+{
+ _stopThread = true;
+ waitForStop();
+}
+
+
+bool MyNode::init(Flows::PNodeInfo info)
+{
+ try
+ {
+ auto settingsIterator = info->info->structValue->find("period");
+ if(settingsIterator != info->info->structValue->end()) _period = Flows::Math::getNumber(settingsIterator->second->stringValue);
+
+ settingsIterator = info->info->structValue->find("dutycyclemin");
+ if(settingsIterator != info->info->structValue->end()) _dutyCycleMin = Flows::Math::getNumber(settingsIterator->second->stringValue);
+
+ settingsIterator = info->info->structValue->find("dutycyclemax");
+ if(settingsIterator != info->info->structValue->end()) _dutyCycleMax = Flows::Math::getNumber(settingsIterator->second->stringValue);
+
+ if(_dutyCycleMax <= _dutyCycleMin)
+ {
+ Flows::Output::printError("Error: Duty cycle maximum is smaller than or equal to duty cycle minimum. Setting both to defaults.");
+ _dutyCycleMin = 0;
+ _dutyCycleMax = 100;
+ }
+
+ if(_period < 10) _period = 10;
+
+ auto enabled = getNodeData("enabled");
+ if(enabled->type == Flows::VariableType::tBoolean) _enabled = enabled->booleanValue;
+
+ _startTimeAll = getNodeData("startTimeAll")->integerValue;
+ if(_startTimeAll == 0) _startTimeAll = Flows::HelperFunctions::getTimeSeconds();
+
+ _currentDutyCycle = getNodeData("dutycycle")->integerValue;
+
+ return true;
+ }
+ catch(const std::exception& ex)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return false;
+}
+
+bool MyNode::start()
+{
+ try
+ {
+ if(!_enabled) return true;
+ std::lock_guard timerGuard(_timerMutex);
+ _stopThread = false;
+ if(_timerThread.joinable()) _timerThread.join();
+ _timerThread = std::thread(&MyNode::timer, this);
+
+ return true;
+ }
+ catch(const std::exception& ex)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ return false;
+}
+
+void MyNode::stop()
+{
+ try
+ {
+ _stopThread = true;
+ setNodeData("startTimeAll", std::make_shared(_startTimeAll));
+ }
+ catch(const std::exception& ex)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+void MyNode::waitForStop()
+{
+ try
+ {
+ std::lock_guard timerGuard(_timerMutex);
+ if(_timerThread.joinable()) _timerThread.join();
+ }
+ catch(const std::exception& ex)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+int32_t MyNode::scale(int32_t value, int32_t valueMin, int32_t valueMax, int32_t scaleMin, int32_t scaleMax)
+{
+ double vPerc = ((double)(value - valueMin)) / (valueMax - valueMin);
+ double bigSpan = vPerc * (scaleMax - scaleMin);
+
+ return std::lround(scaleMin + bigSpan);
+}
+
+void MyNode::timer()
+{
+ int32_t pwmPosition = (Flows::HelperFunctions::getTimeSeconds() - _startTimeAll) % _period;
+ bool pwmState = pwmPosition <= _currentDutyCycle && _currentDutyCycle > _dutyCycleMin;
+ bool lastPwmState = pwmState;
+
+ Flows::PVariable message = std::make_shared(Flows::VariableType::tStruct);
+ message->structValue->emplace("payload", std::make_shared(pwmState));
+ output(0, message);
+
+ while(!_stopThread)
+ {
+ try
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+ if(_stopThread) return;
+
+ pwmPosition = (Flows::HelperFunctions::getTimeSeconds() - _startTimeAll) % _period;
+ pwmState = pwmPosition <= _currentDutyCycle && _currentDutyCycle > _dutyCycleMin;
+ if(pwmState != lastPwmState)
+ {
+ lastPwmState = pwmState;
+ message->structValue->at("payload")->booleanValue = pwmState;
+ output(0, message);
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+ }
+}
+
+void MyNode::input(Flows::PNodeInfo info, uint32_t index, Flows::PVariable message)
+{
+ try
+ {
+ if(index == 0)
+ {
+ int32_t dutyCycle = message->structValue->at("payload")->integerValue64;
+ if(dutyCycle > _dutyCycleMax) dutyCycle = _dutyCycleMax;
+ else if(dutyCycle < _dutyCycleMin) dutyCycle = _dutyCycleMin;
+ dutyCycle = std::lround((double)_period * (((double)(dutyCycle - _dutyCycleMin)) / (_dutyCycleMax - _dutyCycleMin)));
+ _currentDutyCycle = dutyCycle;
+ setNodeData("dutycycle", std::make_shared(dutyCycle));
+ }
+ else if(index == 1)
+ {
+ _enabled = message->structValue->at("payload")->booleanValue;
+ setNodeData("enabled", std::make_shared(_enabled));
+ Flows::PVariable status = std::make_shared(Flows::VariableType::tStruct);
+ status->structValue->emplace("text", std::make_shared(_enabled ? "enabled" : "disabled"));
+ nodeEvent("statusTop/" + _id, status);
+ std::lock_guard timerGuard(_timerMutex);
+ _stopThread = true;
+ if(_timerThread.joinable()) _timerThread.join();
+ if(_enabled)
+ {
+ _startTimeAll = Flows::HelperFunctions::getTimeSeconds();
+ _stopThread = false;
+ _timerThread = std::thread(&MyNode::timer, this);
+ }
+ }
+ }
+ catch(const std::exception& ex)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__, ex.what());
+ }
+ catch(...)
+ {
+ Flows::Output::printEx(__FILE__, __LINE__, __PRETTY_FUNCTION__);
+ }
+}
+
+}
diff --git a/timers/slow-pwm/MyNode.h b/timers/slow-pwm/MyNode.h
new file mode 100644
index 00000000..efcf1ffe
--- /dev/null
+++ b/timers/slow-pwm/MyNode.h
@@ -0,0 +1,70 @@
+/* Copyright 2013-2017 Sathya Laufer
+ *
+ * Homegear is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Homegear is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Homegear. If not, see .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations
+ * including the two.
+ * You must obey the GNU General Public License in all respects
+ * for all of the code used other than OpenSSL. If you modify
+ * file(s) with this exception, you may extend this exception to your
+ * version of the file(s), but you are not obligated to do so. If you
+ * do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source
+ * files in the program, then also delete it here.
+ */
+
+#ifndef MYNODE_H_
+#define MYNODE_H_
+
+#include
+#include
+#include
+
+namespace MyNode
+{
+
+class MyNode: public Flows::INode
+{
+public:
+ MyNode(std::string path, std::string nodeNamespace, std::string type, const std::atomic_bool* frontendConnected);
+ virtual ~MyNode();
+
+ virtual bool init(Flows::PNodeInfo info);
+ virtual bool start();
+ virtual void stop();
+ virtual void waitForStop();
+private:
+ std::atomic_bool _enabled;
+ uint32_t _period = 1800;
+ int32_t _dutyCycleMin = 0;
+ int32_t _dutyCycleMax = 100;
+ std::atomic _currentDutyCycle;
+
+ int32_t _startTimeAll = 0;
+
+ std::mutex _timerMutex;
+ std::atomic_bool _stopThread;
+ std::thread _timerThread;
+
+ int32_t scale(int32_t value, int32_t valueMin, int32_t valueMax, int32_t scaleMin, int32_t scaleMax);
+ void timer();
+ virtual void input(Flows::PNodeInfo info, uint32_t index, Flows::PVariable message);
+};
+
+}
+
+#endif
diff --git a/timers/slow-pwm/locales/en-US/slow-pwm b/timers/slow-pwm/locales/en-US/slow-pwm
new file mode 100644
index 00000000..8fe1da79
--- /dev/null
+++ b/timers/slow-pwm/locales/en-US/slow-pwm
@@ -0,0 +1,17 @@
+{
+ "timers/slow-pwm.hni": {
+ "slow-pwm": {
+ "label": {
+ "period": "Period",
+ "period2": "Period in seconds",
+ "dutycyclemin": "Minimum duty cycle value",
+ "dutycyclemax": "Maximum duty cycle value",
+ "name": "Name"
+ },
+ "input1Description": "The duty cycle.",
+ "output1Description": "Outputs \"true\" on high and \"false\" on low value.",
+ "paletteHelp": "Generates a PWM signal.
",
+ "help": "This node generates a slow PWM signal. Input the duty cycle lenght to D
. Set Period
to the period in seconds. The minimum period is 10 seconds, the duty cycle resolution is 1 second. Set EN
to \"false\" to disable the PWM."
+ }
+ }
+}
diff --git a/timers/slow-pwm/slow-pwm.hni b/timers/slow-pwm/slow-pwm.hni
new file mode 100644
index 00000000..f4eba8cf
--- /dev/null
+++ b/timers/slow-pwm/slow-pwm.hni
@@ -0,0 +1,62 @@
+
+
+
diff --git a/timers/sun-position/MyNode.cpp b/timers/sun-position/MyNode.cpp
index 4963563f..7d351c6f 100644
--- a/timers/sun-position/MyNode.cpp
+++ b/timers/sun-position/MyNode.cpp
@@ -139,6 +139,18 @@ void MyNode::waitForStop()
void MyNode::timer()
{
int32_t i = 0;
+ {
+ std::random_device rd;
+ std::mt19937 gen(rd());
+ std::uniform_int_distribution<> dis(0, 60);
+ int32_t randomInterval = dis(gen);
+ for(i = 0; i < randomInterval; i++)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+ if(_stopThread) break;
+ }
+ }
+
Flows::PVariable message = std::make_shared(Flows::VariableType::tStruct);
Flows::PVariable sunPositionPayload = std::make_shared(Flows::VariableType::tStruct);
message->structValue->emplace("payload", sunPositionPayload);
@@ -151,6 +163,7 @@ void MyNode::timer()
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
if(_stopThread) break;
}
+ if(_stopThread) break;
auto sunPosition = _sunTime.getPosition(Flows::HelperFunctions::getTime(), _latitude, _longitude);
sunPositionPayload->structValue->clear();
sunPositionPayload->structValue->emplace("azimuth", std::make_shared((double)sunPosition.azimuth));
diff --git a/timers/sun-position/MyNode.h b/timers/sun-position/MyNode.h
index a91d7c17..75ffa586 100644
--- a/timers/sun-position/MyNode.h
+++ b/timers/sun-position/MyNode.h
@@ -34,6 +34,7 @@
#include
#include
#include
+#include
namespace MyNode
{
diff --git a/timers/sun-position/SunTime.h b/timers/sun-position/SunTime.h
index 80c56ab0..b8d85d0e 100644
--- a/timers/sun-position/SunTime.h
+++ b/timers/sun-position/SunTime.h
@@ -46,6 +46,7 @@
#include
#include
#include
+#include
namespace MyNode
{
diff --git a/timers/timer/MyNode.h b/timers/timer/MyNode.h
index d0bf71fb..2045dc38 100644
--- a/timers/timer/MyNode.h
+++ b/timers/timer/MyNode.h
@@ -51,7 +51,7 @@ class MyNode: public Flows::INode
virtual void waitForStop();
private:
SunTime _sunTime;
- bool _enabled = false;
+ std::atomic_bool _enabled;
bool _outputOnStartUp = false;
std::string _onTime;
std::string _onTimeType;
diff --git a/timers/timer/SunTime.h b/timers/timer/SunTime.h
index 80c56ab0..b8d85d0e 100644
--- a/timers/timer/SunTime.h
+++ b/timers/timer/SunTime.h
@@ -46,6 +46,7 @@
#include
#include
#include
+#include
namespace MyNode
{
diff --git a/variable/constant/MyNode.cpp b/variable/constant/MyNode.cpp
index 2c6c1dab..6336b5ce 100644
--- a/variable/constant/MyNode.cpp
+++ b/variable/constant/MyNode.cpp
@@ -62,11 +62,15 @@ bool MyNode::init(Flows::PNodeInfo info)
{
_value->setType(Flows::VariableType::tInteger64);
_value->integerValue64 = Flows::Math::getNumber64(payload);
+ _value->integerValue = (int32_t)_value->integerValue64;
+ _value->floatValue = _value->integerValue64;
}
else if(payloadType == "float")
{
_value->setType(Flows::VariableType::tFloat);
_value->floatValue = Flows::Math::getDouble(payload);
+ _value->integerValue = _value->floatValue;
+ _value->integerValue64 = _value->floatValue;
}
else if(payloadType == "string")
{
diff --git a/variable/variable-out/variable-out.hni b/variable/variable-out/variable-out.hni
index 78d80a1c..8abec7da 100644
--- a/variable/variable-out/variable-out.hni
+++ b/variable/variable-out/variable-out.hni
@@ -286,12 +286,6 @@
updatePeerIdOptions();
});
//}}}
- },
- oneditsave: function() {
- if(!$("#node-input-peerid").val()) $("#node-input-peerid").val("0");
- if(!$("#node-input-channel").val()) $("#node-input-channel").val("-1");
- if(!$("#node-input-variabletext").val()) $("#node-input-variabletext").val($("#node-input-variable").val());
- if(!$("#node-input-variable").val()) $("#node-input-variable").val($("#node-input-variabletext").val());
}
});