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