# NL alert

**URL:** <https://community.homey.app/t/nl-alert/139128>\
**Category:** Flows\
**Created:** [July 2, 2025, 8:24pm UTC](https://community.homey.app/t/nl-alert/139128 "2025-07-02T20:24:04Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fabian\_Annequin](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/fabian_annequin/32/30342_2.png) [@Fabian\_Annequin](https://community.homey.app/u/Fabian_Annequin)\
**Post date:** [July 2, 2025, 8:24pm UTC](https://community.homey.app/t/nl-alert/139128/1 "2025-07-02T20:24:04Z")

</div>

Ik heb een homey script laten maken door mijn vriend chatgpt waarmee nl-alerts worden opgehaald. deze informatie kun je dan weer gebruiken om apparaten aan te sturen. In mijn geval:

-De eerste paar zinnen van het bericht worden uitgesproken via GH-speakers  
-Geautomatiseerder ramen worden gesloten.  
-Handmatige ramen en deuren worden geconroleerd en gecorrigeerd door een spraakbericht via google home speakers. wanneer een deur of raam opent terwijl de alert actief is word hiervoor ook gewaarschuwd.  
-Mechanische ventilatie word uitgeschakeld.

Bij een testbericht gebeurd dit alles ook, maar word het naar 1 minuut hersteld.

Mocht iemand geintereseerd zijn:

> // Coördinaten van je adres : maps in browser \> rechtermuisknop op je huis \>copy/paste \> beperk tot 5 cijfers achter de comma \> hieronder invoeren  
> const myLat = 52.XXXXX;  
> const myLon = 4.XXXXX;
> 
> // Haversine afstandsfunctie  
> function getDistance(lat1, lon1, lat2, lon2) {  
> const R = 6371000;  
> const toRad = deg =\> deg \* Math.PI / 180;  
> const dLat = toRad(lat2 - lat1);  
> const dLon = toRad(lon2 - lon1);  
> const a = Math.sin(dLat/2)\*\*2 + Math.cos(toRad(lat1)) \* Math.cos(toRad(lat2)) \* Math.sin(dLon/2)\*\*2;  
> const c = 2 \* Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));  
> return R \* c;  
> }
> 
> // Datum formatter  
> function formatDate(isoString) {  
> const date = new Date(isoString);  
> const pad = n =\> n.toString().padStart(2, ‘0’);  
> return `${pad(date.getDate())}-${pad(date.getMonth() + 1)}-${date.getFullYear()} ${pad(date.getHours())}:${pad(date.getMinutes())}`;  
> }
> 
> try {  
> // Fetch alerts  
> const URL = ‘[https://api.public-warning.app/api/v1/providers/nl-alert/alerts](https://api.public-warning.app/api/v1/providers/nl-alert/alerts)’;  
> const response = await fetch(URL);  
> if (response.status !== 200) throw Error(‘Invalid response’);
> 
> const json = await response.json();  
> const alerts = json.data || json;
> 
> if (!Array.isArray(alerts) || alerts.length === 0) throw Error(‘Geen alerts gevonden’);
> 
> let foundMessage = null;  
> let foundTimestamp = null;
> 
> for (const alert of alerts) {  
> const info = alert.message || alert.info?.[0]?.description;  
> const polygon = alert.area?.[0];  
> if (!polygon) continue;
> 
> ```
> const firstPoint = polygon.trim().split(' ')[0];
> const [lat, lon] = firstPoint.split(',').map(Number);
> const dist = getDistance(myLat, myLon, lat, lon);
> 
> ```
> 
> const alertTime = new Date(alert.start\_at);  
> const now = new Date();  
> const ageInMs = now - alertTime;
> 
> if (dist \<= 10000 && ageInMs \<= 24 \* 60 \* 60 \* 1000) {  
> foundMessage = info || ‘NL-Alert actief’;  
> foundTimestamp = formatDate(alert.start\_at || now.toISOString());  
> break;  
> }  
> }
> 
> if (!foundMessage) {  
> foundMessage = ‘Geen relevante NL-Alert in jouw buurt’;  
> foundTimestamp = formatDate(new Date().toISOString());  
> }
> 
> // Tekst inkorten tot max 100 tekens, netjes eindigend op een punt als mogelijk  
> if (foundMessage.length \> 100) {  
> const cutoff = foundMessage.substring(0, 100);  
> const lastDot = cutoff.lastIndexOf(‘.’);  
> if (lastDot \> 20) {  
> foundMessage = cutoff.substring(0, lastDot + 1); // netjes tot punt  
> } else {  
> const lastSpace = cutoff.lastIndexOf(’ ');  
> foundMessage = cutoff.substring(0, lastSpace \> 0 ? lastSpace : 97) + ‘…’;  
> }  
> }
> 
> // Haal alle logic variables op en zet ze in een array  
> const varsObj = await Homey.logic.getVariables();  
> const vars = Object.values(varsObj);
> 
> // Vind de variables op naam  
> const messageVar = vars.find(v =\> v.name === “nlAlertMessage”);  
> const timestampVar = vars.find(v =\> v.name === “nlAlertTimestamp”);
> 
> if (!messageVar || !timestampVar) {  
> throw new Error(‘Variabelen nlAlertMessage of nlAlertTimestamp niet gevonden’);  
> }
> 
> // Update de variables  
> await Homey.logic.updateVariable({ id: messageVar.id, variable: { value: foundMessage } });  
> await Homey.logic.updateVariable({ id: timestampVar.id, variable: { value: foundTimestamp } });
> 
> return `NL-Alert bijgewerkt: ${foundMessage} (Ontvangen op ${foundTimestamp})`;
> 
> } catch (error) {  
> return `Fout: ${error.message}`;  
> }

 ![Screenshot 2025-07-02 22.22.31](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/7/4/748e11e32254bea71948ecfaa5285771b66604ba.png)

---

<div class="post-metadata">

**Author:** ![Walter\_vande\_kerkhof](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/walter_vande_kerkhof/32/28963_2.png) [@Walter\_vande\_kerkhof](https://community.homey.app/u/Walter_vande_kerkhof)\
**Post date:** [July 3, 2025, 5:32pm UTC](https://community.homey.app/t/nl-alert/139128/2 "2025-07-03T17:32:00Z")

</div>

Hi, didn’t get this script to work. It generates several errors after copy/paste as a homey-script. Error starts at line 19 (must that be double-quote instead of single-quote?) and line 21 (doesn’t expect { ).

---

<div class="post-metadata">

**Author:** ![Le\_Cactus](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/le_cactus/32/9727_2.png) [@Le\_Cactus](https://community.homey.app/u/Le_Cactus)\
**Post date:** [July 3, 2025, 6:36pm UTC](https://community.homey.app/t/nl-alert/139128/3 "2025-07-03T18:36:15Z")

</div>

Nice! Bedankt!! Hier zocht ik al een tijdje naar.

@Walter_vande_kerkhof

Je zult iig twee (tekst) variabele aan moeten maken; nlAlertTimestamp en nlAlertMessage.

De code is verder verkeerd in de post gezet. Als je deze pakt zal hij wel werken:

```auto
// Coördinaten van je adres: maps in browser > rechtermuisknop op je huis > copy/paste > beperk tot 5 cijfers achter de komma
const myLat = 51.97481;
const myLon = 6.71247;

// Haversine afstandsfunctie
function getDistance(lat1, lon1, lat2, lon2) {
    const R = 6371000;
    const toRad = deg => deg * Math.PI / 180;
    const dLat = toRad(lat2 - lat1);
    const dLon = toRad(lon2 - lon1);
    const a = Math.sin(dLat / 2) **2 + Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) * Math.sin(dLon / 2)** 2;
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    return R * c;
}

// Datum formatter
function formatDate(isoString) {
    const date = new Date(isoString);
    const pad = n => n.toString().padStart(2, '0');
    return `${pad(date.getDate())}-${pad(date.getMonth() + 1)}-${date.getFullYear()} ${pad(date.getHours())}:${pad(date.getMinutes())}`;
}

try {
    // Fetch alerts
    const URL = 'https://api.public-warning.app/api/v1/providers/nl-alert/alerts';
    const response = await fetch(URL);
    if (response.status !== 200) throw Error('Invalid response');

    const json = await response.json();
    const alerts = json.data || json;

    if (!Array.isArray(alerts) || alerts.length === 0) throw Error('Geen alerts gevonden');

    let foundMessage = null;
    let foundTimestamp = null;

    for (const alert of alerts) {
        const info = alert.message || alert.info?.[0]?.description;
        const polygon = alert.area?.[0];
        if (!polygon) continue;

        const firstPoint = polygon.trim().split(' ')[0];
        const [lat, lon] = firstPoint.split(',').map(Number);
        const dist = getDistance(myLat, myLon, lat, lon);
        const alertTime = new Date(alert.start_at);
        const now = new Date();
        const ageInMs = now - alertTime;

        if (dist <= 10000 && ageInMs <= 24 * 60 * 60 * 1000) {
            foundMessage = info || 'NL - Alert actief';
            foundTimestamp = formatDate(alert.start_at || now.toISOString());
            break;
        }
    }

    if (!foundMessage) {
        foundMessage = 'Geen relevante NL - Alert in jouw buurt';
        foundTimestamp = formatDate(new Date().toISOString());
    }

    // Tekst inkorten tot max 100 tekens, netjes eindigend op een punt als mogelijk
    if (foundMessage.length > 100) {
        const cutoff = foundMessage.substring(0, 100);
        const lastDot = cutoff.lastIndexOf('.');
        if (lastDot > 20) {
            foundMessage = cutoff.substring(0, lastDot + 1); // netjes tot punt
        } else {
            const lastSpace = cutoff.lastIndexOf(' ');
            foundMessage = cutoff.substring(0, lastSpace > 0 ? lastSpace : 97) + '…';
        }
    }

    // Haal alle logic variables op en zet ze in een array
    const varsObj = await Homey.logic.getVariables();
    const vars = Object.values(varsObj);

    // Vind de variables op naam
    const messageVar = vars.find(v => v.name === "nlAlertMessage");
    const timestampVar = vars.find(v => v.name === "nlAlertTimestamp");

    if (!messageVar || !timestampVar) {
        throw new Error('Variabelen nlAlertMessage of nlAlertTimestamp niet gevonden');
    }

    // Update de variables
    await Homey.logic.updateVariable({ id: messageVar.id, variable: { value: foundMessage } });
    await Homey.logic.updateVariable({ id: timestampVar.id, variable: { value: foundTimestamp } });

    return `NL - Alert bijgewerkt: ${foundMessage} (Ontvangen op ${foundTimestamp})`;

} catch (error) {
    return `Fout: ${error.message}`;
}

```

---

<div class="post-metadata">

**Author:** ![Walter\_vande\_kerkhof](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/walter_vande_kerkhof/32/28963_2.png) [@Walter\_vande\_kerkhof](https://community.homey.app/u/Walter_vande_kerkhof)\
**Post date:** [July 5, 2025, 10:30am UTC](https://community.homey.app/t/nl-alert/139128/4 "2025-07-05T10:30:48Z")

</div>

Heb de code aangepast zodat het tijdstip klopt met mijn tijdzone ipv UTC
