Valve Logic #922
Unanswered
notmydayjob
asked this question in
App and O/S Config Questions
Valve Logic
#922
Replies: 1 comment 1 reply
-
Here's one possible solution that uses a custom rule processor. You can read about custom bindings in the wiki. DirectionsHere's the set up:
Here's how the front end works, and then at the bottom I'll explain the code.
Code to modify{
"context": {
"name": "customValveRule",
"options": {},
"vars": {}
},
"events": [
{
"name": "feature",
"description": "Wait 6s and turn on the waterfall pump",
"processor": [
"try {",
"let wtrFallPumpCircuit = 10; // waterfall pump circuit",
"let wtrFallOffCircuit = 130;",
"let delay = 6;",
"let scirc = state.circuits.getInterfaceById(wtrFallPumpCircuit);",
"if (scirc.isOn) return;",
"await setTimeout(() => {sys.board.circuits.setCircuitStateAsync(wtrFallPumpCircuit, true); // waterfall start/valve diverted",
"sys.board.circuits.setCircuitStateAsync(wtrFallOffCircuit, true);",
"logger.info(`Waited ${delay}s and turned off feature/valve.`)}, delay*1000);",
"} catch(err) { logger.error(`Error triggering circuit ${err.message}`); }"
],
"filter": "@bind=data.id; === 129 && @bind=data.isOn;===true;"
},
{
"name": "feature",
"description": "Wait 60s and turn off the waterfall pump",
"processor": [
"try {",
"let wtrFallPumpCircuit = 10;",
"let wtrFallOnCircuit = 129;",
"let delay = 60;",
"let scirc = state.circuits.getInterfaceById(wtrFallPumpCircuit);",
"if (!scirc.isOn) return;",
"logger.info('Overriding circuit (turned back on). Turning off pump, waiting ${delay}s and turning off feature.');",
"sys.board.circuits.setCircuitStateAsync(wtrFallPumpCircuit, false);",
"await setTimeout(() => {logger.info(`Waited ${delay}s and turning off feature/valve.`);",
"sys.board.circuits.setCircuitStateAsync(wtrFallOnCircuit, false);",
"}, delay*1000);",
"",
"} catch(err) { logger.error(`Error triggering circuit ${err.message}`); }"
],
"enabled": true,
"filter": "@bind=data.id; === 130 && @bind=data.isOn;===false;"
}
]
} Technical ExplanationThis solution uses two separate features because the rules are evaluated just after the feature is toggled. Hence, there is a need for a separate on and off feature such that we can control the delay. {
"context": {
"name": "customValveRule", // Name of the rule
"options": {},
"vars": {}
},
"events": [
{
"name": "feature", // the event type that this rule will listen for.
"description": "Wait 6s and turn on the waterfall pump", // plain text
"processor": [ // the below is a function that will be executed when the event occurs and the filter evaluates to true
"try {",
"let wtrFallPumpCircuit = 10; // waterfall pump circuit", // this turns the pump on/off and when associated with the VSF pump sets the speed
"let wtrFallOffCircuit = 130;", // replace the 130 here with the id of the feature created in step 3
"let delay = 6;", // delay in seconds. Adjust as needed.
"let scirc = state.circuits.getInterfaceById(wtrFallPumpCircuit);", // this gets the values of the waterfall pump circuit so...
"if (scirc.isOn) return;", // we check to make sure the pump is off. If it's on, we abort this code.
// the next await function will wait the delay (6) seconds and then execute the code to turn on the waterfall circuit and the waterfall off feature
"await setTimeout(() => {sys.board.circuits.setCircuitStateAsync(wtrFallPumpCircuit, true); // waterfall start/valve diverted",
"sys.board.circuits.setCircuitStateAsync(wtrFallOffCircuit, true);",
"logger.info(`Waited ${delay}s and turned off feature/valve.`)}, delay*1000);",
"} catch(err) { logger.error(`Error triggering circuit ${err.message}`); }" // end of try block to catch errors so we don't crash the app
],
"filter": "@bind=data.id; === 129 && @bind=data.isOn;===true;" // this processor will only be run when the feature event is broadcast, the circuit that is triggered is 129 (replace with the waterfall on feature), and the circuit is now on.
},
// below is very similar logic but in reverse.
{
"name": "feature",
"description": "Wait 60s and turn off the waterfall pump",
"processor": [
"try {",
"let wtrFallPumpCircuit = 10;",
"let wtrFallOnCircuit = 129;",
"let delay = 60;",
"let scirc = state.circuits.getInterfaceById(wtrFallPumpCircuit);",
"if (!scirc.isOn) return;",
// below we turn off the waterfall pump and the wtrFallOffCircuit, and then after 60s turn off the wtrFallOnCircuit (change the valve).
"logger.info('Overriding circuit (turned back on). Turning off pump, waiting ${delay}s and turning off feature.');",
"sys.board.circuits.setCircuitStateAsync(wtrFallPumpCircuit, false);",
"await setTimeout(() => {logger.info(`Waited ${delay}s and turning off feature/valve.`);",
"sys.board.circuits.setCircuitStateAsync(wtrFallOnCircuit, false);",
"}, delay*1000);",
"",
"} catch(err) { logger.error(`Error triggering circuit ${err.message}`); }"
],
"enabled": true,
"filter": "@bind=data.id; === 130 && @bind=data.isOn;===false;"
}
]
} |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I have a waterfall in my pool. It is plumbed separately for the main body plumbing. The rest of my pool is being run by the Nixie controller in njs-PC running on an RPi however, the waterfall is not currently integrated in njs-PC.
The main pool system is a shared body (pool/spa) using an intelliflo VSF controlled via serial and with valves controlled by REM. The waterfall is powered by an intelliflo VS pump that I currently control via the onboard control panel. The water leaving the pump flows through a 3-way valve that lets me direct the water to either the waterfall feature or a pool return located below the waterline.
Currently when I shut off the waterfall pump I turn the 3-way valve to the pool return before shutting off the pump this keeps the pipes full of water preventing priming problems the next time it starts. If I leave it directed to the waterfall, it sucks air and the system has to reprime. Conversely, when I start the pump I wait a moment before directing the water to the waterfall.
I would like to add a a servo to the valve and integrate the waterfall into njs-PC. I can add the pump and create a waterfall feature, however I am stuck at building the logic that, upon turning off the feature would activate the valve and wait 60 seconds (or so) before shutting down the pump. On startup the pump should start and then after a pause the valve should activate to switch to the waterfall.
Thanks in advance for any help.
Beta Was this translation helpful? Give feedback.
All reactions