Possibilité de paramétrage d'un délai avant et après les levés et coucher du soleil

Feature description
Pour l’allumage et l’extinction de lumière d’ambiance, les horaires de levés et de coucher du soleil ne correspondent pas exactement aux besoins selon l’exposition des pièces dans une maison. Un délai de part et d’autre serait très intéressant.

Il me semblait qu’il y’avait déjà une demande sur ça et qu’il y’avait une issue github mais j’ai rien trouvé.

+1 pour les lumières et volets c’est indispensable.

Yes je suis d’accord!

Pour ceux qui passent par ce topic, un délai « après » en soit c’est déjà possible il suffit d’ajouter une action « attendre » dans la scène. Pour un délai avant effectivement c’est pas possible actuellement :slight_smile:

1 « J'aime »

J’utilise actuellement « A chaque lever de soleil » pour l’ouverture des volets roulants.

Mais il fait déjà jour depuis quelques temps lorsque que ceux ci s’ouvrent.

Il existe plus de notions astronomiques : Lever du Soleil et Coucher du Soleil | Augusta

N’y aurait-il une API qui pourrait nous donner plus d’options ?

https://lunarok.github.io/jeedom_docs/plugins/heliotrope/

Je crois avoir mis la main sur quelque chose d’exploitable :

https://sunrise-sunset.org/api

Il n’y a pas toutes les options de l’heliotrope dispo sous Jeedom mais il y a bien les notions d’aube astronomique etc…

1 « J'aime »

Je suis pas sûr qu’on ait besoin de passer par une API, actuellement on fait les calculs en local :slight_smile:

Pourquoi pas ajouter d’autres calculs si besoin, tu créé une demande de fonctionnalité spécifique avec les autres calculs que tu souhaites ?

Ok ! Top… je ne me rends pas compte de tout ce qu’il se cache derrière Gladys !

Je regarde plus précisément les différentes notions ( aube/crépuscule astronomique, civile, nautique…) pour formuler quelque chose de cohérent.

2 « J'aime »

Bonjour @b3n.0 ,

En général les calculs sont effectués sur les éphémérides civiles (soleil 6° en dessous de l’horizon).

D’un point de vue affichage, une représentation intéressante par exemple est la ligne du temps sur laquelle tu viens avec un curseur allonger ou raccourcir la journée et la nuit.

Mais le risque est que, si le calcul est pris sur une date 0-24h UTC, et que l’affichage sur l’appli prend l’heure GMT du navigateur, le curseur se retrouve à cheval sur deux jours.

De plus attention, les codes de calcul utilisent souvent des algorithmes simplifiés qui deviennent moins précis au dessus du 60ème parallèle. Il serait intéressant de vérifier les calculs si quelqu’un utilise Gladys sur les stations polaires?

Gladys utilise la librairie « suncalc » qui effectue le calcul de cette manière:

Dans la même librairie, d’après ce que j’y comprends, il me semble y avoir les notions qui permettent davoir les « premières lueurs du jour » :

// sun times configuration (angle, morning name, evening name)

var times = SunCalc.times = [
    [-0.833, 'sunrise',       'sunset'      ],
    [  -0.3, 'sunriseEnd',    'sunsetStart' ],
    [    -6, 'dawn',          'dusk'        ],
    [   -12, 'nauticalDawn',  'nauticalDusk'],
    [   -18, 'nightEnd',      'night'       ],
    [     6, 'goldenHourEnd', 'goldenHour'  ]
];

@b3n.0
il y a 2 solutions, passer par node-red Mini-tuto Sun-Position Nore-red Mqtt pour piloter les volets en fonction de la position du soleil et des mois

en modifiant le flow pour avoir sunrise et sunset comme ci-dessous et en ajoutant
dans gladys dans l’appareil créé pour l’azimuth et l’altitude 2 commutateurs
correspondants qui recoit du flow node-red
gladys/master/device/mqtt:soleil/feature/mqtt:sunrise/state
gladys/master/device/mqtt:soleil/feature/mqtt:sunset/state
ensuite il y a plus qu’à le gérer dans une scène en récupérant l’état de l’appareil
dans le code de la fonction minutedepuis minuit il faut passer l’état à 1 dans le payload pour commuter et ajuster le node « delay »

Code du flow
t[
    {
        "id": "dbd46647b51191ed",
        "type": "tab",
        "label": "Sun-Position",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "a0d0e562.7ad1d8",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 1",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 720,
        "y": 180,
        "wires": []
    },
    {
        "id": "9cc2d51.4ac0828",
        "type": "change",
        "z": "dbd46647b51191ed",
        "name": "azimuth",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.azimuth",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "gladys/master/device/mqtt:soleil/feature/mqtt:azimuth/state",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 240,
        "wires": [
            [
                "0a17f9d94c9dae35",
                "ddf8b5e66052a4dc"
            ]
        ]
    },
    {
        "id": "28e91.9d63d16f6",
        "type": "change",
        "z": "dbd46647b51191ed",
        "name": "altitude",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.altitude",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "gladys/master/device/mqtt:soleil/feature/mqtt:altitude/state",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 320,
        "wires": [
            [
                "ae57174554627c71",
                "58367a9aedab25dc"
            ]
        ]
    },
    {
        "id": "e921e01a.a0fa3",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 4",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 720,
        "y": 380,
        "wires": []
    },
    {
        "id": "e866e950.a7f798",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 3",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 1160,
        "y": 180,
        "wires": []
    },
    {
        "id": "5b085e1b.4ec8a",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 6",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 1160,
        "y": 380,
        "wires": []
    },
    {
        "id": "8eee70dd77c1369c",
        "type": "mqtt out",
        "z": "dbd46647b51191ed",
        "name": "",
        "topic": "",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "3c3eb52d.9fb296",
        "x": 1150,
        "y": 280,
        "wires": []
    },
    {
        "id": "0a17f9d94c9dae35",
        "type": "function",
        "z": "dbd46647b51191ed",
        "name": "arrondi entier",
        "func": "msg.payload = Math.round(msg.payload)\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 930,
        "y": 240,
        "wires": [
            [
                "8eee70dd77c1369c",
                "e866e950.a7f798"
            ]
        ]
    },
    {
        "id": "ddf8b5e66052a4dc",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 2",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 920,
        "y": 180,
        "wires": []
    },
    {
        "id": "ae57174554627c71",
        "type": "function",
        "z": "dbd46647b51191ed",
        "name": "arrondi entier",
        "func": "msg.payload = Math.round(msg.payload)\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 930,
        "y": 320,
        "wires": [
            [
                "5b085e1b.4ec8a",
                "8eee70dd77c1369c"
            ]
        ]
    },
    {
        "id": "58367a9aedab25dc",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 5",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "true",
        "targetType": "full",
        "statusVal": "",
        "statusType": "auto",
        "x": 920,
        "y": 380,
        "wires": []
    },
    {
        "id": "56265aeb.99f034",
        "type": "sun-position",
        "z": "dbd46647b51191ed",
        "name": "",
        "positionConfig": "2831ba70.55a636",
        "rules": [
            {
                "valueLow": "0",
                "valueLowType": "num",
                "valueHigh": "360",
                "valueHighType": "num"
            }
        ],
        "onlyOnChange": "true",
        "topic": "",
        "outputs": 2,
        "start": "sunsetStart",
        "startType": "pdsTime",
        "startOffset": 0,
        "startOffsetType": "num",
        "startOffsetMultiplier": 60000,
        "end": "sunriseEnd",
        "endType": "pdsTime",
        "endOffset": 0,
        "endOffsetType": "num",
        "endOffsetMultiplier": 60000,
        "x": 470,
        "y": 280,
        "wires": [
            [
                "a0d0e562.7ad1d8",
                "9cc2d51.4ac0828",
                "28e91.9d63d16f6",
                "6b1f97b4cc4c5e53",
                "b10eedb2bb5656c1"
            ],
            [
                "e921e01a.a0fa3"
            ]
        ]
    },
    {
        "id": "664b1852987e09be",
        "type": "time-inject",
        "z": "dbd46647b51191ed",
        "name": "Période et Intervalle d'injection .",
        "nameInt": "¹sunrise start - sunset end = timestamp ↻10min",
        "positionConfig": "2831ba70.55a636",
        "props": [
            {
                "p": "",
                "pt": "msgPayload",
                "v": "",
                "vt": "date",
                "o": "",
                "oT": "none",
                "oM": "60000",
                "f": 0,
                "fS": 0,
                "fT": "UNIX timestamp (ms)",
                "fI": "0",
                "next": true,
                "days": "*",
                "months": "*",
                "onlyOddDays": false,
                "onlyEvenDays": false,
                "onlyOddWeeks": false,
                "onlyEvenWeeks": false
            },
            {
                "p": "",
                "pt": "msgTopic",
                "v": "",
                "vt": "str",
                "o": "",
                "oT": "none",
                "oM": "60000",
                "f": 0,
                "fS": 0,
                "fT": "UNIX timestamp (ms)",
                "fI": "0",
                "next": false,
                "days": "*",
                "months": "*",
                "onlyOddDays": false,
                "onlyEvenDays": false,
                "onlyOddWeeks": false,
                "onlyEvenWeeks": false
            }
        ],
        "injectTypeSelect": "interval-time",
        "intervalCount": "10",
        "intervalCountType": "num",
        "intervalCountMultiplier": 60000,
        "cron": "",
        "cronType": "cronexpr",
        "time": "sunriseStart",
        "timeType": "pdsTime",
        "offset": 0,
        "offsetType": "none",
        "offsetMultiplier": 60000,
        "timeEnd": "sunsetEnd",
        "timeEndType": "pdsTime",
        "timeEndOffset": 0,
        "timeEndOffsetType": "none",
        "timeEndOffsetMultiplier": 60000,
        "timeDays": "*",
        "timeOnlyOddDays": false,
        "timeOnlyEvenDays": false,
        "timeOnlyOddWeeks": false,
        "timeOnlyEvenWeeks": false,
        "timeMonths": "*",
        "timedatestart": "",
        "timedateend": "",
        "property": "",
        "propertyType": "none",
        "propertyCompare": "true",
        "propertyThreshold": "",
        "propertyThresholdType": "num",
        "timeAlt": "",
        "timeAltType": "entered",
        "timeAltDays": "*",
        "timeAltOnlyOddDays": false,
        "timeAltOnlyEvenDays": false,
        "timeAltOnlyOddWeeks": false,
        "timeAltOnlyEvenWeeks": false,
        "timeAltMonths": "*",
        "timeAltOffset": 0,
        "timeAltOffsetType": "none",
        "timeAltOffsetMultiplier": 60000,
        "once": true,
        "onceDelay": 0.1,
        "recalcTime": 2,
        "x": 220,
        "y": 280,
        "wires": [
            [
                "56265aeb.99f034"
            ]
        ]
    },
    {
        "id": "6b1f97b4cc4c5e53",
        "type": "change",
        "z": "dbd46647b51191ed",
        "name": "sunset",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.times.sunsetStart",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "gladys/master/device/mqtt:soleil/feature/mqtt:sunset/state",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 710,
        "y": 660,
        "wires": [
            [
                "8c99bc6da0a4d5b0",
                "3e97e9902da57988"
            ]
        ]
    },
    {
        "id": "b10eedb2bb5656c1",
        "type": "change",
        "z": "dbd46647b51191ed",
        "name": "sunrise",
        "rules": [
            {
                "t": "set",
                "p": "payload",
                "pt": "msg",
                "to": "payload.times.sunriseStart",
                "tot": "msg"
            },
            {
                "t": "set",
                "p": "topic",
                "pt": "msg",
                "to": "gladys/master/device/mqtt:soleil/feature/mqtt:sunrise/state",
                "tot": "str"
            }
        ],
        "action": "",
        "property": "",
        "from": "",
        "to": "",
        "reg": false,
        "x": 720,
        "y": 500,
        "wires": [
            [
                "ac45aa2966444fcf",
                "bb2297c4afea4845"
            ]
        ]
    },
    {
        "id": "3e97e9902da57988",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 10",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 920,
        "y": 720,
        "wires": []
    },
    {
        "id": "e9dd4a4e8fcb034c",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 11",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 1160,
        "y": 440,
        "wires": []
    },
    {
        "id": "870a1a0c309ea346",
        "type": "mqtt out",
        "z": "dbd46647b51191ed",
        "name": "",
        "topic": "",
        "qos": "",
        "retain": "",
        "respTopic": "",
        "contentType": "",
        "userProps": "",
        "correl": "",
        "expiry": "",
        "broker": "3c3eb52d.9fb296",
        "x": 1170,
        "y": 580,
        "wires": []
    },
    {
        "id": "8c99bc6da0a4d5b0",
        "type": "function",
        "z": "dbd46647b51191ed",
        "name": "minutes depuis 00h00",
        "func": "// Entrée : msg.payload = \"2023-11-23T16:23:18.121Z\"\n\n// Convertir la chaîne de caractères en objet Date\nvar dateObj = new Date(msg.payload.value);\n\n// Extraire l'heure et les minutes\nvar heures = dateObj.getUTCHours();\nvar minutes = dateObj.getUTCMinutes();\n\n// Calculer le nombre total de minutes depuis 00:00\nvar minutesDepuisMinuit = heures * 60 + minutes;\n\nmsg.topic = heures;\nmsg.payload = minutesDepuisMinuit;\n\n// Renvoyer le message\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 940,
        "y": 660,
        "wires": [
            [
                "7134c8c9865f611d",
                "5efa49d45f363336"
            ]
        ]
    },
    {
        "id": "ac45aa2966444fcf",
        "type": "function",
        "z": "dbd46647b51191ed",
        "name": "minutes depuis 00h00",
        "func": "// Entrée : msg.payload = \"2023-11-23T16:23:18.121Z\"\n\n// Convertir la chaîne de caractères en objet Date\nvar dateObj = new Date(msg.payload.value);\n\n// Extraire l'heure et les minutes\nvar heures = dateObj.getUTCHours();\nvar minutes = dateObj.getUTCMinutes();\n\n// Calculer le nombre total de minutes depuis 00:00\nvar minutesDepuisMinuit = heures * 60 + minutes;\n\nmsg.payload = minutesDepuisMinuit;\n\n// Renvoyer le message\nreturn msg;",
        "outputs": 1,
        "timeout": "",
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 940,
        "y": 500,
        "wires": [
            [
                "e9dd4a4e8fcb034c",
                "9de494cb30ca99c2"
            ]
        ]
    },
    {
        "id": "bb2297c4afea4845",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 12",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 920,
        "y": 440,
        "wires": []
    },
    {
        "id": "7134c8c9865f611d",
        "type": "debug",
        "z": "dbd46647b51191ed",
        "name": "debug 13",
        "active": false,
        "tosidebar": true,
        "console": false,
        "tostatus": true,
        "complete": "true",
        "targetType": "full",
        "statusVal": "payload",
        "statusType": "auto",
        "x": 1160,
        "y": 720,
        "wires": []
    },
    {
        "id": "9de494cb30ca99c2",
        "type": "delay",
        "z": "dbd46647b51191ed",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 1160,
        "y": 500,
        "wires": [
            [
                "870a1a0c309ea346"
            ]
        ]
    },
    {
        "id": "5efa49d45f363336",
        "type": "delay",
        "z": "dbd46647b51191ed",
        "name": "",
        "pauseType": "delay",
        "timeout": "5",
        "timeoutUnits": "seconds",
        "rate": "1",
        "nbRateUnits": "1",
        "rateUnits": "second",
        "randomFirst": "1",
        "randomLast": "5",
        "randomUnits": "seconds",
        "drop": false,
        "allowrate": false,
        "outputs": 1,
        "x": 1160,
        "y": 660,
        "wires": [
            [
                "870a1a0c309ea346"
            ]
        ]
    },
    {
        "id": "3c3eb52d.9fb296",
        "type": "mqtt-broker",
        "name": "MQTT Broker",
        "broker": "localhost",
        "port": "1883",
        "clientid": "",
        "autoConnect": true,
        "usetls": false,
        "compatmode": false,
        "protocolVersion": "4",
        "keepalive": "60",
        "cleansession": true,
        "birthTopic": "",
        "birthQos": "0",
        "birthPayload": "",
        "birthMsg": {},
        "closeTopic": "",
        "closeQos": "0",
        "closePayload": "",
        "closeMsg": {},
        "willTopic": "",
        "willQos": "0",
        "willPayload": "",
        "willMsg": {},
        "userProps": "",
        "sessionExpiry": ""
    },
    {
        "id": "2831ba70.55a636",
        "type": "position-config",
        "name": "Maison",
        "isValide": "true",
        "angleType": "deg",
        "timeZoneOffset": "99",
        "timeZoneDST": "0",
        "stateTimeFormat": "3",
        "stateDateFormat": "12",
        "contextStore": ""
    }
]

ou par une scène (en attendant un dev pour cela avec sunrise, sunset, l’altitude et la longitude) :

pour choisir les jours concernés avec J -1 ici pour que cela fonctionne de L à V

combien de temps avant le lever du soleil = 24h - le temps désiré ici pour 1 h avant le lever du soleil

Il y a plus qu’à actionner

Merci @cce66 pour ta réponse.

Je ne suis pas encore très à l’aise avec Node Red ! Je compte bien y regarder de plus près mais j’ai du mal à prendre le temps.

J’avais bien penser à cette solution… m’étant fait la réflexion qu’elle ne fonctionne pas deux dimanches dans l’année (changement d’heure).

C’est ce qui m’a poussée à regarder les autres notions de l’aube !

Cet article est assez intéressant : Comprendre - Concepts fondamentaux - Lever et coucher d'un astre
Mais peut-être un peu trop technique (en tout cas pour moi).

@b3n.0

excellents tutos et drôle qui plus est…

Faut juste ajuster le node function du « flow » mais normalement le code ajuste sur l’UTC donc ca devrait le faire sinon 2 fois par an…
// Extraire l’heure et les minutes
var heures = dateObj.getUTCHours();
var minutes = dateObj.getUTCMinutes();

C’est pour cela que j’avais fait ce tuto sur Sun-position ça permet de piloter les volets par exemple pour palier au sunrise sunset il y a la notion d’altitude tu peux déclencher l’ouverture dès que l’altitude dépasse 10 et les fermer quand elle passe sous 10

1 « J'aime »

hello @cce66 ,
iodyme le maitre en nodered ! une reference !
present sur youtube de temps en temps mais surtout sur twitch !

Merci pour le partage ! Je vais essayé de me mettre le défi de bien rentrer dedans pendant les vacances de fin d’année.

Ma remarque était plutôt pour la seconde méthode

tu verras c’est pas si compliqué surtout après avoir regardé les tutos de Neodyme (il est prof à l’université de Liège) et node-red est super pour ce qui est de l’interaction avec tout si tu vas sur la doc ou si tu vas chercher des flows sur le net (on en trouves pas mal de tout fait qui permettent de se familiariser avec). Là le fait d’avoir une interaction avec node-red et gladys ca pallie pour le moment ce qui n’est pas encore implémenté dans gladys ou qui ne le sera pas si le besoin est trop spécifique.

J’ai ajouté un Mini-tuto qui devrait t’aider :blush:

1 « J'aime »

J’ai une solution toute simple qui me permet de paramétrer des déclenchements dans des scènes en avance des levers et couchers du soleil.
J’ai testé la fonction « attendre » avec des valeurs en heures pleines ou directement en minutes, au delà de délais aux environs de 20h00 et ça permet de gérer le déclenchement en amont du lever ou du coucher.


La précision dépend toutefois de la valeur de la variation de l’heure des levers et couchers de soleil de la veille :wink:
Si ça peut convenir, ça libère des votes.

C’est ce que j’avais indiqué plus haut dans le post (avec la contrainte pour le lever du soleil de devoir le faire comme suit HeureLeverSoleil + Attendre24h - TempsActionAvantLeverSoleil )

La demande d’un Déclencheur « Avant » reste pertinente il me semble et pourrait être utile pour d’autres événements (anniversaire etc) :wink:

Oups, désolé, je n’avais pas fait attention :face_with_hand_over_mouth:

Cela m’est arrivé :wink: quelquefois ! :joy: