diff --git a/lib/MycilaDimmer/MycilaDimmer.cpp b/lib/MycilaDimmer/MycilaDimmer.cpp index 6b6a245..6c71939 100644 --- a/lib/MycilaDimmer/MycilaDimmer.cpp +++ b/lib/MycilaDimmer/MycilaDimmer.cpp @@ -38,12 +38,12 @@ extern Mycila::Logger logger; static const uint16_t TABLE_PHASE_DELAY[TABLE_PHASE_LEN] PROGMEM{0xefea, 0xdfd4, 0xd735, 0xd10d, 0xcc12, 0xc7cc, 0xc403, 0xc094, 0xbd6a, 0xba78, 0xb7b2, 0xb512, 0xb291, 0xb02b, 0xaddc, 0xaba2, 0xa97a, 0xa762, 0xa557, 0xa35a, 0xa167, 0x9f7f, 0x9da0, 0x9bc9, 0x99fa, 0x9831, 0x966e, 0x94b1, 0x92f9, 0x9145, 0x8f95, 0x8de8, 0x8c3e, 0x8a97, 0x88f2, 0x8750, 0x85ae, 0x840e, 0x826e, 0x80cf, 0x7f31, 0x7d92, 0x7bf2, 0x7a52, 0x78b0, 0x770e, 0x7569, 0x73c2, 0x7218, 0x706b, 0x6ebb, 0x6d07, 0x6b4f, 0x6992, 0x67cf, 0x6606, 0x6437, 0x6260, 0x6081, 0x5e99, 0x5ca6, 0x5aa9, 0x589e, 0x5686, 0x545e, 0x5224, 0x4fd5, 0x4d6f, 0x4aee, 0x484e, 0x4588, 0x4296, 0x3f6c, 0x3bfd, 0x3834, 0x33ee, 0x2ef3, 0x28cb, 0x202c, 0x1016}; -void Mycila::Dimmer::beginDimmer(const int8_t pin, const uint16_t semiPeriod) { - if (_dimmer) +void Mycila::Dimmer::begin(int8_t pin, uint32_t semiPeriod) { + if (_enabled) return; if (!semiPeriod) { - LOGE(TAG, "Disable Dimmer on pin %" PRId8 ": Invalid semi-period: %" PRIu16 " us", pin, semiPeriod); + LOGE(TAG, "Disable Dimmer on pin %" PRId8 ": Invalid semi-period: %" PRIu32 " us", pin, semiPeriod); return; } @@ -55,30 +55,28 @@ void Mycila::Dimmer::beginDimmer(const int8_t pin, const uint16_t semiPeriod) { return; } - LOGI(TAG, "Enable Dimmer on pin %" PRId8, _pin); + LOGI(TAG, "Enable Dimmer on pin %" PRId8 " with semi-period %" PRIu32 " us", pin, semiPeriod); _semiPeriod = semiPeriod; + _dimmer = new Thyristor(_pin); pinMode(_pin, OUTPUT); digitalWrite(_pin, LOW); + _enabled = true; - _dimmer = new Thyristor(_pin); setDutyCycle(_dutyCycleMin); } -void Mycila::Dimmer::endDimmer() { - if (_dimmer) { - LOGI(TAG, "Disable Dimmer on pin %" PRId8, _pin); - _dutyCycle = 0; - _dimmer->turnOff(); - digitalWrite(_pin, LOW); - delete _dimmer; - _dimmer = nullptr; - _pin = GPIO_NUM_NC; - } +void Mycila::Dimmer::end() { + if (!_enabled) + return; + + LOGI(TAG, "Disable Dimmer on pin %" PRId8, _pin); + _enabled = false; + _disable(); } void Mycila::Dimmer::setDutyCycle(float newDutyCycle) { - if (!_dimmer) + if (!_enabled) return; if (_semiPeriod == 0) @@ -104,25 +102,38 @@ void Mycila::Dimmer::setDutyCycle(float newDutyCycle) { const uint32_t a = TABLE_PHASE_DELAY[index]; const uint32_t b = TABLE_PHASE_DELAY[index + 1]; const uint32_t delay = a - (((a - b) * (slot & 0xffff)) >> 16); - _dimmer->setDelay((delay * _semiPeriod) >> 16); + _delay = (delay * _semiPeriod) >> 16; + + _dimmer->setDelay(_delay); } } void Mycila::Dimmer::setDutyCycleLimit(float limit) { _dutyCycleLimit = constrain(limit, 0, 1); - LOGD(TAG, "Set dimmer duty cycle limit to %f", _dutyCycleLimit); + LOGD(TAG, "Set dimmer %" PRId8 " duty cycle limit to %f", _pin, _dutyCycleLimit); if (_dutyCycle > _dutyCycleLimit) setDutyCycle(_dutyCycleLimit); } void Mycila::Dimmer::setDutyCycleMin(float min) { _dutyCycleMin = constrain(min, 0, _dutyCycleMax); - LOGD(TAG, "Set dimmer duty cycle min to %f", _dutyCycleMin); + LOGD(TAG, "Set dimmer %" PRId8 " duty cycle min to %f", _pin, _dutyCycleMin); setDutyCycle(_dutyCycle); } void Mycila::Dimmer::setDutyCycleMax(float max) { _dutyCycleMax = constrain(max, _dutyCycleMin, 1); - LOGD(TAG, "Set dimmer duty cycle max to %f", _dutyCycleMax); + LOGD(TAG, "Set dimmer %" PRId8 " duty cycle max to %f", _pin, _dutyCycleMax); setDutyCycle(_dutyCycle); } + +void Mycila::Dimmer::_disable() { + if (_enabled) { + _dutyCycle = 0; + _delay = UINT32_MAX; + digitalWrite(_pin, LOW); + delete _dimmer; + _dimmer = nullptr; + _pin = GPIO_NUM_NC; + } +} diff --git a/lib/MycilaDimmer/MycilaDimmer.h b/lib/MycilaDimmer/MycilaDimmer.h index 728e1fc..a417948 100644 --- a/lib/MycilaDimmer/MycilaDimmer.h +++ b/lib/MycilaDimmer/MycilaDimmer.h @@ -17,22 +17,49 @@ namespace Mycila { class Dimmer { public: - ~Dimmer() { endDimmer(); } + Dimmer() {} + ~Dimmer() { end(); } - void beginDimmer(const int8_t pin, const uint16_t semiPeriod); - void endDimmer(); + /** + * @brief Enable a dimmer on a specific GPIO pin + * + * @param pin: the GPIO pin to use for the dimmer + * + * @warning Dimmer won't be enabled if pin is invalid + * @warning Dimmer won't be activated until the ZCD is enabled + */ + void begin(int8_t pin, uint32_t semiPeriod); + /** + * @brief Disable the dimmer + * + * @warning Dimmer won't be destroyed but won't turn on anymore even is a duty cycle is set. + */ + void end(); + + /** + * @brief Check if the dimmer is enabled + */ + bool isEnabled() const { return _enabled; } + + /** + * @brief Get the GPIO pin used for the dimmer + */ gpio_num_t getPin() const { return _pin; } - bool isDimmerEnabled() const { return _dimmer != nullptr; } #ifdef MYCILA_JSON_SUPPORT + /** + * @brief Serialize Dimmer information to a JSON object + * + * @param root: the JSON object to serialize to + */ void dimmerToJson(const JsonObject& root) const { const float angle = getPhaseAngle(); - root["enabled"] = _dimmer != nullptr; + root["enabled"] = _enabled; root["state"] = isOn() ? "on" : "off"; root["angle_d"] = angle * RAD_TO_DEG; root["angle"] = angle; - root["delay"] = getFiringDelay(); + root["delay"] = _delay; root["duty_cycle"] = _dutyCycle; root["duty_cycle_limit"] = _dutyCycleLimit; root["duty_cycle_min"] = _dutyCycleMin; @@ -41,52 +68,106 @@ namespace Mycila { } #endif + /** + * @brief Turn on the dimmer at full power + */ void on() { setDutyCycle(1); } + + /** + * @brief Turn off the dimmer + */ void off() { setDutyCycle(0); } + + /** + * @brief Check if the dimmer is off + */ bool isOff() const { return _dutyCycle <= _dutyCycleMin; } + + /** + * @brief Check if the dimmer is on + */ bool isOn() const { return _dutyCycle > _dutyCycleMin; } + + /** + * @brief Check if the dimmer is on at full power + */ bool isOnAtFullPower() const { return _dutyCycle >= _dutyCycleMax; } - // Power Duty Cycle [0, 1] - // At 0% power, duty == 0 - // At 100% power, duty == 1 + /** + * @brief Set the power duty + * + * @param dutyCycle: the power duty cycle in the range [0.0, 1.0] + */ void setDutyCycle(float dutyCycle); - // set the maximum duty [0, 1] + /** + * @brief Set the power duty cycle limit of the dimmer. The duty cycle will be clamped to this limit. + * + * @param limit: the power duty cycle limit in the range [0.0, 1.0] + */ void setDutyCycleLimit(float limit); - // Duty remapping (equivalent to Shelly Dimmer remapping feature) - // remap the duty minimum and maximum values to be a new ones - // useful to calibrate the dimmer when using for example a PWM signal to 0-10V analog convertor connected to a voltage regulator which is only working in a specific voltage range like 1-8V + /** + * @brief Duty remapping (equivalent to Shelly Dimmer remapping feature). + * Useful to calibrate the dimmer when using for example a PWM signal to 0-10V analog convertor connected to a voltage regulator which is only working in a specific voltage range like 1-8V. + * + * @param min: Set the new "0" value for the power duty cycle. The duty cycle in the range [0.0, 1.0] will be remapped to [min, max]. + */ void setDutyCycleMin(float min); + + /** + * @brief Duty remapping (equivalent to Shelly Dimmer remapping feature). + * Useful to calibrate the dimmer when using for example a PWM signal to 0-10V analog convertor connected to a voltage regulator which is only working in a specific voltage range like 1-8V. + * + * @param max: Set the new "1" value for the power duty cycle. The duty cycle in the range [0.0, 1.0] will be remapped to [min, max]. + */ void setDutyCycleMax(float max); + /** + * @brief Get the power duty cycle of the dimmer + */ float getDutyCycle() const { return _dutyCycle; } + + /** + * @brief Get the power duty cycle limit of the dimmer + */ float getDutyCycleLimit() const { return _dutyCycleLimit; } + + /** + * @brief Get the remapped "0" of the dimmer duty cycle + */ float getDutyCycleMin() const { return _dutyCycleMin; } + + /** + * @brief Get the remapped "1" of the dimmer duty cycle + */ float getDutyCycleMax() const { return _dutyCycleMax; } - // Delay [0, semi-period] us - // Where semi-period = 1000000 / 2 / frequency (50h: 10000 us, 60Hz: 8333 us) - // At 0% power, delay is equal to the semi-period - // At 100% power, the delay is 0 us - uint16_t getFiringDelay() const { return isDimmerEnabled() ? _dimmer->getDelay() : _semiPeriod; } - - // Phase angle [0, PI] rad - // At 0% power, the phase angle is equal to PI - // At 100% power, the phase angle is equal to 0 - float getPhaseAngle() const { - // angle_rad = PI * delay_us / period_us - return _semiPeriod == 0 ? PI : PI * getFiringDelay() / _semiPeriod; - } + /** + * @brief Get the firing delay in us of the dimmer in the range [0, semi-period] + * At 0% power, delay is equal to the semi-period. + * At 100% power, the delay is 0 us + * If the firing delay is UINT32_MAX, the dimmer is off + */ + uint32_t getFiringDelay() const { return _delay; } + + /** + * @brief Get the phase angle in radians of the dimmer in the range [0, PI] + * At 0% power, the phase angle is equal to PI + * At 100% power, the phase angle is equal to 0 + */ + float getPhaseAngle() const { return _delay >= _semiPeriod ? PI : PI * _delay / _semiPeriod; } private: + bool _enabled = false; gpio_num_t _pin = GPIO_NUM_NC; - Thyristor* _dimmer = nullptr; - uint16_t _semiPeriod = 0; + uint32_t _semiPeriod = 0; + float _dutyCycle = 0; + float _dutyCycleLimit = 1; float _dutyCycleMin = 0; float _dutyCycleMax = 1; - float _dutyCycleLimit = 1; - float _dutyCycle = 0; + void _disable(); + uint32_t _delay = UINT32_MAX; + Thyristor* _dimmer = nullptr; }; } // namespace Mycila diff --git a/lib/MycilaRouter/MycilaRouterOutput.cpp b/lib/MycilaRouter/MycilaRouterOutput.cpp index 30b6972..ec8fbb4 100644 --- a/lib/MycilaRouter/MycilaRouterOutput.cpp +++ b/lib/MycilaRouter/MycilaRouterOutput.cpp @@ -38,7 +38,7 @@ const char* Mycila::RouterOutput::getStateName() const { return StateNames[stati // output Mycila::RouterOutput::State Mycila::RouterOutput::getState() const { - if (!_dimmer->isDimmerEnabled() && !_relay->isEnabled()) + if (!_dimmer->isEnabled() && !_relay->isEnabled()) return State::OUTPUT_DISABLED; if (_autoBypassEnabled) return State::OUTPUT_BYPASS_AUTO; @@ -52,7 +52,7 @@ Mycila::RouterOutput::State Mycila::RouterOutput::getState() const { #ifdef MYCILA_JSON_SUPPORT void Mycila::RouterOutput::toJson(const JsonObject& root, float gridVoltage) const { root["bypass"] = isBypassOn() ? "on" : "off"; - root["enabled"] = isDimmerEnabled(); + root["enabled"] = isEnabled(); root["state"] = getStateName(); root["temperature"] = _temperature.orElse(0); @@ -81,7 +81,7 @@ void Mycila::RouterOutput::toJson(const JsonObject& dest, const Metrics& metrics // dimmer bool Mycila::RouterOutput::setDimmerDutyCycle(float dutyCycle) { - if (!_dimmer->isDimmerEnabled()) { + if (!_dimmer->isEnabled()) { LOGW(TAG, "Dimmer '%s' is disabled", _name); return false; } @@ -127,7 +127,7 @@ void Mycila::RouterOutput::applyTemperatureLimit() { } float Mycila::RouterOutput::autoDivert(float gridVoltage, float availablePowerToDivert) { - if (!_dimmer->isDimmerEnabled() || _autoBypassEnabled || !config.autoDimmer || config.calibratedResistance <= 0 || isDimmerTemperatureLimitReached()) { + if (!_dimmer->isEnabled() || _autoBypassEnabled || !config.autoDimmer || config.calibratedResistance <= 0 || isDimmerTemperatureLimitReached()) { _dimmer->off(); return 0; } @@ -171,7 +171,7 @@ void Mycila::RouterOutput::applyAutoBypass() { // dimmer & relay checks - if (!_relay->isEnabled() && !_dimmer->isDimmerEnabled()) { + if (!_relay->isEnabled() && !_dimmer->isEnabled()) { if (_autoBypassEnabled) { LOGW(TAG, "Relay and dimmer disabled: stopping Auto Bypass '%s'", _name); _autoBypassEnabled = false; @@ -252,7 +252,7 @@ void Mycila::RouterOutput::applyAutoBypass() { // time and temp OK, let's start if (!_autoBypassEnabled) { // auto bypass is not enabled, let's start it - if (!_relay->isEnabled() && !_dimmer->isDimmerEnabled()) { + if (!_relay->isEnabled() && !_dimmer->isEnabled()) { return; } const char* wday = DaysOfWeek[timeInfo.tm_wday]; @@ -329,7 +329,7 @@ void Mycila::RouterOutput::_setBypass(bool state, bool log) { } else { // we don't have a relay: use the dimmer - if (_dimmer->isDimmerEnabled()) { + if (_dimmer->isEnabled()) { if (log) LOGD(TAG, "Turning Dimmer '%s' ON", _name); _dimmer->on(); diff --git a/lib/MycilaRouter/MycilaRouterOutput.h b/lib/MycilaRouter/MycilaRouterOutput.h index b1f2f79..693dc3a 100644 --- a/lib/MycilaRouter/MycilaRouterOutput.h +++ b/lib/MycilaRouter/MycilaRouterOutput.h @@ -74,8 +74,8 @@ namespace Mycila { // dimmer - bool isDimmerEnabled() const { return _dimmer->isDimmerEnabled(); } - bool isAutoDimmerEnabled() const { return _dimmer->isDimmerEnabled() && config.autoDimmer && config.calibratedResistance > 0; } + bool isEnabled() const { return _dimmer->isEnabled(); } + bool isAutoDimmerEnabled() const { return _dimmer->isEnabled() && config.autoDimmer && config.calibratedResistance > 0; } bool isDimmerTemperatureLimitReached() const { return config.dimmerTempLimit > 0 && _temperature.orElse(0) >= config.dimmerTempLimit; } bool isDimmerOn() const { return _dimmer->isOn(); } float getDimmerDutyCycle() const { return _dimmer->getDutyCycle(); } @@ -91,7 +91,7 @@ namespace Mycila { // bypass - bool isBypassEnabled() const { return _relay->isEnabled() || _dimmer->isDimmerEnabled(); } + bool isBypassEnabled() const { return _relay->isEnabled() || _dimmer->isEnabled(); } bool isAutoBypassEnabled() const { return isBypassEnabled() && config.autoBypass; } bool isBypassOn() const { return _bypassEnabled; } bool setBypass(bool state); diff --git a/src/Website.cpp b/src/Website.cpp index 9ae3406..48ffe76 100644 --- a/src/Website.cpp +++ b/src/Website.cpp @@ -907,10 +907,10 @@ void YaSolR::WebsiteClass::updateCards() { _status(_jsy, KEY_ENABLE_JSY, jsy.isEnabled(), jsy.isConnected(), YASOLR_LBL_110); _status(_mqtt, KEY_ENABLE_MQTT, mqtt.isEnabled(), mqtt.isConnected(), mqtt.getLastError() ? mqtt.getLastError() : YASOLR_LBL_113); - _status(_output1Dimmer, KEY_ENABLE_OUTPUT1_DIMMER, dimmerO1.isDimmerEnabled(), zcd.isEnabled(), YASOLR_LBL_179); + _status(_output1Dimmer, KEY_ENABLE_OUTPUT1_DIMMER, dimmerO1.isEnabled(), zcd.isEnabled(), YASOLR_LBL_179); _status(_output1DS18, KEY_ENABLE_OUTPUT1_DS18, ds18O1.isEnabled(), ds18O1.getLastTime() > 0, YASOLR_LBL_114); _status(_output1PZEM, KEY_ENABLE_OUTPUT1_PZEM, pzemO1.isEnabled(), pzemO1.isConnected() && pzemO1.readAddress() == YASOLR_PZEM_ADDRESS_OUTPUT1, pzemO1.isConnected() ? YASOLR_LBL_180 : YASOLR_LBL_110); - _status(_output2Dimmer, KEY_ENABLE_OUTPUT2_DIMMER, dimmerO2.isDimmerEnabled(), zcd.isEnabled(), YASOLR_LBL_179); + _status(_output2Dimmer, KEY_ENABLE_OUTPUT2_DIMMER, dimmerO2.isEnabled(), zcd.isEnabled(), YASOLR_LBL_179); _status(_output2DS18, KEY_ENABLE_OUTPUT2_DS18, ds18O2.isEnabled(), ds18O2.getLastTime() > 0, YASOLR_LBL_114); _status(_output2PZEM, KEY_ENABLE_OUTPUT2_PZEM, pzemO2.isEnabled(), pzemO2.isConnected() && pzemO2.readAddress() == YASOLR_PZEM_ADDRESS_OUTPUT2, pzemO2.isConnected() ? YASOLR_LBL_180 : YASOLR_LBL_110); _status(_routerDS18, KEY_ENABLE_DS18_SYSTEM, ds18Sys.isEnabled(), ds18Sys.getLastTime() > 0, YASOLR_LBL_114); @@ -1108,7 +1108,7 @@ void YaSolR::WebsiteClass::_outputBypassSwitch(Card& card, Mycila::RouterOutput& void YaSolR::WebsiteClass::_outputDimmerSlider(Card& card, Mycila::RouterOutput& output) { card.attachCallbackF([&card, &output, this](float value) { - if (output.isDimmerEnabled()) { + if (output.isEnabled()) { output.setDimmerDutyCycle(value / 100); } card.update(output.getDimmerDutyCycle() * 100); diff --git a/src/init/Config.cpp b/src/init/Config.cpp index f02c8fe..dcad008 100644 --- a/src/init/Config.cpp +++ b/src/init/Config.cpp @@ -23,7 +23,7 @@ Mycila::Task initConfigTask("Init Config", [](void* params) { relayTask.setInterval(7 * Mycila::TaskDuration::SECONDS); routerTask.setEnabledWhen([]() { return !router.isCalibrationRunning(); }); routerTask.setInterval(500 * Mycila::TaskDuration::MILLISECONDS); - zcdTask.setInterval(1500 * Mycila::TaskDuration::MILLISECONDS); + zcdTask.setInterval(1000 * Mycila::TaskDuration::MILLISECONDS); #ifdef APP_MODEL_TRIAL trialTask.setInterval(30 * Mycila::TaskDuration::SECONDS); #endif diff --git a/src/init/Events.cpp b/src/init/Events.cpp index a1a5ea3..84f1e43 100644 --- a/src/init/Events.cpp +++ b/src/init/Events.cpp @@ -143,12 +143,12 @@ Mycila::Task initEventsTask("Init Events", [](void* params) { if (config.getBool(KEY_ENABLE_OUTPUT2_DS18)) ds18O2.begin(config.get(KEY_PIN_OUTPUT2_DS18).toInt()); - } else if (key == KEY_ENABLE_ZCD) { - zcdTask.requestEarlyRun(); - } else if (key == KEY_ENABLE_MQTT) { mqttConfigTask.resume(); + } else if (key == KEY_ENABLE_ZCD) { + zcdTask.requestEarlyRun(); + } else if (key == KEY_ENABLE_OUTPUT1_DIMMER) { dimmer1Task.resume(); diff --git a/src/init/REST.cpp b/src/init/REST.cpp index 2558b31..be29df2 100644 --- a/src/init/REST.cpp +++ b/src/init/REST.cpp @@ -83,8 +83,7 @@ Mycila::Task initRestApiTask("Init REST API", [](void* params) { grid.toJson(root["grid"].to()); jsy.toJson(root["jsy"].to()); - zcd.zcdToJson(root["zcd"].to()); - pulseAnalyzer.toJson(root["zcd_pulse_analyzer"].to()); + pulseAnalyzer.toJson(root["pulse_analyzer"].to()); pidController.toJson(root["pid"].to()); // router diff --git a/src/tasks/Dimmers.cpp b/src/tasks/Dimmers.cpp index 24676fd..9483127 100644 --- a/src/tasks/Dimmers.cpp +++ b/src/tasks/Dimmers.cpp @@ -5,13 +5,13 @@ #include Mycila::Task dimmer1Task("Dimmer 1", Mycila::TaskType::ONCE, [](void* params) { - if (dimmerO1.isDimmerEnabled()) { - dimmerO1.endDimmer(); + if (dimmerO1.isEnabled()) { + dimmerO1.end(); delay(10); } if (config.getBool(KEY_ENABLE_OUTPUT1_DIMMER) && zcd.isEnabled()) { - dimmerO1.beginDimmer(config.get(KEY_PIN_OUTPUT1_DIMMER).toInt(), zcd.getSemiPeriod()); - if (dimmerO1.isDimmerEnabled()) { + dimmerO1.begin(config.get(KEY_PIN_OUTPUT1_DIMMER).toInt(), zcd.getSemiPeriod()); + if (dimmerO1.isEnabled()) { dimmerO1.setDutyCycleMin(config.get(KEY_OUTPUT1_DIMMER_MIN).toFloat() / 100); dimmerO1.setDutyCycleMax(config.get(KEY_OUTPUT1_DIMMER_MAX).toFloat() / 100); dimmerO1.setDutyCycleLimit(config.get(KEY_OUTPUT1_DIMMER_LIMIT).toFloat() / 100); @@ -20,13 +20,13 @@ Mycila::Task dimmer1Task("Dimmer 1", Mycila::TaskType::ONCE, [](void* params) { }); Mycila::Task dimmer2Task("Dimmer 2", Mycila::TaskType::ONCE, [](void* params) { - if (dimmerO2.isDimmerEnabled()) { - dimmerO2.endDimmer(); + if (dimmerO2.isEnabled()) { + dimmerO2.end(); delay(10); } if (config.getBool(KEY_ENABLE_OUTPUT2_DIMMER) && zcd.isEnabled()) { - dimmerO2.beginDimmer(config.get(KEY_PIN_OUTPUT2_DIMMER).toInt(), zcd.getSemiPeriod()); - if (dimmerO2.isDimmerEnabled()) { + dimmerO2.begin(config.get(KEY_PIN_OUTPUT2_DIMMER).toInt(), zcd.getSemiPeriod()); + if (dimmerO2.isEnabled()) { dimmerO2.setDutyCycleMin(config.get(KEY_OUTPUT2_DIMMER_MIN).toFloat() / 100); dimmerO2.setDutyCycleMax(config.get(KEY_OUTPUT2_DIMMER_MAX).toFloat() / 100); dimmerO2.setDutyCycleLimit(config.get(KEY_OUTPUT2_DIMMER_LIMIT).toFloat() / 100); diff --git a/src/tasks/SafeBoot.cpp b/src/tasks/SafeBoot.cpp index 3365b1d..e7206b2 100644 --- a/src/tasks/SafeBoot.cpp +++ b/src/tasks/SafeBoot.cpp @@ -7,8 +7,8 @@ Mycila::Task safeBootTask("SafeBoot", Mycila::TaskType::ONCE, [](void* params) { logger.info(TAG, "Restarting %s in SafeBoot mode...", Mycila::AppInfo.nameModelVersion.c_str()); // stop electricity - dimmerO1.endDimmer(); - dimmerO2.endDimmer(); + dimmerO1.end(); + dimmerO2.end(); bypassRelayO1.end(); bypassRelayO2.end(); relay1.end();