iRobot Steuerung in ioBroker

Lesedauer: 10 Minuten

In diesem Beitrag zeige ich Dir, wie du deinen iRobot Roboter bequem anhand der Räume steuern kannst. Die Steuerung über die iRobot App bietet inzwischen die Möglichkeit, den jeweiligen Roboter mit einem Fingerzeig in den jeweiligen Raum fahren zu lassen. Über ioBroker ist dies bisher leider nur über Umwege möglich. Hier setzt mein Skript an und bietet Dir komfortabel die Möglichkeit, den Roboter in verschiedene Räume und sogar Zonen zu senden.

Des Weiteren zeigt das Skript folgende Daten an:

  • die gereinigte Fläche des Durchgangs
  • welches Wischtuch z.B. beim Braava installiert ist
  • ob der Wassertank des Braava gefüllt ist oder nicht

Damit das Skript ordnungsgemäß arbeiten kann, ist der Roomba Adapter in ioBroker notwendig. Des Weiteren sind ein paar Vorbereitungen notwendig – die aber relativ schnell, einfach und einmalig erledigt werden können.

Vorbereitungen

Installiere bitte den Roomba Adapter in ioBroker und richte den Adapter ein. Wie dies funktioniert, ist hier beschrieben.

Erstelle Dir ein neues Skript im common Bereich mit dem Namen “iRobot-Control”. In das leere Skript kopierst Du Dir den nachfolgenden Inhalt. Startest das Skript aber noch nicht, da noch 2 Zeilen anzupassen sind – Zeile 32 und 33.

Skript

/*
 * @copyright 2020 Stephan Kreyenborg <stephan@kreyenborg.koeln>
 *
 * @author 2020 Stephan Kreyenborg <stephan@kreyenborg.koeln>
 *
 * Dieses Skript dient zur freien Verwendung in ioBroker zur erweiterten Steuerung der iRobot Roboter.
 * Jegliche Verantwortung liegt beim Benutzer. Das Skript wurde unter Berücksichtigung der bestmöglichen Nutzung
 * und Performance entwickelt.
 * Der Entwickler versichert, das keine böswilligen Systemeingriffe im originalen Skript vorhanden sind.
 *
 * Sollte das Skript wider Erwarten nicht korrekt funktionieren, so hast Du jederzeit die Möglichkeit, Dich auf
 * https://www.kreyenborg.koeln
 * für Unterstützung zu melden. Jedes Skript besitzt seine eigene Kommentarseite, auf der,
 * nach zeitlicher Möglichkeit des Autors, Hilfe angeboten wird. Ein Anrecht hierauf besteht nicht!
 * 
 * Ansprüche gegenüber Dritten bestehen nicht. 
 * 
 * Skript Name:		iRobot-Control
 * Skript Version:	1.2
 * Erstell-Datum:	14. Oktober 2021
 * 
 */

// Datenpunkte neu erstellen
var ueberschreiben = false;

// Hauptdatenpunkt unterhalb javascript
var datenpunkt = "iRobot."; // Abschließender Punkt !!! WICHTIG !!!

// Instanzen der Geräte
var datenpunkt_instanz = "roomba."; // Abschließender Punkt | !!! BITTE NICHT ÄNDERN !!!
var instanz_geraet = [0, 1]; // Installierte Instanz | Bsp: 0 für Roomba, 1 für Braava
var instanz_name = ["Roomba", "Braava"]; // Keine Leerzeichen | Namen der Geräte ohne Leerzeichen

function abonniere_datenpunkte() {
    for (let i = 0; i < instanz_geraet.length; i++) {
        // Abonniere Datenpunkt zu Details des Roboters
        on({ id: datenpunkt_instanz + instanz_geraet[i] + ".device._rawData", change: "any" }, function (obj) {
            // Hole Datenpunkt
            var j = JSON.parse(obj.state.val);

            // Aktualisiere alle Datenpunkte
            var tmp_id = obj.id.split(".");
            var id = tmp_id[1];
            aktualisiere_datenpunkte(id, j);
        });
        // Abonniere eigene Datenpunkte zur Steuerung
        on({ id: "javascript.0." + datenpunkt + instanz_name[i] + ".Steuerung", change: "any" }, function (obj) {
            if (obj.state.val != "" || obj.state.val != null) {
                var tmp_id = obj.id.split(".");
                robot_steuerung(instanz_name.indexOf(tmp_id[tmp_id.length - 2]), obj.state.val, "Skript-Control");
            }
        });
        // Abonniere eigene Datenpunkte für geplante Bereiche
        on({ id: "javascript.0." + datenpunkt + instanz_name[i] + ".Geplante_Bereiche", change: "any" }, function (obj) {
            if (obj.state.val != "" || obj.state.val != null) {
                var tmp_id = obj.id.split(".");
                robot_auftrag(instanz_name.indexOf(tmp_id[tmp_id.length - 2]), obj.state.val);
            }
        });
    }
    log("iRobot-Control: Benötigte Datenpunkte wurden erstellt und abonniert. Skript ist einsatzbereit!");
}

// Reinigungsauftrag
function robot_auftrag(idRoboter, bereiche) {
    // Basis JSON Objekt
    let j_kommando = {
        command: "start",
        ordered: 1,
        pmap_id: null,
        regions: [],
        user_pmapv_id: null
    };
    // Sortiere Bereiche in Array ein
    var array_bereiche = bereiche.split(",");

    // Gefundene Bereiche
    var gefundene_bereiche = new Array();

    // Lese alle vorhandenen Räume ein
    var vorhandene_bereiche = $('state[id=javascript.0.' + datenpunkt + instanz_name[idRoboter] + '.*.*.name]');
    
    // Prüfe, ob mindestens ein Raum im Datenpunkt existiert
    if (vorhandene_bereiche[0] != undefined) {
        // Trenne den Datenpunkt
        var tmp_id = vorhandene_bereiche[0].split(".");
        // Karte
        var karte = getState(datenpunkt + instanz_name[idRoboter] + ".Bereiche." + tmp_id[tmp_id.length - 4] + ".pmap_id").val;
        j_kommando.pmap_id = karte;
        // Version der Karte
        var version = getState(datenpunkt + instanz_name[idRoboter] + ".Bereiche." + tmp_id[tmp_id.length - 4] + ".user_pmapv_id").val;
        j_kommando.user_pmapv_id = version;
        // Suche die passende ID zum Raum
        for (let i = 0; i < array_bereiche.length; i++) {
            vorhandene_bereiche.each(function (id, n) {
                // Trenne den Datenpunkt
                var tmp_dp = id.split(".");
                // ID des Bereichs (Raum oder Zone)
                var bereich_id = tmp_dp[tmp_id.length - 2];
                // Typ -> Zone oder Raum
                var typ = tmp_dp[tmp_id.length - 3];
                // lesbarer Name des Bereichs
                var bereich_name = getState(id).val;
                // Sortiere die Räume und Zonen ein
                if (bereich_name.toLowerCase() == array_bereiche[i].trim().toLowerCase()) {
                    if (typ == "Raeume") {
                        let tmp = { region_id: bereich_id.toString(), type: "rid" };
                        j_kommando.regions.push(tmp);
                        gefundene_bereiche.push(bereich_name + " (ID: " + bereich_id + ")");
                    }
                    if (typ == "Zonen") {
                        let tmp = { region_id: bereich_id.toString(), type: "zid" };
                        j_kommando.regions.push(tmp);
                        gefundene_bereiche.push(bereich_name + " (ID: " + bereich_id + ")");
                    }
                }
            });
        }
        let kommando = JSON.stringify(j_kommando);
        log("iRobot-Control: Starte Reinigung mit " + instanz_name[idRoboter] + " für: " + gefundene_bereiche.join(", "));
        setState(datenpunkt_instanz + idRoboter + ".commands._runCommand", kommando);
    } else {
        log("iRobot-Control: Noch keine Bereiche vorhanden. Auftrag kann nicht gestartet werden!");
    }
}

// Roboter Steuerung
function robot_steuerung(id, kommando, app) {
    let j_command = { command: kommando, time: Date.now() / 1000 | 0, initiator: app };
    let command = JSON.stringify(j_command);

    // Prüfe, von wem das Kommando kam
    if (app == "Skript-Control") {
        setState("roomba." + id + ".commands._runCommand", command);
    } else {
        setState(datenpunkt + instanz_name[id] + ".Steuerung", kommando, true);
    }
}

// Lege neuen Raum an
function neuer_raum(geraet, pmap_id, region_id, region_type, user_pmapv_id) {
    // Bereiche
    createState(datenpunkt + geraet + ".Bereiche." + pmap_id, '', { name: 'ID der Karte', type: 'string', role: 'state' }, function () { });
    createState(datenpunkt + geraet + ".Bereiche." + pmap_id + ".pmap_id", pmap_id, { name: "ID der Karte", type: 'string', role: 'value' }, function () { });
    createState(datenpunkt + geraet + ".Bereiche." + pmap_id + ".user_pmapv_id", user_pmapv_id, { name: "Version der Karte", type: 'string', role: 'value' }, function () { });

    // Raum
    if (region_type == "rid") {
        createState(datenpunkt + geraet + ".Bereiche." + pmap_id + '.Raeume.' + region_id, '', { name: 'ID des Raumes', type: 'string', role: 'state' }, function () { });
        createState(datenpunkt + geraet + ".Bereiche." + pmap_id + '.Raeume.' + region_id + '.region_id', region_id, { name: 'ID Des Raumes', type: 'string', role: 'value' }, function () { });
        createState(datenpunkt + geraet + ".Bereiche." + pmap_id + '.Raeume.' + region_id + '.name', '', { name: 'Eigener Name des Raumes', type: 'string', role: 'value' }, function () { });
        createState(datenpunkt + geraet + ".Bereiche." + pmap_id + '.Raeume.' + region_id + '.erstellt', hole_datum(), { name: 'Datum des Hinzufügens', type: 'string', role: 'value' }, function () { });
        log("iRobot-Control: Neuer Raum für " + geraet + " gefunden und angelegt! ID: " + region_id);
    }

    // Schmutzzone
    if (region_type == "zid") {
        createState(datenpunkt + geraet + ".Bereiche." + pmap_id + '.Zonen.' + region_id, '', { name: 'ID der Zone', type: 'string', role: 'state' }, function () { });
        createState(datenpunkt + geraet + ".Bereiche." + pmap_id + ".Zonen." + region_id + '.region_id', region_id, { name: 'ID der Zone', type: 'string', role: 'value' }, function () { });
        createState(datenpunkt + geraet + ".Bereiche." + pmap_id + ".Zonen." + region_id + '.name', '', { name: 'Eigener Name der Zone', type: 'string', role: 'value' }, function () { });
        createState(datenpunkt + geraet + ".Bereiche." + pmap_id + '.Zonen.' + region_id + '.erstellt', hole_datum(), { name: 'Datum des Hinzufügens', type: 'string', role: 'value' }, function () { });
        log("iRobot-Control: Neue Zone für " + geraet + " gefunden und angelegt! ID: " + region_id);
    }
}

// Aktualisiere alle Datenpunkte
function aktualisiere_datenpunkte(id, j) {
    // Generelle Datenpunkte
    // Gereinigte Quadratmeter
    setState(datenpunkt + instanz_name[id] + ".Quadratmeter", parseFloat((j.bbrun.sqft / 10.764).toFixed(2)), true);
    // Prüfe Wassertank des Braava
    if (j.cleanMissionStatus.notReady === 31) {
        setState(datenpunkt + instanz_name[id] + ".Wassertank", true, true);
    } else {
        setState(datenpunkt + instanz_name[id] + ".Wassertank", false, true);
    }
    // Wischtuch des Braava
    if (j.detectedPad != null) {
        setState(datenpunkt + instanz_name[id] + ".Wischtuch", j.detectedPad, true);
    }

    // Aktuelle Räume im Auftrag
    setState(datenpunkt + instanz_name[id] + ".Durchgang_Raeume", generiere_raumliste(id, j.lastCommand.pmap_id, j.lastCommand.regions), true);

    // Prüfe, ob kein Training stattfindet
    if (j.lastCommand.regions != null) {
        var region_id = j.lastCommand.regions[0].region_id;
        var region_type = j.lastCommand.regions[0].type;
        var pmap_id = j.lastCommand.pmap_id;
        var user_pmapv_id = j.lastCommand.user_pmapv_id;

        // Region Räume
        if (region_type == "rid") {
            // Prüfe, ob Raum existiert
            if (!existsState(datenpunkt + instanz_name[id] + ".Bereiche." + pmap_id + ".Raeume." + region_id + ".region_id")) {
                // Raum existiert nicht. Raum anlegen
                neuer_raum(instanz_name[id], pmap_id, region_id, region_type, user_pmapv_id);
            } else {
                if (user_pmapv_id != null) {
                    setState(datenpunkt + instanz_name[id] + ".Bereiche." + pmap_id + ".user_pmapv_id", user_pmapv_id, true);
                }
            }
        }
        // Region Zonen
        if (region_type == "zid") {
            // Prüfe, ob Raum existiert
            if (!existsState(datenpunkt + instanz_name[id] + ".Bereiche." + pmap_id + ".Zonen." + region_id + ".region_id")) {
                // Raum existiert nicht. Raum anlegen
                neuer_raum(instanz_name[id], pmap_id, region_id, region_type, user_pmapv_id);
            } else {
                if (user_pmapv_id != null) {
                    setState(datenpunkt + instanz_name[id] + ".Bereiche." + pmap_id + ".user_pmapv_id", user_pmapv_id, true);
                }
            }
        }
    }
}

// Generiere Raumliste
function generiere_raumliste(id, karte, raeume) {
    if (raeume == null) {
        return "Keine Räume im Auftrag";
    } else {
        // Lege Array an
        var raumliste_name = new Array();
        // Irritiere über die übermittelten Räume
        for (let i = 0; i < raeume.length; i++) {
            var name = "";
            if (raeume[i].type == "rid") {
                if (existsState(datenpunkt + instanz_name[id] + ".Bereiche." + karte + ".Raeume." + raeume[i].region_id + ".name")) {
                    name = getState(datenpunkt + instanz_name[id] + ".Bereiche." + karte + ".Raeume." + raeume[i].region_id + ".name").val;
                    if (name == "" || name == null) {
                        name = "Namenloser Raum mit der ID: " + raeume[i].region_id;
                    }
                } else {
                    // Raum noch nicht vorhanden
                    name = "Nicht definierter Raum (ID: " + raeume[i].region_id + ")";
                }
            }
            if (raeume[i].type == "zid") {
                if (existsState(datenpunkt + instanz_name[id] + ".Bereiche." + karte + ".Zonen." + raeume[i].region_id + ".name")) {
                    name = getState(datenpunkt + instanz_name[id] + ".Bereiche." + karte + ".Zonen." + raeume[i].region_id + ".name").val;
                    if (name == "" || name == null) {
                        name = "Namenlose Zone mit der ID: " + raeume[i].region_id;
                    }
                } else {
                    // Raum noch nicht vorhanden
                    name = "Nicht definierte Zone (ID: " + raeume[i].region_id + ")";
                }
            }
            if (name != "") {
                raumliste_name.push(name);
            }
        }
        // Gebe Raumliste zurück
        if (raumliste_name.length === 0) {
            return "Keine Räume im Autrag!";
        } else {
            return raumliste_name.join(", ");
        }
    }
}

// Datum 
function hole_datum() {
    let datum = new Date();
    let tag = '0' + datum.getDate();
    let monat = '0' + (datum.getMonth() + 1);
    let jahr = datum.getFullYear();
    let stunde = '0' + datum.getHours();
    let minute = '0' + datum.getMinutes();
    let sekunde = '0' + datum.getSeconds();
    return tag.substr(-2) + '.' + monat.substr(-2) + '.' + jahr + ' ' + stunde.substr(-2) + ':' + minute.substr(-2) + ':' + sekunde.substr(-2);
}

// Werte für die Datenpunkte
// iRobot Objekte
var objekt = [
    "Steuerung",
    "Quadratmeter",
    "Wassertank",
    "Wischtuch",
    "Durchgang_Raeume",
    "Geplante_Bereiche"
];

// Beschreibung der Objekte
var beschreibung = [
    "Steuerung des Roboters",
    "Gereinigte Quadratmeter",
    "Wassertank des Braava",
    "Montiertes Wischtuch des Braava",
    "Räume des aktuellen Durchgangs",
    "Geplante Bereiche für den Durchgang"
];

// Einheiten der Objekte
var einheiten = [
    "",
    "qm²",
    "",
    "",
    "",
    ""
    ,];

// Typen der Objekte
var typen = [
    "string",
    "number",
    "boolean",
    "string",
    "string"
];

// Rollen der Objekte
var rolle = [
    "action",
    "value",
    "inidcator",
    "value",
    "value",
    "string"
];

// Erstelle die benötigten Datenpunkte
function datenpunkte_erstellen() {
    for (let g = 0; g < instanz_geraet.length; g++) {
        for (let i = 0; i < objekt.length; i++) {
            createState(datenpunkt + instanz_name[g] + "." + objekt[i], null, ueberschreiben, {
                name: beschreibung[i],
                desc: beschreibung[i],
                type: typen[i],
                role: rolle[i],
                unit: einheiten[i]
            });
        }
    }
    log("iRobot-Control: Datenpunkte werden im Hintergrund erstellt. Dies dauert 30 Sekunden. Bitte warten!");
    setTimeout(abonniere_datenpunkte, 30000);
}

function irobot_erster_start() {
    log("iRobot-Control: Erster Start des Skriptes! Datenpunkte werden erstellt!");
    // Datenpunkte werden erstellt
    if (existsState(datenpunkt_instanz + "0.device._rawData")) {
        datenpunkte_erstellen();
    } else {
        stopScript("");
        log("iRobot-Control: Fehler: Roomba Adapter scheint nicht installiert zu sein!", "error");
    }
}

// Erster Start und Initialisierung
irobot_erster_start();

Änderungen

1.2 (14. Oktober 2021)

  • Änderung der Priorisierung der Räume
  • Raumfindung angepasst
  • Start-Limit angepasst

1.0 (07. Oktober 2021)

  • erste Version

Konfiguration

Damit nun das Skript weiss, welche iRobot Geräte (bei mehr als 2 Instanzen) bei Dir vorhanden sind, musst Du Zeile 32 und 33 wie folgt anpassen.

Zeile 32: Hier sind die Instanzen des Roomba Adapters gemeint. Bei einem Gerät ist es die 0. Bei mehr als einer Instanz sind diese mit Komma getrennt anzugeben.

Zeile 33: Hier gibst Du die Namen der Geräte an, damit Du sie leichter zuordnen kannst.

Ab hier kannst Du das Skript starten und es werden einige Datenpunkte unterhalb javascript.0.iRobot erzeugt. Pro Gerät, welches Du angegeben hast, wie folgt:

DatenpunktBezeichnung
Bereiche (Ordner)Beinhaltet die Bereiche, die gefunden wurden (s.u.)
Duchgang_RaeumeRäume des aktuellen Durchgangs
Geplante_BereicheGeplante Bereiche für den Durchgang
QuadratmeterGereinigte Quadratmeter
SteuerungSteuerung des Roboters (mehr Befehle möglich)
WassertankWassertank des Braava (sonst “null”)
WischtuchWischtuch des Braava (sonst “null”)

Räume dem Skript hinzufügen

Da das Skript nun gestartet ist und die einzelnen Datenpunkte oberhalb bereits erstellt worden sind, kannst Du beginnen, die einzelnen Räume dem Skript zuzuweisen.

Starte mit der Roomba App auf dem Smartphone einen Reinigungsauftrag für ein Gerät (beim Roomba ohne Nachwischen). Sobald der Roboter losgefahren ist (maximal 60 Sekunden später), kannst Du im Log von ioBroker erkennen, dass das Skript eine ID und einen Bereich (Zone oder Raum) ausgibt.

Robot-Control: Neuer Raum für Roomba gefunden und angelegt! ID: 4

Hieran kannst Du erkennen, das es sich um einen neuen Raum handelt, den das Skript noch nicht kennt.

Der Roboter kann in der Zwischenzeit zur Basis zurückkehren.

Nun begibst Du Dich in den Objekt-Browser von ioBroker und navigierst zu:

javascript.0.iRobot.<Name-des-Roboters>.Bereiche.<Karte-ID>.<Bereich>.<ID des Raumes> (Bereich: Raeume oder Zone; ID des Raumes: ID aus dem Log)

Hier solltest du ein Layout wie folgt sehen:

Objekte des Skriptes
Objekte des Skriptes

Dort gibt es nun den Ordner mit der gefundenen ID – hier 4. Diesen Ordner kannst Du nun der Übersicht halber einem Raum aus der ioBroker Liste zuweisen (nur für die Optik). Viel wichtiger ist hier der Datenpunkt “name“. Das ist später der eigentliche Name, den das Skript verwendet. Anklicken, Namen festlegen, Wert setzen, Fertig. Der erste Raum ist nun angelegt.
Tipp: Am Besten verwendest Du die gleichen Namen, wie in der App.

Nun solltest Du (innerhalb von 60 Sekunden) sehen, das der Datenpunkt “Durchgang_Raeume” auch den von dir festgelegten Raum darstellt.

Datenpunkt des aktuellen Durchgangs
Datenpunkt des aktuellen Durchgangs

Diesen Schritt kannst Du nun für jeden Raum wiederholen. Bitte bedenke, dass das Skript während der Einrichtung immer nur einen Raum identifiziert. Dies macht es Dir leichter, die einzelnen Räume zu benennen, da man bei mehreren ID’s wahrscheinlich durcheinander kommt 😉

Anwendung des Skripts – Räume und Zonen steuern

Nachdem Du nun alle Räume und Zonen dem Skript mitgeteilt hast, kann es an die eigentliche Verwendung gehen – das Steuern des Roboters über die Raumnamen.

Hier ist der jeweilige Datenpunkt javascript.0.iRobot.<Name-des-Roboters>.Geplante_Bereiche wichtig, denn hier kannst du – jeweils durch ein Komma getrennt, deine Räume und Zonen zur gleichen Zeit eintragen und der Roboter beginnt mit der Reinigung. Auch die Priorisierung ist möglich. Der Raum oder die Zone, die zuerst angegeben ist, wird zuerst gereinigt. Einfach, oder?

Beispiel:

Du möchtest Küche, Couchtisch und Esszimmer reinigen. So schreibst Du diesen Wert (String) einfach in den Datenpunkt. Dies kann natürlich auch über ein kleines Skript erfolgen, welches in etwa so aussieht:

// Reinigung von Küche, Couchtisch und Esszimmer jeden Tag zur goldenen Abendstunde
schedule({ astro: "goldenHour" }, function () {
    setState("javascript.0.iRobot.Roomba.Geplante_Bereiche", "Küche, Couchtisch, Esszimmer", true);
});

Weitere Zeiten zum Thema “Astro” findest Du hier.

Natürlich lassen sich alle Datenpunkte auch in VIS oder JarVIS steuern und anzeigen.

Hier ein Beispiel für JarVIS und den Roomba i7:

Roomba i7 in JarVIS
Roomba i7 in JarVIS

Anwendung des Skripts – iRobot steuern

Wie eingangs erwähnt, bietet mein Skript noch einige Steuerbefehle mehr. Diese laufen über den Datenpunkt javascript.0.iRobot.<Name-des-Roboters>.Steuerung

Dieser Wert wird immer mit dem des Roomba Adapter abgeglichen – heisst, wenn der Adapter “stop” meldet, aktualisiert sich dieser Datenpunkt auch. Wir können diesen Datenpunkt aber auch selber nutzen, um den iRobot zu steuern. Dies funktioniert mit folgenden Befehlen, die der Roomba Adapter zwar unterstützt aber nicht selbst anbietet:

WertBezeichnung
startStarten des iRobot
stopStoppen des iRobot
pausePausieren des iRobot
resumeFortsetzen des iRobot
dockiRobot zur Aufladestation senden
trainiRobot auf einen Kartierungslauf schicken
findiRobot suchen – ein Ton ertönt
evaciRobot an der Absaugstation absaugen lassen (nur für Modelle mit Absaugstation)
Mögliche Steuerbefehle

Anwendung des Skript – erweiterte Datenpunkte

Der Roomba Adapter bietet zwar die Ausgabe der erledigten Quadratmeter – dies funktioniert aber leider inzwischen – oder bei neueren Modellen – nicht mehr. Mein Skript zeigt Dir folgende Werte an:

DatenpunktBeschreibung
QuadratmeterGereinigte Quadratmeter des Durchlaufs
Wassertankfalse bei vollem Behälter – true bei leerem Behälter
WischtuchInstalliertes Wischtuch der Braava Modelle
Erweiterte Datenpunkte
Wie hat Dir der Beitrag gefallen?
Bewertung: 5/5 - abgegebene Bewertungen: 3

25 Gedanken zu „iRobot Steuerung in ioBroker

  1. ioBroker_newby Antworten

    Hallo.

    Das Script scheint super zu funktionieren. Die Räume konnte ich anlegen und die Namen habe ich angepasst. Jedoch bin ich zu doof meinen Roomba nun per (Loxone VO) Virtuellen Aussgang in einen Raum zu schicken. Seit bitte etwas nachsichtig bin gerade erst von Loxberry auf ioBroker umgestiegen.

    Mein Link sieht wie folg aus: http://ipdesiobroker:8087/javascript.0.iRobot.Lana.Geplante_Bereiche“, “Eingang, Kueche”, true);

    Antwort: { “error”: “command javascript.0.iRobot.Lana.Geplante_Bereiche”, “Eingang, Kueche”, true);

    Würde mir jemand auf die Sprünge helfen

    • Stephan Autor des BeitragsAntworten

      Du kannst, soweit mit bekannt ist, ioBroker nicht per http steuern, sondern nur per Datenpunkte.

      Gruß,
      Stephan

  2. chris Antworten

    moin, hat noch jemand das Problem,das der Fehler im Skript erscheint ( error javascript.0 (3254) script.js.common.iRobot-Control: iRobot-Control: Fehler: Roomba Adapter scheint nicht installiert zu sein! ) Der adapter ist aber installiert nur stürzt er immer wieder ab. hat die ip,id und das pw vom roomba i5+ abgerufen aber stürzt tzd immer wieder ab.

    • Stephan Autor des BeitragsAntworten

      Hallo Chris,
      Wenn der Adapter abstürzt ist dies ja “ähnlich” wie: nicht installiert.
      Ohne lauffähigen Roomba-adapter wird das Skript nicht funktionieren.

      Gruß,
      Stephan

  3. Volker Antworten

    Hallo Stephan,

    supportest du das Skript noch?

    Zuerst mal ganz herzlichen Dank, top Sache!

    Ein paar Anmerkungen hätte ich dazu:

    1.) Seit dem suchen der Räume bekomme ich ununterbrochen die Meldung:
    script.js.common.iRobot-Control: iRobot-Control: Neuer Raum für No-No gefunden und angelegt! ID: 11 (bzw. die Nummer des ersten zu reinigenden Raums)

    2.) Das Objekt “javascript.0.iRobot.No-No.Durchgang_Raeume” steht immer auf den letzten zu saugenden Räumen z.B. “Nicht definierter Raum (ID: 11), Nicht definierter Raum (ID: 8)”.

    3.) Die qm werden leider nicht gefüllt

    Die Namen habe ich korrekt eingepflegt z.B. “javascript.0.iRobot.No-No.Bereiche.xxxxxxxxxxxxxx.Raeume.11.name” mit “Küche”

    Die Welt geht davon nicht unter … das Spammen, kann ich ihm schon abgewöhnen, das Wichtigste ist der Aufruf der Räume und der Reihenfolge, aber wäre schon toll wenns komplett klappen würde.

    Herzlichen Dank und viele Grüße

    Volker

    • Volker Antworten

      Hallo Stephan,

      habe das Problem 1 und 2 lösen können.

      – neue Zeile über 28 eingefügt:
      var datenpunkt_komplett = “javascript.0.iRobot.”; // Abschließender Punkt !!! WICHTIG !!!

      – bei den 5 Vorkommen von >>existsState<>datenpunkt<>datenpunkt_komplett<>existsState<< den ganzen Pfad braucht und nicht nur das unterhalb von "javascript.0"

      Punkt 3 ist mir eigentlich egal 😉

      Nochmals ganz herzlichen Dank für deine Arbeit!
      Super Leistung 🙂

      Viele Grüße Volker

  4. Didier Antworten

    Hallo Stephan,

    Starte mit der Roomba App auf dem Smartphone einen Reinigungsauftrag für ein Gerät (beim Roomba ohne Nachwischen). Sobald der Roboter losgefahren ist (maximal 60 Sekunden später), kannst Du im Log von ioBroker erkennen, dass das Skript eine ID und einen Bereich (Zone oder Raum) ausgibt.

    Robot-Control: Neuer Raum für Roomba gefunden und angelegt! ID: 4

    Habe es so gemacht wie geschrieben bekomme leider keine Räume. Bzw keine neue Datenpunkte.

    Was mache ich falsch?

    Danke für deine Hilfe

    • Stephan Autor des BeitragsAntworten

      Hallo Didier,
      kommt denn eine Fehlermeldung im Log? Erscheint kein Datenpunkt unterhalb des javascript Adapters?

      Gruß,
      Stephan

  5. Alex Antworten

    Grüß dich Stephan,

    vielen lieben Dank für das Script. Das ist genau das, was ich brauche für unsere Roombas.
    Allerdings habe ich folgendes Problem:
    Es gibt zwei Roombas und zwei Instanzen des Roomba Adapters (Instanz 1 und 2 keine 0).
    Habe auch alles entsprechend eingestellt:

    // Instanzen der Geräte
    var datenpunkt_instanz = “roomba.”; // Abschließender Punkt | !!! BITTE NICHT ÄNDERN !!!
    var instanz_geraet = [1, 2]; // Installierte Instanz | Bsp: 0 für Roomba, 1 für Braava
    var instanz_name = [“Jarvis”, “Dobby”]; // Keine Leerzeichen | Namen der Geräte ohne Leerzeichen

    Es wird aber kein neuer Raum in Datenpunkt Dobby angelegt sondern es wird ein Undefined Datenpunkt erstellt und dort wird ein neuer Raum erstellt.
    Mit diesem undefined kann auch auch Dobby steuern. Also wird es Dobby sein, aber ohne richtigen Namen.

    Was könnte das sein?

    Danke dir

    LG Alex

    • Stephan Autor des BeitragsAntworten

      Hallo Alex,
      kannst du bzgl. deines Beitrags eine Mail mit dem Datenpunkt schicken? Dann könnte man einmal weiterschauen. Danke!

      Gruß,
      Stephan

  6. Christian Antworten

    Hallo Stephan,
    danke für dein Skript. Ich habe einen Braava Jet. Wenn ich diesen über dein Skript starte fährt er in den richtigen Raum und wischt, nutzt dabei aber nicht die Sprühfunktion. Wenn ich ihn über den roomba-Datenpunkt “roomba.0.commands.start” starte nutzt er die Sprühfunktion. Wie kann man die Spühfunktion in deinem Skript anschalten?

    Gruß Christian

      • Martin Antworten

        Hi, über die app hat man die Funktion nach dem Saugen zu wischen… kann man dass auch irgendwie integrieren??

        • Stephan Autor des BeitragsAntworten

          Hallo Martin,
          dazu müsstest Du dir ein Hilfs-Skript erstellen, welches dann reagiert, sobald der Sauger fertig ist und den Wische losschickt.

          Gruß,
          Stephan

  7. Carsten Antworten

    Hallo,

    ich wollte Dein Skript ausprobieren, es kommt allerdings beim Skriptstart zu einer Fehlermeldung bei mir:
    “javascript.0
    2021-10-14 09:13:23.654 error at processImmediate (internal/timers.js:461:21)
    javascript.0
    2021-10-14 09:13:23.654 error at Immediate._onImmediate (/opt/iobroker/node_modules/iobroker.js-controller/lib/adapter.js:5706:41)
    javascript.0
    2021-10-14 09:13:23.654 error at Object.stateChange (/opt/iobroker/node_modules/iobroker.javascript/main.js:525:29)
    javascript.0
    2021-10-14 09:13:23.654 error at Object.callback (/opt/iobroker/node_modules/iobroker.javascript/lib/sandbox.js:1087:38)
    javascript.0
    2021-10-14 09:13:23.654 error at Object. (script.js.common.iRobot-Control:56:17)
    javascript.0
    2021-10-14 09:13:23.653 error at robot_auftrag (script.js.common.iRobot-Control:73:35)
    javascript.0
    2021-10-14 09:13:23.653 error Error in callback: TypeError: Cannot read property ‘split’ of null”

    und der Ordner “Bereiche” wird nicht angelegt.

    • Stephan Autor des BeitragsAntworten

      Hallo Carsten
      danke für die Rückmeldung.

      Habe das Skript noch einmal angepasst.
      Du hast aber Zeile 32 und 33 an Deine Umgebung angepasst?

      Gruß,
      Stephan

      • Carsten Antworten

        Hallo Stephan, ja habe ich:
        // Instanzen der Geräte
        var datenpunkt_instanz = “roomba.”; // Abschließender Punkt | !!! BITTE NICHT ÄNDERN !!!
        var instanz_geraet = [0]; // Installierte Instanz | Bsp: 0 für Roomba, 1 für Braava
        var instanz_name = [“Roomba”]; // Keine Leerzeichen | Namen der Geräte ohne Leerzeichen

        Ich versiche mal Deine Änderungen

      • Carsten Antworten

        Nach Deinen Änderungen im Skript kommt zwar keine Fehlermeldung, es werden aber trotzdem nicht die Datenpunkte richtig angelegt. Der Ordner “Bereiche” fehlt weiterhin.

          • Stephan Autor des Beitrags

            Kein Problem. Melde Dich gerne, wenn Du nicht weiterkommst 😉

            Schick’ den Roboter einfach mit einem Raum auf die Reise und beobachte Log-Ausgabe. Dann erscheint eine ID. Diese ID findest Du dann, wie in der Anleitung erklärt, im Objekt-Baum unter Bereiche.

            Gruß,
            Stephan

          • Stephan Autor des Beitrags

            Hallo Carsten,
            ich wollte mal nachhören, ob das Skript bei Dir inzwischen funktioniert.
            Ich habe noch etwas angepasst, damit nun auch die Priorisierung der Räume richtig funktioniert.

            Gruß,
            Stephan

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert