Post hier je geavanceerde NodeRED flows

Plaats reactie
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

Misschien eens interessant om een topic te beginnen waarin je je complexe NodeRED flows kan posten en uitleggen.
Ik zal beginnen met mijn flow voor verlichting :-)

Probleemstelling:
De verlichting moet automatisch gestuurd worden op basis van een aantal parameters:
  • Donker
  • Tijd/dag (variaties op feestdagen)
  • Home/Away (op basis van de status van mijn alarmsysteem)
  • Slaapmodus actief ?
  • Holiday mode
Dit kan ook redelijk simpel met gewone YAML en scenes, maar daar stoorde ik mij aan de overgang van de verschillende scene's. Bijvoorbeeld, als we 's avonds vertrekken, dan moet bepaalde verlichting aanblijven (afwezigheidsverlichting), terwijl alle andere verlichting uit moet. Dit is op te lossen door eerst all lights off, en dan de scene te activeren, maar dan gingen sommige lichten dus van aan naar uit naar terug aan. Ik kan me daar mateloos aan ergeren :-)

Ook wil ik (sommige gevallen) niet dat als bv de spots op 40% ingesteld staan en een andere scene wordt actief, dat de spots dan naar 20% gaan omdat dat zo in die scene ingesteld is. Ik kan bij lampen een minimale brightness instellen: is de brightness beneden die waarde, dan wordt die aangepast. Is ie hoger, dan blijft ie zo.

Uitleg:
De 3 groene timers zijn gedefinieerd voor verschillende tijdstippen:
  • Weekdagen (uitgezonderd feestdagen)
  • Weekend (uitgezonderd feestdagen)
  • Feestdagen (kerstavond, kerstmis, oudejaar, nieuwjaar). Op deze dagen moet de afwezigheidsverlichting langer branden
Flow store time_lights_off slaat de on/off tijden van de actieve timer op, zodat die gebruikt kunnen worden in de vakantiemodus. Wanneer het donker is, gaan die lampen op willekeurige tijdstippen met een variabele duur en random aantal keer aan/uit tussen deze tijdstippen.

De 3 timers (waarvan er maar 1 per keer actief is), worden boolean ge'ORd. Deze timers geven aan of de afwezigheidsverlichting actief moet zijn wanneer we niet thuis zijn, of dat de lampen uitgeschakeld worden. Als we thuis zijn en deze timers worden inactief, dan blijven de lampen dus gewoon aan.

Het traffic light zorgt ervoor dat ik makkelijk de hele flow kan disablen.

All verlichting uit behalve spots keuken en Group to entities (subflow): Deze zorgen ervoor dat ik makkelijk alle lampen kan uitdoen, met uitzondering van een aantal lampen.

Spots rondom min 15% (subflow): Hiermee kan ik makkelijk een minimale brightness instellen van een lamp. Als die op het moment van uitvoeren hoger is dan de ingestelde waarde, gebeurd er niets.

Zoals je ziet maak ik veel gebruik van link nodes, om de flow overzichtelijk te houden. De statemachine bepaald op basis van de inputs welke 'scene' actief is.
Bijlagen
verlichting.png
Gebruikersavatar
devilkin
Elite Poster
Elite Poster
Berichten: 4884
Lid geworden op: 17 mei 2006, 20:10
Uitgedeelde bedankjes: 551 keer
Bedankt: 341 keer
Contacteer:

Whoa. Nice!

Kan je eventueel eens de inhoud van je state machine tonen? Ik ben nog wat aan't puzzelen hoe ik die zelf zou gebruiken - al denk ik dat ik momenteel al zelf state machines onderhou in function nodes ;) maar die mogelijks wel te vereenvoudigen zijn?

De boolean node, die heb je zelf geinstalleerd vermoed ik?
Telenet All-Internet -- using CV8560E & OPNsense on PCEngines APU2E4
Proximus & Mobile Vikings -- Using OnePlus 8 Pro (ROM: Stock)
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

Dit is mijn statemachine. Belangrijk is dat je alle binnekomende states onthoudt (opslaat), omdat die mogelijk niet nu maar pas later van toepassing zijn.

Die boolean logic is inderdaad een node die je apart moet installeren. Andere nodes die ik veelvuldig gebruik:

Code: Selecteer alles

context.data = context.data || {
    "alarm": null,
    "donker": null,
    "slapen": null,
    "vakantie": null,
    "avondverlichting": null,
}

var slapenNetActief = false;

switch (msg.topic)
{
    case "alarm":
        context.data.alarm = msg.payload;
        break;
    case "donker":
        context.data.donker = msg.payload;
        break;
    case "slapen":
        if (context.data.slapen === false && msg.payload)
            slapenNetActief = true;
        context.data.slapen = msg.payload;
        break;
    case "vakantie":
        context.data.vakantie = msg.payload;
        break;
    case "avondverlichting":
        context.data.avondverlichting = msg.payload;
        break;
}

if (context.data.alarm !== null &&
    context.data.donker !== null &&
    context.data.slapen !== null &&
    context.data.vakantie !== null)
{
    var status = "";
    
    if (slapenNetActief)
    {
        status = "Naar bed gaan";
    }
    else if (context.data.vakantie && context.data.donker && context.data.alarm && context.data.avondverlichting)
    {
        status = "Vakantie - lichten aan";
    }
    else if (context.data.vakantie && context.data.donker && context.data.alarm && !context.data.avondverlichting)
    {
        status = "Vakantie - lichten uit";
    }
    else if (!context.data.donker && !context.data.alarm)
    {
        status = "Aanwezig - lichten uit (overdag)";
    }
    else if (!context.data.donker && context.data.alarm)
    {
        status = "Afwezig - lichten uit (overdag)";
    }
    else if (context.data.donker && context.data.alarm && context.data.slapen)
    {
        status = "Slapen - lichten uit";
    }
    else if (!context.data.avondverlichting && context.data.donker && context.data.alarm)
    {
        status = "Nacht - lichten uit";
    }
    else if (context.data.donker && !context.data.alarm && !context.data.slapen)
    {
        status = "Aanwezig - lichten aan";
    }
    else if (context.data.donker && context.data.alarm && context.data.avondverlichting && !context.data.slapen)
    {
        status = "Afwezig - lichten aan";
    }
    node.status({fill:"green",shape:"dot",text: status});
    
    return { "payload": status };
}
else
{
    node.status({fill:"red",shape:"ring",text: "Undefined"});
}
return null;
Gebruikersavatar
devilkin
Elite Poster
Elite Poster
Berichten: 4884
Lid geworden op: 17 mei 2006, 20:10
Uitgedeelde bedankjes: 551 keer
Bedankt: 341 keer
Contacteer:

Wat doe je eigenlijk in die 'net slapen gaan' flow? (en hoe trigger je die?)
Telenet All-Internet -- using CV8560E & OPNsense on PCEngines APU2E4
Proximus & Mobile Vikings -- Using OnePlus 8 Pro (ROM: Stock)
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

Die staat gedeeltelijk onderaan in mn screenshot. Wat er dan gebeurt:
  • Alle lichten beneden gaan uit, met uitzondering van de gang, keuken, ... Eigenlijk dus het pad om naar boven te gaan. De lampen die uitgezonderd zijn gaan zachtjes aan naar een bepaald minimum niveau
  • In de slaapkamer gaan de lachtlampen aan, op basis van wie thuis is en nog niet in bed. Ik blijf laat op (dagelijks tot rond 1u), mijn vrouw gaat vroeger naar bed. Als ik dan ga slapen, gaat haar nachtlamp niet branden. Als ik niet thuis ben, gaat mijn nachtlamp niet branden.
  • Speciale modus voor mn bewegingssensoren. Als er dan gedurende 2 minuten beneden geen beweging gedecteerd is, wordt het alarm ingeschakeld.
Die modus wordt geactiveerd middels Google Assistant (Hey google, activeer slapen), of vanuit de UI. Ik probeer de UI zoveel mogelijk te vermijden. Dan wordt een input_boolean op true gezet (die wordt 's morgen weer uit gezet als het alarm uitgeschakeld wordt). Die input_boolean triggerd op zich nog een aantal andere automations die ik in YAML gehouden heb omdat ze te simpel zijn:
  • TV uitschakelen
  • Sonos uitschakelen
  • Veranderen van profiel van mn camerasysteem.
Gebruikersavatar
Goztow
userbase crew
userbase crew
Berichten: 13588
Lid geworden op: 14 nov 2006, 16:21
Locatie: Brussel
Uitgedeelde bedankjes: 1422 keer
Bedankt: 878 keer

Super! Kan je ook één maken van eenvoudige? Dan kan ik daarmee starten :lol:
Bedank andere users voor nuttige posts, door op Afbeelding te klikken
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

Deze ;-)
Sonos opzetten wanneer het alarm wordt uitgeschakeld, maar met een variabel volume. Ik heb een andere zender voorkeur dan mn vrouw, dus als zij niet thuis is, is het dansmuziek ;-)
Bijlagen
sonos.png
Gebruikersavatar
MaT
Elite Poster
Elite Poster
Berichten: 1888
Lid geworden op: 18 feb 2014, 15:40
Locatie: Gent
Uitgedeelde bedankjes: 161 keer
Bedankt: 282 keer

Als je geen persoonlijke info in je flow hebt kan je die ook exporteren als gewone tekst he mannen. Deze kan je dan gewoon posten hier als code en dan hebben wij maar te importeren in node red ipv alles na te bouwen ;)
-Met name de kosten in verband met de eindapparatuur (modem, settopbox, ...) zouden beperkt kunnen worden, als die toestellen hergebruikt zouden kunnen worden of vrij gekozen worden door de klant- Bron
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

MaT schreef:Als je geen persoonlijke info in je flow hebt kan je die ook exporteren als gewone tekst he mannen. Deze kan je dan gewoon posten hier als code en dan hebben wij maar te importeren in node red ipv alles na te bouwen ;)
Ik zal mijn subflows hier wel eens delen.

Deze flow heb ik voor een andere gebruiker op het forum gemaakt hier. Volledige aansturing van klimatisatie: ventilatie, koeling en bevochtigers. Dit om het verbruik van de ventilatieunit te beperken (het betreft 2 units, 1 voor iedere woning).
Sturing is op basis van:
  • Iemand thuis ? Of wanneer op vakantie en de buurman komt kijken: op basis van de sloten van de dru
  • CO2 niveau
  • Luchtvochtigheid
  • Manuele preset
  • Binnen vs buitentemperatuur
  • ...
En dan opnieuw een statemachine om te bepalen in welke modus de ventilatie moet zijn (off/low/medium/high). Custom threshold function nodes omdat ik niet tevreden was met de standaard nodes :-)

Code: Selecteer alles

context.data = context.data || false;
var result = context.data;

if (msg.payload >= msg.upper)
{
  result = true;
}
else if (msg.payload <= msg.lower)
{
  result = false;
}

context.data = result;
msg.payload = result;
node.status({fill: result ? "green" : "red",shape:"dot",text: result});
return msg;
Bijlagen
klimaatsturing.png
Gebruikersavatar
devilkin
Elite Poster
Elite Poster
Berichten: 4884
Lid geworden op: 17 mei 2006, 20:10
Uitgedeelde bedankjes: 551 keer
Bedankt: 341 keer
Contacteer:

Holy F. Ik dacht dat sommige van de mijne al groot werden ;)
Telenet All-Internet -- using CV8560E & OPNsense on PCEngines APU2E4
Proximus & Mobile Vikings -- Using OnePlus 8 Pro (ROM: Stock)
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

Een 32' ultrawidescreen helpt om het overzicht te houden :lol:
Gebruikersavatar
devilkin
Elite Poster
Elite Poster
Berichten: 4884
Lid geworden op: 17 mei 2006, 20:10
Uitgedeelde bedankjes: 551 keer
Bedankt: 341 keer
Contacteer:

In opbouw:

Afbeelding

Beheer van lampen, adhv 3 inputs:
* sunset event
* motion detector event
* button presses op de ikea tradfri remote

Gebruik makende van 3 subflows om de lampen af/aan te zetten. Was even puzzelen maar 't is leuk speelgoed ;)
Telenet All-Internet -- using CV8560E & OPNsense on PCEngines APU2E4
Proximus & Mobile Vikings -- Using OnePlus 8 Pro (ROM: Stock)
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

Zie ik daar een state machine? :wink:
Gebruikersavatar
devilkin
Elite Poster
Elite Poster
Berichten: 4884
Lid geworden op: 17 mei 2006, 20:10
Uitgedeelde bedankjes: 551 keer
Bedankt: 341 keer
Contacteer:

Yeah. Een hoop flows in 1 gemigreerd. 'k moet het wel allemaal nog es goed testen...
Telenet All-Internet -- using CV8560E & OPNsense on PCEngines APU2E4
Proximus & Mobile Vikings -- Using OnePlus 8 Pro (ROM: Stock)
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

Mijn eerste subflow: Xiaomi Remote Click counter
xiaomi.png
xiaomi.png (5.35 KiB) 860 keer bekeken
Ik heb een aantal Xiaomi aqara switches. Een annoyance die ik daar heb ik dat een dubbele klik interval wat lang is, waardoor als ik bv soms 2x heel snel 1x duw, hij het als 2x een enkele press ziet ipv een dubbele.

Deze flow lost dat op, ten koste van een extra delay van 100ms. Hij telt gewoon het aantal keer dat je gedrukt hebt en geeft daarna het resultaat terug. Hierdoor kan ik nu dus ook makkelijk flows maken waarin er 1-999999999 keer op de knop geduwd moet worden, terwijl de originele switch max 4 presses aan kan.

Code: Selecteer alles

[{"id":"fdf47ee3.6ba08","type":"subflow","name":"Xiaomi Remote Click","info":"","category":"","in":[{"x":45,"y":75,"wires":[{"id":"67e66414.a0b91c"}]}],"out":[{"x":520,"y":75,"wires":[{"id":"4466519a.f490a","port":0}]}],"env":[]},{"id":"4466519a.f490a","type":"timed-counter","z":"fdf47ee3.6ba08","name":"","timelimit":"100","timeunit":"1","withhold":true,"fixedtimeout":false,"pertopic":false,"x":380,"y":75,"wires":[[]]},{"id":"67e66414.a0b91c","type":"function","z":"fdf47ee3.6ba08","name":"","func":"let num = 0;\nvar output = [null, null, null, null];\n\nswitch (msg.payload.event.event)\n{\n    case 1002: num = 1; break;\n    case 1004: num = 2; break;\n    case 1005: num = 3; break;\n    case 1006: num = 4; break;\n}\n\nfor (var i = 0; i < num; i++)\n    output[i] = msg;\n\nreturn output;","outputs":4,"noerr":0,"x":200,"y":75,"wires":[["4466519a.f490a"],["4466519a.f490a"],["4466519a.f490a"],["4466519a.f490a"]]}]
devastator
Elite Poster
Elite Poster
Berichten: 1218
Lid geworden op: 01 nov 2005, 10:53
Locatie: Pelt
Uitgedeelde bedankjes: 27 keer
Bedankt: 56 keer

Minimal brightness: Verander de helderheid van een lamp enkel en alleen wanneer ie uit staat of kleiner is dan het opgegeven percentage.
minbrightness.png

Code: Selecteer alles

[{"id":"b24b480a.845eb8","type":"subflow","name":"Set minimum brightness","info":"Changes the brightness of an entity only if the current brightness is lower than the requested brightness","category":"","in":[{"x":45,"y":75,"wires":[{"id":"fc99524c.fa17e"}]}],"out":[{"x":1270,"y":25,"wires":[{"id":"5202d7e9.81385","port":0}]}],"env":[{"name":"ENTITY_ID","type":"str","value":""},{"name":"BRIGHTNESS_PCT","type":"num","value":""},{"name":"TRANSITION","type":"num","value":"0"}],"color":"#E2D96E","icon":"font-awesome/fa-lightbulb-o"},{"id":"fc99524c.fa17e","type":"api-current-state","z":"b24b480a.845eb8","name":"","server":"98e45af.82949a8","version":1,"outputs":1,"halt_if":"","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"${ENTITY_ID}","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":215,"y":75,"wires":[["e65343c.c3397c"]]},{"id":"e65343c.c3397c","type":"switch","z":"b24b480a.845eb8","name":"on/off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":425,"y":75,"wires":[["82c84a26.fc0098"],["4fc93404.2d9654"]]},{"id":"351c0ab9.0161f6","type":"api-call-service","z":"b24b480a.845eb8","name":"","server":"98e45af.82949a8","version":1,"debugenabled":false,"service_domain":"light","service":"turn_on","entityId":"${ENTITY_ID}","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1065,"y":100,"wires":[["5202d7e9.81385"]]},{"id":"f36dea0b.9388a8","type":"switch","z":"b24b480a.845eb8","name":"","property":"data.attributes.brightness_pct","propertyType":"msg","rules":[{"t":"gte","v":"BRIGHTNESS_PCT","vt":"env"},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":725,"y":50,"wires":[["5202d7e9.81385"],["4fc93404.2d9654","5202d7e9.81385"]]},{"id":"82c84a26.fc0098","type":"function","z":"b24b480a.845eb8","name":"percentage","func":"var brightness = 255;\n\ntry {\n  brightness = msg.data.attributes.brightness;\n}\ncatch(error) {\n  node.error(error);\n}\n\nmsg.data.attributes.brightness_pct = Math.round(brightness * 100 / 255);\nreturn msg;","outputs":1,"noerr":0,"x":570,"y":50,"wires":[["f36dea0b.9388a8"]]},{"id":"4fc93404.2d9654","type":"function","z":"b24b480a.845eb8","name":"","func":"TRANSITION = env.get(\"TRANSITION\");\nBRIGHTNESS = env.get(\"BRIGHTNESS_PCT\")\n\nmsg = {}\nmsg.payload = {}\nmsg.payload.data = {}\n\nmsg.payload.data[\"brightness\"] = BRIGHTNESS;\nif (TRANSITION > 0)\n    msg.payload.data[\"transition\"] = TRANSITION;\n\nreturn msg;","outputs":1,"noerr":0,"x":875,"y":100,"wires":[["351c0ab9.0161f6"]]},{"id":"5202d7e9.81385","type":"function","z":"b24b480a.845eb8","name":"clear","func":"msg = {}\n\nreturn msg;","outputs":1,"noerr":0,"x":1175,"y":25,"wires":[[]]},{"id":"98e45af.82949a8","type":"server","z":"","name":"Home Assistant","legacy":false,"hassio":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":false}]
Plaats reactie

Terug naar “Home automation en domotica”