From 5cb9c87135eb9a4fb1fa732f9d12cfe5298cb7aa Mon Sep 17 00:00:00 2001 From: "anklimov@gmail.com" Date: Tue, 5 May 2026 22:08:07 +0300 Subject: [PATCH] Multi AC/vent - released. Sprinkler - alpha for testing Co-authored-by: Copilot --- build-flags/build_flags_lighthub21 | 3 +- lighthub/abstractch.cpp | 6 +- lighthub/abstractch.h | 2 +- lighthub/item.cpp | 3 + lighthub/modules/out_multivent.cpp | 25 ++- lighthub/modules/out_sprinkler.cpp | 321 ++++++++++++++++++----------- lighthub/modules/out_sprinkler.h | 3 + lighthub/utils.cpp | 49 +++++ lighthub/utils.h | 4 +- 9 files changed, 288 insertions(+), 128 deletions(-) diff --git a/build-flags/build_flags_lighthub21 b/build-flags/build_flags_lighthub21 index d9ecf2d..55b89cb 100644 --- a/build-flags/build_flags_lighthub21 +++ b/build-flags/build_flags_lighthub21 @@ -42,4 +42,5 @@ -D CONFIG_CLEAN_PIN=2 -D ROTARYENCODER -D CANDRV --D THERMO_OVERHEAT_CELSIUS=44. \ No newline at end of file +-D THERMO_OVERHEAT_CELSIUS=44. +-D SPRINKLER_ENABLE \ No newline at end of file diff --git a/lighthub/abstractch.cpp b/lighthub/abstractch.cpp index ae7dfa0..5384b73 100644 --- a/lighthub/abstractch.cpp +++ b/lighthub/abstractch.cpp @@ -28,7 +28,7 @@ int abstractCh::publishTopic(const char* topic, float value, const char* subtopi return publishTopic(topic, valstr,subtopic); }; -int abstractCh::publishTopic(const char* topic, const char * value, const char* subtopic) +int abstractCh::publishTopic(const char* topic, const char * value, const char* subtopic, const char* suffix) { #if not defined (NOIP) char addrstr[MQTT_TOPIC_LENGTH]; @@ -38,6 +38,10 @@ int abstractCh::publishTopic(const char* topic, const char * value, const char* strncpy(addrstr,topic,sizeof(addrstr)); if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,topic); strncat(addrstr,subtopic,sizeof(addrstr)-1); + if (suffix) + { + strncat(addrstr,suffix,sizeof(addrstr)-1); + } if (mqttClient.connected() && lanStatus == OPERATION && !ethernetIdleCount) { mqttClient.publish(addrstr, value, true); diff --git a/lighthub/abstractch.h b/lighthub/abstractch.h index 7f8bf3e..491c29a 100644 --- a/lighthub/abstractch.h +++ b/lighthub/abstractch.h @@ -21,6 +21,6 @@ public: protected: int publishTopic(const char* topic, long value, const char* subtopic = NULL); int publishTopic(const char* topic, float value, const char* subtopic = NULL ); -int publishTopic(const char* topic, const char * value, const char* subtopic = NULL); +int publishTopic(const char* topic, const char * value, const char* subtopic = NULL, const char* suffix = NULL); }; diff --git a/lighthub/item.cpp b/lighthub/item.cpp index 62d0e9b..8715ccd 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -2066,6 +2066,9 @@ int Item::SendStatus(long sendFlags, char * subItem) { case S_FAN: strncat_P(addrstr, suffix_P[S_FAN], sizeof(addrstr)-1); break; + case S_VAL: + strncat_P(addrstr, suffix_P[S_VAL], sizeof(addrstr)-1); + break; default: strncat_P(addrstr, suffix_P[S_SET], sizeof(addrstr)-1); } diff --git a/lighthub/modules/out_multivent.cpp b/lighthub/modules/out_multivent.cpp index ea11f43..fbd03a7 100644 --- a/lighthub/modules/out_multivent.cpp +++ b/lighthub/modules/out_multivent.cpp @@ -194,7 +194,7 @@ int out_Multivent::isActive() if (i->name && *i->name) { int preHaltcmd = getIntFromJson(i,"@preHaltcmd",CMD_OFF); - if (preHaltcmd) //setPassiveMode(i, false); + if (preHaltcmd && (preHaltcmd != CMD_OFF)) //setPassiveMode(i, false); fanCtrl(itemCmd().Cmd(preHaltcmd).setSuffix(S_CMD),i->name,true); setValToJson(i,"@preHaltcmd",0); //reset preHaltcmd in any case } @@ -711,7 +711,7 @@ while (i) case S_CMD: if (cmd.isCommand()) { - + bool checkMinFanLevel = false; if (cmd.getCmd() == CMD_ON) { if (getFlag(i,FLAG_FREEZED)) {debugSerial<valueint = cmd.getCmd(); setPassiveMode(i,false); + checkMinFanLevel = true; break; case CMD_HEAT: @@ -783,6 +785,7 @@ while (i) sendFlags |= FLAG_COMMAND; cmdObj->valueint = cmd.getCmd(); setPassiveMode(i,false); + checkMinFanLevel = true; break; case CMD_FAN: @@ -795,10 +798,11 @@ while (i) sendFlags |= FLAG_COMMAND; cmdObj->valueint = cmd.getCmd(); setPassiveMode(i,false); + checkMinFanLevel = true; break; //todo - halt-rest-xon-xoff } - if (isNotRetainingStatus() && (cmdObj->valueint == CMD_ON) && (fanObj->valueint<20)) + if (isNotRetainingStatus() && checkMinFanLevel && (fanObj->valueint<20)) { fanObj->valueint=30; cmd.Percents255(30); @@ -961,7 +965,7 @@ bool out_Multivent::pidEnabled(aJsonObject* pidObj) if (!(acCmd == CMD_OFF && lastFan == 0)) { debugSerial<<"VENT: AC MODE changed manually from "<itemArg) return false; @@ -33,21 +33,21 @@ bool out_sprinkler::getConfig() aJsonObject * rootCfg = aJson.getObjectItem(gatesObj, ""); if (!rootCfg) rootCfg = gatesObj; - vinPin = getIntFromJson(rootCfg, "vIn", -1); - drenPin = getIntFromJson(rootCfg, "rDren", -1); - pumpPin = getIntFromJson(rootCfg, "rPump", -1); - wMaxPin = getIntFromJson(rootCfg, "wMax", -1); - wMinPin = getIntFromJson(rootCfg, "wMin", -1); - fbDrenPin = getIntFromJson(rootCfg, "fbDren", -1); - fbPumpPin = getIntFromJson(rootCfg, "fbPump", -1); - wCtrPin = getIntFromJson(rootCfg, "wCtr", -1); + vinPin = getIntFromJson(rootCfg, "vIn", PINS_COUNT); + drenPin = getIntFromJson(rootCfg, "rDren", PINS_COUNT); + pumpPin = getIntFromJson(rootCfg, "rPump", PINS_COUNT); + wMaxPin = getIntFromJson(rootCfg, "wMax", PINS_COUNT); + wMinPin = getIntFromJson(rootCfg, "wMin", PINS_COUNT); + fbDrenPin = getIntFromJson(rootCfg, "fbDren", PINS_COUNT); + fbPumpPin = getIntFromJson(rootCfg, "fbPump", PINS_COUNT); + wCtrPin = getIntFromJson(rootCfg, "wCtr", PINS_COUNT); return true; } static bool isValidControlPin(short pin) { - return (pin >= 0 && pin < PINS_COUNT && !isProtectedPin(pin)); + return (abs(pin) < PINS_COUNT && !isProtectedPin(abs(pin))); } void out_sprinkler::publishBooleanStateIfChanged(const char * subItem, bool state, uint32_t flag, uint32_t & lastState) @@ -59,8 +59,7 @@ void out_sprinkler::publishBooleanStateIfChanged(const char * subItem, bool stat void out_sprinkler::setOutput(short pin, bool value) { - if (!isValidControlPin(pin)) return; - digitalWrite(pin, value ? HIGH : LOW); + writeOutPin(pin, value ? HIGH : LOW); } int out_sprinkler::Setup() @@ -73,17 +72,19 @@ int out_sprinkler::Setup() return 0; } - if (isValidControlPin(vinPin)) { pinMode(vinPin, OUTPUT); digitalWrite(vinPin, LOW); } - if (isValidControlPin(drenPin)) { pinMode(drenPin, OUTPUT); digitalWrite(drenPin, LOW); } - if (isValidControlPin(pumpPin)) { pinMode(pumpPin, OUTPUT); digitalWrite(pumpPin, LOW); } + if (isValidControlPin(vinPin)) { pinMode(vinPin, OUTPUT); writeOutPin(vinPin, LOW); } + if (isValidControlPin(drenPin)) { pinMode(drenPin, OUTPUT); writeOutPin(drenPin, LOW); } + if (isValidControlPin(pumpPin)) { pinMode(pumpPin, OUTPUT); writeOutPin(pumpPin, LOW); } + + debugSerial << F("SPRINKLER: ")<<"vIN=" << vinPin << " dren=" << drenPin << " pump=" << pumpPin << endl; aJsonObject * zone = gatesObj->child; while (zone) { if (zone->name && *zone->name && zone->type == aJson_Object) { - short pin = getIntFromJson(zone, "pin", -1); - if (isValidControlPin(pin)) { pinMode(pin, OUTPUT); digitalWrite(pin, LOW); } + short pin = getIntFromJson(zone, "pin", PINS_COUNT); + if (isValidControlPin(pin)) { pinMode(pin, OUTPUT); writeOutPin(pin, LOW); } getCreateObject(zone, "cmd", (long)CMD_OFF); getCreateObject(zone, "val", (long)0); getCreateObject(zone, "set", (long)0); @@ -95,29 +96,30 @@ int out_sprinkler::Setup() getCreateObject(gatesObj, "@state", (long)SP_UNKNOWN); getCreateObject(gatesObj, "@timer", (long)0); getCreateObject(gatesObj, "@flowTimer", (long)0); - + + debugSerial << F("SPRINKLER: ") << " wMax=" << wMaxPin << " wMin=" << wMinPin << " fbDren=" << fbDrenPin << " fbPump=" << fbPumpPin << " wCtr=" << wCtrPin << endl; uint16_t lastVals = 0; - if (wCtrPin >= 0 && wCtrPin < PINS_COUNT) + if (wCtrPin != PINS_COUNT) { - pinMode(wCtrPin, INPUT); - lastVals |= (getPinVal(wCtrPin) ? LASTWCTRLSTATE : 0); - lastVals |= (getPinVal(wCtrPin) ? LASTWCTRLSTATE_ALL : 0); + setupInPin(wCtrPin); + lastVals |= (readInPin(wCtrPin) ? LASTWCTRLSTATE : 0); + lastVals |= (readInPin(wCtrPin) ? LASTWCTRLSTATE_ALL : 0); } - if (wMaxPin >= 0 && wMaxPin < PINS_COUNT) { - pinMode(wMaxPin, INPUT); - lastVals |= (publishBooleanState("$wMax", getPinVal(wMaxPin)) ? LASTWMAXSTATE : 0); + if (wMaxPin != PINS_COUNT) { + setupInPin(wMaxPin); + lastVals |= (publishBooleanState("/$wMax", readInPin(wMaxPin)) ? LASTWMAXSTATE : 0); } - if (wMinPin >= 0 && wMinPin < PINS_COUNT) { - pinMode(wMinPin, INPUT); - lastVals |= (publishBooleanState("$wMin", getPinVal(wMinPin)) ? LASTWMINSTATE : 0); + if (wMinPin != PINS_COUNT) { + setupInPin(wMinPin); + lastVals |= (publishBooleanState("/$wMin", readInPin(wMinPin)) ? LASTWMINSTATE : 0); } - if (fbDrenPin >= 0 && fbDrenPin < PINS_COUNT) { - pinMode(fbDrenPin, INPUT); - lastVals |= (publishBooleanState("$fbDren", getPinVal(fbDrenPin)) ? LASTFBDRENSTATE : 0); + if (fbDrenPin != PINS_COUNT) { + setupInPin(fbDrenPin); + lastVals |= (publishBooleanState("/$fbDren", readInPin(fbDrenPin)) ? LASTFBDRENSTATE : 0); } - if (fbPumpPin >= 0 && fbPumpPin < PINS_COUNT) { - pinMode(fbPumpPin, INPUT); - lastVals |= (publishBooleanState("$fbPump", getPinVal(fbPumpPin)) ? LASTFBPUMPSTATE : 0); + if (fbPumpPin != PINS_COUNT) { + setupInPin(fbPumpPin); + lastVals |= (publishBooleanState("/$fbPump", readInPin(fbPumpPin)) ? LASTFBPUMPSTATE : 0); } setValToJson(gatesObj, "@lastVals", (long)lastVals); @@ -133,39 +135,18 @@ int out_sprinkler::Stop() debugSerial << F("SPRINKLER: stop") << endl; turnOffAllZones(); pump(false); + dren(false); setOutput(vinPin, false); - setOutput(drenPin, false); - setOutput(pumpPin, false); setStatus(CST_UNKNOWN); return 1; } -/* -int out_sprinkler::Status() -{ - if (!item || !gatesObj) return 0; - bool wMax = (wMaxPin >= 0) ? getPinVal(wMaxPin) : false; - bool wMin = (wMinPin >= 0) ? getPinVal(wMinPin) : false; - bool fbDren = (fbDrenPin >= 0) ? getPinVal(fbDrenPin) : false; - bool fbPump = (fbPumpPin >= 0) ? getPinVal(fbPumpPin) : false; - - publishBooleanStateIfChanged("$wMax", wMax, lastWMaxState); - publishBooleanStateIfChanged("$wMin", wMin, lastWMinState); - publishBooleanStateIfChanged("$fbDren", fbDren, lastFbDrenState); - publishBooleanStateIfChanged("$fbPump", fbPump, lastFbPumpState); - - int state = getIntFromJson(gatesObj, "@state", SP_UNKNOWN); - publishNumericState("$state", state); - - return 1; -} -*/ bool out_sprinkler::isFreeze() { if (!item) return false; - return ((item->getFlag(FLAG_FREEZED) & FLAG_FREEZED) == FLAG_FREEZED); + return (item->getFlag(FLAG_FREEZED)); } bool out_sprinkler::isNeedPump(bool steelNeed) @@ -195,8 +176,27 @@ bool out_sprinkler::isNeedPump(bool steelNeed) void out_sprinkler::pump(bool state) { if (!isValidControlPin(pumpPin)) return; + uint32_t lastVals = getIntFromJson (gatesObj, "@lastVals", 0); setOutput(pumpPin, state); - publishBooleanState("$rPump", state); + if (state != (bool)(lastVals & LASTPUMPSTATE)) + { + if(state) lastVals |= LASTPUMPSTATE; else lastVals &= ~LASTPUMPSTATE; + setValToJson(gatesObj, "@lastVals", (long)lastVals); + publishBooleanState("/$rPump", state); + } +} + +void out_sprinkler::dren(bool state) +{ + if (!isValidControlPin(drenPin)) return; + uint32_t lastVals = getIntFromJson (gatesObj, "@lastVals", 0); + setOutput(drenPin, state); + if (state != (bool)(lastVals & LASTDRENSTATE)) + { + if(state) lastVals |= LASTDRENSTATE; else lastVals &= ~LASTDRENSTATE; + setValToJson(gatesObj, "@lastVals", (long)lastVals); + publishBooleanState("/$rDren", state); + } } void out_sprinkler::turnOffAllZones() @@ -207,7 +207,7 @@ void out_sprinkler::turnOffAllZones() { if (zone->name && *zone->name && zone->type == aJson_Object) { - short pin = getIntFromJson(zone, "pin", -1); + short pin = getIntFromJson(zone, "pin", PINS_COUNT); setOutput(pin, false); if (getIntFromJson(zone, "@active", 0)) { @@ -225,12 +225,78 @@ void out_sprinkler::turnOffValves() setOutput(drenPin, false); } -void out_sprinkler::notifyState(short state) +//void out_sprinkler::notifyState(short state) +//{ +// if (!gatesObj) return; +// setValToJson(gatesObj, "@state", (long)state); +// publishNumericState("$state", state); +//} + + + +void out_sprinkler::notifyState(short state) { +char val[16]; +long fault = 0; + if (!gatesObj) return; setValToJson(gatesObj, "@state", (long)state); - publishNumericState("$state", state); + +aJsonObject *faultObj = aJson.getArrayItem(item->itemArg, 3); +switch (state) { + + case SP_OFF: + strcpy(val,"OFF"); + break; + + case SP_DREN_ON: + strcpy(val,"DREN_ON"); + break; + + case SP_DREN_OPERATE: + strcpy(val,"DREN_OPERATE"); + break; + + case SP_DREN_EMPTY: + strcpy(val,"DREN_EMPTY"); + break; + + case SP_VIN: + strcpy(val,"VIN"); + break; + case SP_FULL: + + strcpy(val,"FULL"); + break; + + case SP_FAULT_VIN: + strcpy(val,"FAULT_VIN"); + fault = 1; + break; + + case SP_FAULT_DREN: + strcpy(val,"FAULT_DREN"); + fault = 2; + break; + + + default: + strcpy(val,"UNKNOWN"); + break; + } +//if (fault) strcpy(val,"FAULT"); + +if (faultObj) + { + executeCommand(faultObj,-1,itemCmd().Int((int32_t) fault)); + } + else publishTopic(item->itemArr->name,fault,"/$fault"); + +publishTopic(item->itemArr->name,val,"/$state"); +} + + int out_sprinkler::shutdown(sprinklerState nextState) { @@ -268,8 +334,8 @@ int out_sprinkler::shutdown(sprinklerState nextState) break; } - publishBooleanState("$rDren", nextState == SP_DREN_ON || nextState == SP_DREN_OPERATE); - publishBooleanState("$vIN", nextState == SP_VIN); + publishBooleanState("/$rDren", nextState == SP_DREN_ON || nextState == SP_DREN_OPERATE); + publishBooleanState("/$vIN", nextState == SP_VIN); notifyState(nextState); return 1; } @@ -311,14 +377,17 @@ inline aJsonObject * out_sprinkler::findNextZone() return NULL; } +/* + +*/ void out_sprinkler::setZoneActive(aJsonObject * zone, bool active) { if (!zone) return; setValToJson(zone, "@active", (long)(active ? 1 : 0)); char subItem[48]; - snprintf(subItem, sizeof(subItem), "%s/$state", zone->name); - item->SendStatusImmediate(itemCmd().Cmd(active ? CMD_ON : CMD_OFF).setSuffix(S_CMD), FLAG_COMMAND, subItem); + snprintf(subItem, sizeof(subItem), "/%s/$state", zone->name); + publishTopic(item->itemArr->name, active ? "ON": "OFF", subItem); } void out_sprinkler::updateZoneValue(aJsonObject * zone, long value) @@ -336,7 +405,7 @@ void out_sprinkler::updateCounterValue() if (!gatesObj) return; long current = getIntFromJson(gatesObj, "@wCtr", 0); current += value; - setValToJson(gatesObj, "wCtr", current); + setValToJson(gatesObj, "@wCtr", current); item->SendStatusImmediate(itemCmd().Int(current).setSuffix(S_SET), FLAG_PARAMETERS); } @@ -344,15 +413,11 @@ void out_sprinkler::updateCounterValue() bool out_sprinkler::publishBooleanState(const char * subItem, bool state) { if (!item) return state; - item->SendStatusImmediate(itemCmd().Cmd(state ? CMD_ON : CMD_OFF).setSuffix(S_CMD), FLAG_COMMAND, (char *)subItem); + + publishTopic(item->itemArr->name,state ? "ON": "OFF", subItem); return state; } -void out_sprinkler::publishNumericState(const char * subItem, long value) -{ - if (!item) return; - item->SendStatusImmediate(itemCmd().Int(value).setSuffix(S_SET), FLAG_PARAMETERS, (char *)subItem); -} int out_sprinkler::Poll(short cause) { @@ -360,17 +425,17 @@ int out_sprinkler::Poll(short cause) bool freeze = isFreeze(); - bool wMax = (wMaxPin >= 0) ? getPinVal(wMaxPin) : false; - bool wMin = (wMinPin >= 0) ? getPinVal(wMinPin) : false; - bool fbDren = (fbDrenPin >= 0) ? getPinVal(fbDrenPin) : false; - bool fbPump = (fbPumpPin >= 0) ? getPinVal(fbPumpPin) : false; + bool wMax = (wMaxPin != PINS_COUNT) ? readInPin(wMaxPin) : false; + bool wMin = (wMinPin != PINS_COUNT) ? readInPin(wMinPin) : false; + bool fbDren = (fbDrenPin != PINS_COUNT) ? readInPin(fbDrenPin) : false; + bool fbPump = (fbPumpPin != PINS_COUNT) ? readInPin(fbPumpPin) : false; uint32_t lastVals = getIntFromJson(gatesObj, "@lastVals", 0); - publishBooleanStateIfChanged("$wMax", wMax, LASTWMAXSTATE, lastVals); - publishBooleanStateIfChanged("$wMin", wMin, LASTWMINSTATE, lastVals); - publishBooleanStateIfChanged("$fbDren", fbDren, LASTFBDRENSTATE, lastVals); - publishBooleanStateIfChanged("$fbPump", fbPump, LASTFBPUMPSTATE, lastVals); + publishBooleanStateIfChanged("/$wMax", wMax, LASTWMAXSTATE, lastVals); + publishBooleanStateIfChanged("/$wMin", wMin, LASTWMINSTATE, lastVals); + publishBooleanStateIfChanged("/$fbDren", fbDren, LASTFBDRENSTATE, lastVals); + publishBooleanStateIfChanged("/$fbPump", fbPump, LASTFBPUMPSTATE, lastVals); uint32_t now = millisNZ(); int state = getIntFromJson(gatesObj, "@state", SP_UNKNOWN); @@ -378,9 +443,9 @@ int out_sprinkler::Poll(short cause) bool lastWctrlState = lastVals & LASTWCTRLSTATE; bool lastWctrlStateAll = lastVals & LASTWCTRLSTATE_ALL; - if (wCtrPin >= 0) + if (wCtrPin != PINS_COUNT) { - bool curr = getPinVal(wCtrPin); + bool curr = readInPin(wCtrPin); if (curr && !lastWctrlStateAll) { updateCounterValue(); @@ -520,7 +585,7 @@ int out_sprinkler::Poll(short cause) break; } - bool tankReady = (state == SP_FULL || wMax); + bool tankReady = (state == SP_FULL || wMax || wMin || fbPump); bool needPump = false; aJsonObject * currentZone = NULL; @@ -543,14 +608,14 @@ int out_sprinkler::Poll(short cause) { turnOffAllZones(); setZoneActive(currentZone, true); - short zonePin = getIntFromJson(currentZone, "pin", -1); + short zonePin = getIntFromJson(currentZone, "pin", PINS_COUNT); setOutput(zonePin, true); setValToJson(gatesObj, "@flowTimer", (long)now); } - if (wCtrPin >= 0) + if (wCtrPin != PINS_COUNT) { - bool curr = getPinVal(wCtrPin); + bool curr = readInPin(wCtrPin); if (curr && !lastWctrlState) { updateZoneValue(currentZone, 1); @@ -571,10 +636,10 @@ int out_sprinkler::Poll(short cause) if (setVal > 0 && valVal >= setVal) { - setOutput(getIntFromJson(currentZone, "pin", -1), false); + setOutput(getIntFromJson(currentZone, "pin", PINS_COUNT), false); setZoneActive(currentZone, false); //////setValToJson(currentZone, "cmd", (long)CMD_OFF); - item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF).setSuffix(S_CMD), FLAG_COMMAND, currentZone->name); + //item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF).setSuffix(S_CMD), FLAG_COMMAND, currentZone->name); currentZone = findNextZone(); } @@ -610,29 +675,37 @@ int out_sprinkler::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authori { if (!item || !gatesObj) return 0; int suffixCode = cmd.isCommand() ? S_CMD : cmd.getSuffix(); + debugSerial << "SPRINKLER: CTRL " << subItem << " "<< "Execute:"<< toExecute << " "; cmd.debugOut(); + bool sendStatus = isNotRetainingStatus(); if (subItem && *subItem) { aJsonObject * zone = getZone(subItem); if (!zone) return 0; - +///// FOR ZONES switch (suffixCode) { case S_SET: - if (toExecute) +// if (toExecute) { long value = cmd.getInt(); setValToJson(zone, "set", value); - item->SendStatusImmediate(itemCmd().Int(value).setSuffix(S_SET), FLAG_PARAMETERS, subItem); + if (sendStatus) + { + item->SendStatusImmediate(itemCmd().Int(value).setSuffix(S_SET), FLAG_PARAMETERS, subItem); + } } return 1; case S_VAL: - if (toExecute) +// if (toExecute) { long value = cmd.getInt(); setValToJson(zone, "val", value); - item->SendStatusImmediate(itemCmd().Int(value).setSuffix(S_VAL), FLAG_PARAMETERS, subItem); + if (sendStatus) + { + item->SendStatusImmediate(itemCmd().Int(value).setSuffix(S_VAL), FLAG_PARAMETERS, subItem); + } } return 1; @@ -641,27 +714,28 @@ int out_sprinkler::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authori switch (cmd.getCmd()) { case CMD_ON: - if (toExecute) - { - setValToJson(zone, "cmd", (long)CMD_ON); + setValToJson(zone, "cmd", (long)CMD_ON); + if (sendStatus) + { item->SendStatusImmediate(itemCmd().Cmd(CMD_ON).setSuffix(S_CMD), FLAG_COMMAND, subItem); } return 1; case CMD_OFF: - if (toExecute) + setValToJson(zone, "cmd", (long)CMD_OFF); + setZoneActive(zone, false); + setOutput(getIntFromJson(zone, "pin", PINS_COUNT), false); + + if (sendStatus) { - setValToJson(zone, "cmd", (long)CMD_OFF); - setZoneActive(zone, false); - setOutput(getIntFromJson(zone, "pin", -1), false); item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF).setSuffix(S_CMD), FLAG_COMMAND, subItem); } return 1; case CMD_RESET: - if (toExecute) + setValToJson(zone, "val", (long)0); + if (sendStatus) { - setValToJson(zone, "val", (long)0); item->SendStatusImmediate(itemCmd().Int(0).setSuffix(S_VAL), FLAG_PARAMETERS, subItem); } return 1; @@ -671,7 +745,7 @@ int out_sprinkler::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authori } } } - +/// FOR SPRINKLER CONTROLLER switch (suffixCode) { case S_CMD: @@ -683,6 +757,7 @@ int out_sprinkler::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authori case CMD_OFF: turnOffAllZones(); pump(false); + //dren(false); return 1; case CMD_RESET: @@ -693,7 +768,10 @@ int out_sprinkler::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authori if (zone->name && *zone->name && zone->type == aJson_Object) { setValToJson(zone, "val", (long)0); - item->SendStatusImmediate(itemCmd().Int(0).setSuffix(S_VAL), FLAG_PARAMETERS, zone->name); + if (sendStatus) + { + item->SendStatusImmediate(itemCmd().Int(0).setSuffix(S_VAL), FLAG_PARAMETERS, zone->name); + } } zone = zone->next; } @@ -706,39 +784,44 @@ int out_sprinkler::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authori break; case S_SET: - if (toExecute) - { + { + debugSerial << F("SPRINKLER: set wCtr to ") << cmd.getInt() << endl; long value = cmd.getInt(); setValToJson(gatesObj, "@wCtr", value); + + if (sendStatus) + { + item->SendStatusImmediate(itemCmd().Int(0).setSuffix(S_SET), FLAG_PARAMETERS); } return 1; - + } case S_VAL: - if (toExecute) - { + { + debugSerial << F("SPRINKLER: ext temperature: ") << cmd.getInt() << endl; long value = cmd.getInt(); if (value < 0) { item->setFlag(FLAG_FREEZED); item->SendStatus(FLAG_FLAGS); } - else if (isFreeze()) - { - item->clearFlag(FLAG_FREEZED); - item->SendStatus(FLAG_FLAGS); - } - } +// else if (isFreeze()) +// { + // item->clearFlag(FLAG_FREEZED); + // item->SendStatus(FLAG_FLAGS); + // } + return 1; + } - default: - break; + // default: + // break; } return 0; } int out_sprinkler::getChanType() { - return CH_RELAY; + return CH_COUNTER; } #endif // SPRINKLER_ENABLE \ No newline at end of file diff --git a/lighthub/modules/out_sprinkler.h b/lighthub/modules/out_sprinkler.h index ffc71fa..2a1ef2e 100644 --- a/lighthub/modules/out_sprinkler.h +++ b/lighthub/modules/out_sprinkler.h @@ -15,6 +15,8 @@ #define LASTWMINSTATE 8 #define LASTFBDRENSTATE 16 #define LASTFBPUMPSTATE 32 +#define LASTPUMPSTATE 64 +#define LASTDRENSTATE 128 enum sprinklerState { SP_UNKNOWN = 0, @@ -48,6 +50,7 @@ protected: void pump(bool state); + void dren(bool state); void setOutput(short pin, bool value); bool isNeedPump(bool steelNeed=false); void turnOffValves(); diff --git a/lighthub/utils.cpp b/lighthub/utils.cpp index c123ff5..8e69e9f 100644 --- a/lighthub/utils.cpp +++ b/lighthub/utils.cpp @@ -1136,5 +1136,54 @@ return NULL; } + +void setupInPin(short pin) +{ + if (abs(pin)>=PINS_COUNT) + { + debugSerial<=PINS_COUNT) + { + debugSerial<=PINS_COUNT) + { + debugSerial<