NL alert

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’;
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};
}

3 Likes

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 { ).

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:

// 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}`;
}

1 Like

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

1 Like