How to integrate Dawarich as geofencing into ioBroker

I wrote a small script to use Dawarich as a geofencing alternative for ioBroker. It runs very smoothly and, of course, can be expanded. All objects are created automatically. Included are:

Presence
Distance from the house in meters
Online status
And a vacation switch for the heating system

const axios = require('axios');

// 1. ADRESSE DEINER DAWARICH-INSTANZ
const DAWARICH_URL = 'http://192.168.4.245:32568'; 

// 2. GEOFENCING KOORDINATEN
const HOME_LAT = 52.520815;  // Deinen Breitengrad eintragen (z. B. aus Google Maps)
const HOME_LON = 13.4068442;  // Deinen Längengrad eintragen
const GEOFENCE_RADIUS_METER = 150; // Radius fĂĽr Hoflicht / "Zuhause"

// 3. REISE-GRENZE FĂśR AUTOMATISCHEN URLAUB (z.B. 60 Kilometer)
const VACATION_DISTANCE_METER = 60000; 

// 4. DEINE USER (Dummy fĂĽr Moritz ist wieder da)
const dawarichUsers = [
    { name: 'Udo', apiKey: 'DEIN_BESTEHENDER_API_KEY_USER_1'  },
    { name: 'Heike', apiKey: ' DEIN_BESTEHENDER_API_KEY_USER_2' },
    // { name: 'Moritz, apiKey: 'DEIN_BESTEHENDER_API_KEY_USER_3' } 
];

// Automatische Erstellung aller ioBroker-Datenpunkte
createState('javascript.0.Dawarich.Urlaubsmodus', false, { name: 'Automatischer Urlaubsmodus', type: 'boolean', role: 'state' });

dawarichUsers.forEach(user => {
    createState('javascript.0.Dawarich.' + user.name + '.Online', false, { name: user.name + ' Status', type: 'boolean', role: 'indicator' });
    createState('javascript.0.Dawarich.' + user.name + '.PointCount', 0, { name: user.name + ' GPS-Punkte', type: 'number', role: 'value' });
    createState('javascript.0.Dawarich.' + user.name + '.Zuhause', false, { name: user.name + ' ist Zuhause', type: 'boolean', role: 'presence' });
    createState('javascript.0.Dawarich.' + user.name + '.Entfernung', 0, { name: user.name + ' Entfernung in m', type: 'number', role: 'value' });
});

// Hilfsfunktion zur Entfernungsberechnung (Haversine-Formel)
function getDistance(lat1, lon1, lat2, lon2) {
    const R = 6371e3; 
    const phi1 = lat1 * Math.PI/180;
    const phi2 = lat2 * Math.PI/180;
    const deltaPhi = (lat2-lat1) * Math.PI/180;
    const deltaLambda = (lon2-lon1) * Math.PI/180;
    const a = Math.sin(deltaPhi/2) * Math.sin(deltaPhi/2) +
              Math.cos(phi1) * Math.cos(phi2) *
              Math.sin(deltaLambda/2) * Math.sin(deltaLambda/2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return R * c; 
}

async function checkDawarichUsers() {
    let currentDistances = {};

    for (const user of dawarichUsers) {
        try {
            // Änderung auf den korrekte-n Endpunkt mit Sortierung nach neuesten Punkten zuerst
            const response = await axios.get(`${DAWARICH_URL}/api/v1/points?api_key=${user.apiKey}&order=desc&per_page=1`, {
                timeout: 5000
            });
            
            // Verbindung erfolgreich
            setState('javascript.0.Dawarich.' + user.name + '.Online', true, true);
            
            // Gesamtzahl der Punkte auslesen
            if (response.headers && response.headers['x-total-count']) {
                const totalPoints = parseInt(response.headers['x-total-count'], 10);
                setState('javascript.0.Dawarich.' + user.name + '.PointCount', totalPoints, true);
            }

            // Geofencing: Auswerten des neuesten Standorts (Dank order=desc jetzt an Position 0)
            if (response.data && Array.isArray(response.data) && response.data.length > 0) {
                const lastPoint = response.data[0];
                
                // Koordinaten auslesen
                const userLat = parseFloat(lastPoint.lat || lastPoint.latitude);
                const userLon = parseFloat(lastPoint.lon || lastPoint.lng || lastPoint.longitude);

                if (!isNaN(userLat) && !isNaN(userLon)) {
                    // Entfernung zum Haus berechnen
                    const distance = Math.round(getDistance(userLat, userLon, HOME_LAT, HOME_LON));
                    setState('javascript.0.Dawarich.' + user.name + '.Entfernung', distance, true);
                    
                    // Speichern fĂĽr die Urlaubs-Logik am Ende
                    currentDistances[user.name] = distance;

                    // Anwesenheitsstatus setzen
                    if (distance <= GEOFENCE_RADIUS_METER) {
                        setState('javascript.0.Dawarich.' + user.name + '.Zuhause', true, true);
                    } else {
                        setState('javascript.0.Dawarich.' + user.name + '.Zuhause', false, true);
                    }
                }
            }
        } catch (error) {
            log(`Dawarich Fehler bei User ${user.name}: ` + error.message, 'warn');
            setState('javascript.0.Dawarich.' + user.name + '.Online', false, true);
        }
    }

    // --- AUTOMATISCHE URLAUBS-LOGIK ---
    if (Object.keys(currentDistances).length === dawarichUsers.length && dawarichUsers.length > 0) {
        const isUrlaubAktuell = getState('javascript.0.Dawarich.Urlaubsmodus').val;
        
        const alleImUrlaub = dawarichUsers.every(user => currentDistances[user.name] > VACATION_DISTANCE_METER);
        const einerAufHeimreise = dawarichUsers.some(user => currentDistances[user.name] <= VACATION_DISTANCE_METER);

        if (alleImUrlaub && !isUrlaubAktuell) {
            setState('javascript.0.Dawarich.Urlaubsmodus', true, true);
            log('Automatischer Urlaubsmodus AKTIVIERT.', 'info');
        } else if (einerAufHeimreise && isUrlaubAktuell) {
            setState('javascript.0.Dawarich.Urlaubsmodus', false, true);
            log('Automatischer Urlaubsmodus BEENDET.', 'info');
        }
    }
}

// Alle 5 Minuten abfragen
schedule('*/5 * * * *', checkDawarichUsers);
checkDawarichUsers();



greetz dipsy

1 Like

Works fine, Thank you :grinning_face: