iRobot Roomba 980 integration

Post Reply
rmbrmb
Posts: 11
Joined: Monday 05 December 2016 10:05
Target OS: Raspberry Pi
Domoticz version: Latest
Location: Netherlands
Contact:

iRobot Roomba 980 integration

Post by rmbrmb » Sunday 25 December 2016 11:41

Hi,

I have an iRobot Roomba 980 robot vacuum cleaner, with wifi connection.
It is possible to control the robot via an app and I know how to control this robot via HTTP POST commands.
Can someone advise me how to accomplish this with Lua, or do I have to call Curl via the Lua script?
Also I want to query the status of the robot every 15 minutes, to check if the robot is back on it's base again.

If I use Curl to query the status, the command would look like (assume Roomba has IP 192.168.10.70);
curl -H "Content-Type: application/json" -H "Connection: close" -H "User-Agent: aspen%20production/2618 CFNetwork/758.3.15 Darwin/15.4.0" -H "Content-Encoding: identity" -H "Accept: */*" -H "Accept-Language: en-us" -H "Host: 192.168.10.70" -H "Authorization: Basic [base64-password]" -X POST -d '{"do":"get","args":["mssn"],"id":1}' -k https://192.168.10.70/umi

Then I get (for example) the following response;
{"ok":{"flags":0,"cycle":"none","phase":"charge","pos":{"theta":179,"point":{"x":221,"y":-12}},"batPct":97,"expireM":0,"rechrgM":0,"error":0,"notReady":0,"mssnM":0,"sqft":0},"id":1}

"cycle":"none" tells me the robot is not driving around.
"phase":"charge" tells me the robot is on it's base station, charging.
Also the "error" and "notReady" fields are possibly interesting to monitor.

I would like to query these fields with a Lua script and put them individually in Domoticz variables for further processing.

There is a lot more possible with HTTP POST commands, so if someone is able to write a plugin for full integration of the Roomba 980 in Domoticz that would be even better!

Start a cleaning-job:

POST https://192.168.10.70/umi
Content-Type: application/json
Connection: close
User-Agent: aspen%20production/2618 CFNetwork/758.3.15 Darwin/15.4.0
Content-Encoding: identity
Accept: */*
Accept-Language: en-us
Host: 192.168.10.70
Authorization: Basic [base64-password]

{"do":"set","args":["cmd" {"op":"start"}],"id":1}

Pause the cleaning-job (replace the commands above with):
{"do":"set","args":["cmd" {"op":"pause"}],"id":1}

Resume the cleaning-job (replace the commands above with):
{"do":"set","args":["cmd" {"op":"resume"}],"id":1}

Stop the cleaning-job (replace the commands above with):
{"do":"set","args":["cmd" {"op":"stop"}],"id":1}

Return to base (replace the commands above with):
{"do":"set","args":["cmd" {"op":"dock"}],"id":1}

You will need to get the uniq device password (replace field [base64-password] above, without brackets) and that can be a bit difficult.
Please check the article on the following page to accomplish that;
https://community.smartthings.com/t/roo ... g/44860/93

For more possible commands, please check the source code of the following project;
https://github.com/koalazak/dorita980/

Kind regards,
Rene.

rmbrmb
Posts: 11
Joined: Monday 05 December 2016 10:05
Target OS: Raspberry Pi
Domoticz version: Latest
Location: Netherlands
Contact:

Re: iRobot Roomba 980 integration

Post by rmbrmb » Sunday 25 December 2016 20:08

So far I have accomplished this with a bash script, but I can imagine this can be done prettier;

Code: Select all

#!/bin/bash

function jsonValue()
{
key=$1
num=$2
awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/'$key'\042/){print $(i+1)}}}' | tr -d '"' | sed -n ${num}p
}

output=`curl -s -H "Content-Type: application/json" -H "Connection: close" -H "User-Agent: aspen%20production/2618 CFNetwork/758.3.15 Darwin/15.4.0" -H "Content-Encoding: identity" -H "Accept-Language: en-us" -H "Host: 192.168.10.70" -H "Authorization: Basic [base64-password]" -X POST -d '{"do":"get","args":["mssn"],"id":1}' -k https://192.168.10.70/umi`

RoombaActivity=`echo $output | jsonValue cycle 1`
RoombaStatus=`echo $output | jsonValue phase 1`

if [ "$RoombaActivity" == "none" ]; then
   RoombaActivity='Geen'
else
   RoombaActivity='Bezig'
fi

if [ "$RoombaStatus" == "charge" ]; then
   RoombaStatus='Opladen'
elif [ "$RoombaStatus" == "stop" ]; then
   RoombaStatus='Gestopt'
else
   RoombaStatus='Bezig'
fi

echo "Roomba Activiteit   :" $RoombaActivity
echo -n "Bijgewerkt Domoticz :" && curl -s "http://127.0.0.1:8080/json.htm?type=command&param=updateuservariable&vname=RoombaActivity&vtype=2&vvalue=$RoombaActivity" | jsonValue status 1
echo "Roomba Status       :" $RoombaStatus
echo -n "Bijgewerkt Domoticz :" && curl -s "http://127.0.0.1:8080/json.htm?type=command&param=updateuservariable&vname=RoombaStatus&vtype=2&vvalue=$RoombaStatus" | jsonValue status 1

BakSeeDaa
Posts: 551
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi
Domoticz version:

Re: iRobot Roomba 980 integration

Post by BakSeeDaa » Monday 20 February 2017 19:56

rmbrmb wrote:Hi,

I have an iRobot Roomba 980 robot vacuum cleaner, with wifi connection.
...
Thanks for sharing this @Rene

I have one that will be delivered to me tomorrow and of course it needs to be automated. Awesome!

Cheers

rmbrmb
Posts: 11
Joined: Monday 05 December 2016 10:05
Target OS: Raspberry Pi
Domoticz version: Latest
Location: Netherlands
Contact:

Re: iRobot Roomba 980 integration

Post by rmbrmb » Monday 20 February 2017 21:02

You are welcome.

The only problem at this moment is that iRobot has pushed firmware 2.x, and since this release they have changed the communication protocol completely. The iRobot is now using MQTT in stead of HTTP with firmware 1.x.

There are more people looking for a solution... See also:
https://community.smartthings.com/t/roo ... /44860/144

BakSeeDaa
Posts: 551
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi
Domoticz version:

Re: iRobot Roomba 980 integration

Post by BakSeeDaa » Wednesday 22 February 2017 16:46

rmbrmb wrote:You are welcome.

The only problem at this moment is that iRobot has pushed firmware 2.x, and since this release they have changed the communication protocol completely. The iRobot is now using MQTT in stead of HTTP with firmware 1.x.

There are more people looking for a solution... See also:
https://community.smartthings.com/t/roo ... /44860/144
I've installed the dorita980: unofficial iRobot Roomba 980 NodeJS library / SDK and it's firmware 2.0.0 compatible. I installed it on a different Raspberry Pi, not the one that I use for Domoticz. The HTTP REST API interface is not firmware 2.0.0 compatible yet.

Cheers!
Last edited by BakSeeDaa on Friday 24 February 2017 10:46, edited 2 times in total.

BakSeeDaa
Posts: 551
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi
Domoticz version:

Re: iRobot Roomba 980 integration

Post by BakSeeDaa » Thursday 23 February 2017 12:28

Below is my current working solution for a RaspBerry Pi. It might be improved in many ways but I will await further development of the dorita980: unofficial iRobot Roomba 980 NodeJS library / SDK and the HTTP REST API interface before doing more.

First install the dorita980: unofficial iRobot Roomba 980 NodeJS library / SDK

Set up a Node.js-environment on your Raspberry Pi if You haven't done that already.

Create a dummy Text Device in Domoticz and name it "Adolf Status". (Yes, my iRobot Roomba 980 is named Adolf. Your iRobot Roomba 980 may be named differently.)

Optionally create a dummy Switch Device in Domoticz and name it "schAdolf". Assign a schedule to it and enter when the iRobot Roomba 980 is allowed to autostart)

Created a couple of dummy switches (Adolf Start, Adolf Stop, Adolf Pause, Adolf Resume), entered a 2 second delay off on each switch and put some LUA code into work. Then I made the following LUA script:

script_device_adolf.lua (Your tmp directory might be /tmp instead of /var/tmp Change if necessary!)

Code: Select all

commandArray = {}

if (devicechanged['Adolf Start'] == 'On') then -- Virtual switch to set on/off state
	os.execute('echo -ne start > /var/tmp/adolf-cmd > /dev/null 2>&1 &')
end

if (devicechanged['Adolf Stop'] == 'On') then -- Virtual switch to set on/off state
	os.execute('echo -ne stop > /var/tmp/adolf-cmd > /dev/null 2>&1 &')
end

if (devicechanged['Adolf Pause'] == 'On') then -- Virtual switch to set on/off state
	os.execute('echo -ne pause > /var/tmp/adolf-cmd > /dev/null 2>&1 &')
end

if (devicechanged['Adolf Resume'] == 'On') then -- Virtual switch to set on/off state
	os.execute('echo -ne resume > /var/tmp/adolf-cmd > /dev/null 2>&1 &')
end

if (devicechanged['Adolf Dock'] == 'On') then -- Virtual switch to set on/off state
	os.execute('echo -ne dock > /var/tmp/adolf-cmd > /dev/null 2>&1 &')
end

return commandArray
Create a user variable in Domoticz named roomba980LastRun

Create the following shell script:

/home/pi/domoticz/scripts/sh/adolfGetMission.sh

Code: Select all

#!/bin/bash

if pidof -x "adolf-getMission.js" >/dev/null; then
	echo "Adolf getMission process already running"
	exit 0
fi

node /home/pi/domoticz/scripts/js/adolf-getMission.js &
Create the following script:

home/pi/domoticz/scripts/js/adolf-getMission.js (Your tmp directory might be /tmp instead of /var/tmp Change if necessary!)

Code: Select all

#!/usr/bin/nodejs
var dorita980 = require('dorita980');
var request = require("request");
var fs = require('fs');
var domoHostAndPort = 'http://DOMOUSERNAME:DOMOPASSW@DOMOHOSTNAME:8080';
var domoTextDeviceIdx = 503; // Change this
var cleanMissionStatus = 5000; // default is 800ms
var myRobotViaLocal = new dorita980.Local('MyUsernameBlid', 'MyPassword', '192.168.4.70', 2, cleanMissionStatus);
var lastPhase = '';

myRobotViaLocal.on('mission', function (data) {
	var phase = data.cleanMissionStatus.phase;
	//console.log(phase);
	if (phase != lastPhase) {
		lastPhase = phase;
		tellDomoticz('Adolf', phase, domoTextDeviceIdx);
	}
	var cmdfile = '/var/tmp/adolf-cmd';
	fs.exists(cmdfile, function(exists) {
		if(exists) {
			var contents = fs.readFileSync(cmdfile, 'utf8');
			console.log('Received command: ' + contents);
			if (contents == 'start') myRobotViaLocal.start();
			if (contents == 'stop') myRobotViaLocal.stop();
			if (contents == 'dock') myRobotViaLocal.dock();
			if (contents == 'pause') myRobotViaLocal.pause();
			if (contents == 'resume') myRobotViaLocal.resume();
			fs.unlinkSync(cmdfile);
		}
	});
});

function getDateTime() {
	var date = new Date();
	var hour = date.getHours();
	hour = (hour < 10 ? "0" : "") + hour;
	var min = date.getMinutes();
	min = (min < 10 ? "0" : "") + min;
	var sec = date.getSeconds();
	sec = (sec < 10 ? "0" : "") + sec;
	var year = date.getFullYear();
	var month = date.getMonth() + 1;
	month = (month < 10 ? "0" : "") + month;
	var day = date.getDate();
	day = (day < 10 ? "0" : "") + day;
	return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
}

function tellDomoticz(robotName, newText, idx) {
	if (newText == 'run') {
		request(domoHostAndPort + "/json.htm?type=command&param=saveuservariable&vname=roomba980LastRun&vtype=2&vvalue=" + newText, function(error, response, body) {
		console.log(getDateTime() + ' Storing last run info for ' + robotName + ' : ' + response.statusCode);
	})
	}
	request(domoHostAndPort + "/json.htm?type=command&param=udevice&idx=" + idx + "&nvalue=0&svalue=" + newText, function(error, response, body) {
	console.log(getDateTime() + ' ' + robotName + ' ' + newText + ': ' + response.statusCode);
	})
}
Assign proper permissions

Code: Select all

chmod 755 /home/pi/domoticz/scripts/js/adolf-getMission.js
chmod 755 /home/pi/domoticz/scripts/sh/adolfGetMission.sh
Try if it's working:

Code: Select all

/usr/bin/nodejs /home/pi/domoticz/scripts/js/adolf-getMission.js
When it works, make a crontab entry:

Code: Select all

*/10 * * * * /home/pi/domoticz/scripts/sh/adolfGetMission.sh
Wait 10 minutes and check if the process is up and running

Code: Select all

ps -ef|grep dolf
Below some LUA code that I use in my system to autostart the iRobot Roomba 980 when I leave the premises. It's here just to give You some ideas. You will not be able to use exactly the same LUA script in your system.

Code: Select all

commandArray = {}
-- Start Adolf automatically ?
if ((devicechanged['Z1 Alarm'])
or (devicechanged['schAdolf'] == 'On')) then
	if ((otherdevices_svalues['Z1 Alarm'] == 'Arm Away')
	and (otherdevices['schAdolf'] == 'On')) then
		getMyDomo()
		-- Has it been more than 36 hours since last time Adolf went out?
		if (mydomo.utils.timedifference(uservariables_lastupdate['roomba980LastRun']) > (3600*36) ) then
			if (otherdevices['Adolf Status'] ~= 'run') then
				commandArray['Adolf Start'] = 'On'
			end
		end
	end
end

-- Pause Adolf if necessary when I'm engaged in a phone conversation
if (devicechanged['PhoneConversation'] or devicechanged['A580 IP']) then
	local switchCmd = 'Off'
	if (((otherdevices['PhoneConversation'] == 'On') or (otherdevices['A580 IP'] == 'On'))
	and (otherdevices_svalues['Adolf Status'] == 'run')) then
		commandArray['Adolf Pause'] = 'On'
	elseif (((otherdevices['PhoneConversation'] == 'Off') and (otherdevices['A580 IP'] == 'Off'))
	and (otherdevices_svalues['Adolf Status'] == 'stop')) then
		commandArray['Adolf Resume'] = 'On'
	end
end

return commandArray
Last edited by BakSeeDaa on Friday 24 February 2017 11:30, edited 5 times in total.

rmbrmb
Posts: 11
Joined: Monday 05 December 2016 10:05
Target OS: Raspberry Pi
Domoticz version: Latest
Location: Netherlands
Contact:

Re: iRobot Roomba 980 integration

Post by rmbrmb » Thursday 23 February 2017 12:41

Thanks for sharing!

BakSeeDaa
Posts: 551
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi
Domoticz version:

Re: iRobot Roomba 980 integration

Post by BakSeeDaa » Friday 24 February 2017 11:16

rmbrmb wrote:Thanks for sharing!
The code that I shared above has been updated. :D

Drago85
Posts: 1
Joined: Tuesday 05 December 2017 11:33
Target OS: Linux
Domoticz version:
Contact:

Re: iRobot Roomba 980 integration

Post by Drago85 » Tuesday 05 December 2017 12:09

Hello all,

I recently bougth an iRobot Roomba (896) and was looking at this post to include the Roomba to my Domoticz environment.
My Roomba was delivered with a newer firmware than dorita980 supports (in my case 3.2.7) and therefor the software/code needed some changes.

I wanted to share my code for people with the same "problem".

We need to change the local.js file from dorita980 because the variable "pose" does not exist in the 896 3.2.7 software.
Changes to "dorita980/lib/v2/local.js":

Code: Select all

'use strict';

const mqtt = require('mqtt');

var dorita980 = function localV2 (user, password, host, emitIntervalTime) {
  if (!user) throw new Error('robotID is required.');
  if (!password) throw new Error('password is required.');
  if (!host) throw new Error('host is required.');

  emitIntervalTime = emitIntervalTime || 800;
  var robotState = {};
  var missionInterval;

  const url = 'tls://' + host;

  var options = {
    port: 8883,
    clientId: user,
    rejectUnauthorized: false,
    protocolId: 'MQTT',
    protocolVersion: 4,
    clean: false,
    username: user,
    password: password
  };

  const client = mqtt.connect(url, options);

  client.on('error', function (e) {
    throw e;
  });

  client.on('connect', function () {
    missionInterval = setInterval(() => {
      if (robotState.cleanMissionStatus) { //) { && robotState.pose) {
        client.emit('mission', filterProps(['cleanMissionStatus', 'bin'])); //'pose', 'bin']));
      }
    }, emitIntervalTime);
  });

  client.on('close', function () {
    clearInterval(missionInterval);
  });

  client.on('packetreceive', function (packet) {
    if (packet.payload) {
      try {
        const msg = JSON.parse(packet.payload.toString());
        robotState = Object.assign(robotState, msg.state.reported);
        client.emit('update', msg);
        client.emit('state', robotState);
      } catch (e) {}
    }
  });

  function _apiCall (topic, command) {
    return new Promise((resolve, reject) => {
      let cmd = {command: command, time: Date.now() / 1000 | 0, initiator: 'localApp'};
      if (topic === 'delta') {
        cmd = {'state': command};
      }
      client.publish(topic, JSON.stringify(cmd), function (e) {
        if (e) return reject(e);
        resolve({ok: null}); // for retro compatibility
      });
    });
  }

function hasAllProps (obj, properties) {
    for (var p in properties) {
      if (!obj.hasOwnProperty(properties[p])) {
        return false;
      }
    }
    return true;
  }

  function filterProps (properties) {
    let ret = {};
    if (properties.length === 1) return robotState[properties[0]];
    for (var p in properties) {
      ret[properties[p]] = robotState[properties[p]];
    }
    return ret;
  }

  function waitPreferences (decode, waitFor, returnOnlyThat) {
    waitFor = (typeof waitFor === 'string') ? [waitFor] : waitFor;

    return new Promise((resolve) => {
      var checkInterval = setInterval(() => {
        if (hasAllProps(robotState, waitFor)) {
          clearInterval(checkInterval);
          resolve(returnOnlyThat ? filterProps(waitFor) : robotState);
        }
      }, 100);
    });
  }

  return Object.assign(client, {
    getTime: () => waitPreferences(false, ['utctime'], true),
    getBbrun: () => waitPreferences(false, ['bbrun'], true),
    getLangs: () => waitPreferences(false, ['langs'], true),
    getSys: () => waitPreferences(false, ['bbrstinfo', 'cap', 'sku', 'batteryType', 'soundVer', 'uiSwVer', 'navSwVer', 'wifiSwVer', 'mobilityVer', 'bootloaderVer', 'umiVer', 'softwareVer', 'audio', 'bin'], true),
    getWirelessLastStatus: () => waitPreferences(false, ['wifistat', 'wlcfg'], true),
    getWeek: () => waitPreferences(false, ['cleanSchedule'], true),
    getPreferences: (decode) => waitPreferences(decode, ['cleanMissionStatus', 'cleanSchedule', 'name', 'vacHigh', 'pose', 'signal'], false),
    getRobotState: (fields) => waitPreferences(false, fields, false),
    getMission: (decode) => waitPreferences(decode, ['cleanMissionStatus', 'pose', 'bin', 'batPct'], true),
    getWirelessConfig: () => waitPreferences(false, ['wlcfg', 'netinfo'], true),
    getWirelessStatus: () => waitPreferences(false, ['wifistat', 'netinfo'], true),
    getCloudConfig: () => waitPreferences(false, ['cloudEnv'], true),
    getSKU: () => waitPreferences(false, ['sku'], true),
    start: () => _apiCall('cmd', 'start'),
    pause: () => _apiCall('cmd', 'pause'),
    stop: () => _apiCall('cmd', 'stop'),
    resume: () => _apiCall('cmd', 'resume'),
    dock: () => _apiCall('cmd', 'dock'),
    setWeek: (args) => _apiCall('delta', {cleanSchedule: args}),
    setPreferences: (args) => _apiCall('delta', args),
    setCarpetBoostAuto: () => _apiCall('delta', {'carpetBoost': true, 'vacHigh': false}),
    setCarpetBoostPerformance: () => _apiCall('delta', {'carpetBoost': false, 'vacHigh': true}),
    setCarpetBoostEco: () => _apiCall('delta', {'carpetBoost': false, 'vacHigh': false}),
    setEdgeCleanOn: () => _apiCall('delta', {'openOnly': false}),
    setEdgeCleanOff: () => _apiCall('delta', {'openOnly': true}),
    setCleaningPassesAuto: () => _apiCall('delta', {'noAutoPasses': false, twoPass: false}),
    setCleaningPassesOne: () => _apiCall('delta', {'noAutoPasses': true, twoPass: false}),
    setCleaningPassesTwo: () => _apiCall('delta', {'noAutoPasses': true, twoPass: true}),
    setAlwaysFinishOn: () => _apiCall('delta', {'binPause': false}),
    setAlwaysFinishOff: () => _apiCall('delta', {'binPause': true})
  });
};

module.exports = dorita980;
We also need to change the "-getMission.js", besides the "pose" we need to change seeing the variable does not exist we also need to change the code so we don't leave any open streams to our Roomba.
As a bonus we will create a file that stores the last phase so we won't keep updating it unnecessarily.
FYI my Roomba is called Dusty so change the settings to your liking:

Code: Select all

#!/usr/bin/nodejs
var dorita980 = require('/usr/lib/node_modules/dorita980');
var request = require('/usr/lib/node_modules/dorita980/node_modules/request');
var fs = require('fs');
var domoHostAndPort = 'http://admin:DomoPassword@IP-Address:Port';
var domoTextDeviceIdx = 16; //Device idx of the Roomba state device
var cleanMissionStatus = 5000;
var myRobotViaLocal = new dorita980.Local('MyUsernameBlid', 'MyPassword', 'IP-Address', 2, cleanMissionStatus);
var lastPhaseFile = '/usr/local/domoticz/stateFiles/dustyLastPhase';
var lastPhase = fs.readFileSync(lastPhaseFile, 'utf8');
var cmdfile = '/var/tmp/dusty-cmd';

myRobotViaLocal.on('mission', function (data) {
        var phase = data.cleanMissionStatus.phase;
        if (phase != lastPhase) {
                lastPhase = phase;
		fs.writeFile(lastPhaseFile, lastPhase, function(err) {
    			if(err) {
			        return console.log(err);
			}

		    	console.log("Dusty current state saved in state file!");
		}); 
                tellDomoticz('Dusty', phase, domoTextDeviceIdx);
        }
	else {
		console.log('Dusty Phase same as before = ' + phase);
	}
        fs.exists(cmdfile, function(exists) {
                if(exists) {
                        var contents = fs.readFileSync(cmdfile, 'utf8');
                        console.log('Received command: ' + contents);
                        if (contents == 'start'){
                                myRobotViaLocal.start()
                                .then(() => myRobotViaLocal.end()) // disconnect to leave the channel open for the mobile app.
                                .catch(console.log);
                        }
                        if (contents == 'stop'){
                                myRobotViaLocal.stop()
                                .then(() => myRobotViaLocal.end()) // disconnect to leave the channel open for the mobile app.
                                .catch(console.log);
                        }
                        if (contents == 'dock'){
                                myRobotViaLocal.dock()
                                .then(() => myRobotViaLocal.end()) // disconnect to leave the channel open for the mobile app.
                                .catch(console.log);
                        }
                        if (contents == 'pause'){
                                myRobotViaLocal.pause()
                                .then(() => myRobotViaLocal.end()) // disconnect to leave the channel open for the mobile app.
                                .catch(console.log);
                        }
                        if (contents == 'resume'){
                                myRobotViaLocal.resume()
                                .then(() => myRobotViaLocal.end()) // disconnect to leave the channel open for the mobile app.
                                .catch(console.log);
                        }
                        fs.unlinkSync(cmdfile);
                }
                myRobotViaLocal.end();
        });
 });


function getDateTime() {
        var date = new Date();
        var hour = date.getHours();
        hour = (hour < 10 ? "0" : "") + hour;
        var min = date.getMinutes();
        min = (min < 10 ? "0" : "") + min;
        var sec = date.getSeconds();
        sec = (sec < 10 ? "0" : "") + sec;
        var year = date.getFullYear();
        var month = date.getMonth() + 1;
        month = (month < 10 ? "0" : "") + month;
        var day = date.getDate();
        day = (day < 10 ? "0" : "") + day;
        return year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
}

function tellDomoticz(robotName, newText, idx) {
        if (newText == 'run') {
                request(domoHostAndPort + "/json.htm?type=command&param=updateuservariable&vname=dustyLastRun&vtype=2&vvalue=" + newText, function(error, response, body) {
                console.log(getDateTime() + ' Storing last run info for ' + robotName + ' : ' + response.statusCode);
        })
        }
        request(domoHostAndPort + "/json.htm?type=command&param=udevice&idx=" + idx + "&nvalue=0&svalue=" + newText, function(error, response, body) {
        console.log(getDateTime() + ' ' + robotName + ' ' + newText + ': ' + response.statusCode);
        })
}
I changed the crontab as well seeing I don't want to check the status at night because the Roomba will light up and we have pets:

Code: Select all

*/10 06-19 * * * /usr/local/domoticz/scripts/sh/dustyGetMission.sh
Hope this helps,

Drago

echeberri77
Posts: 36
Joined: Friday 09 March 2018 19:52
Target OS: Linux
Domoticz version: 3.9203
Location: Italy
Contact:

Re: iRobot Roomba 980 integration

Post by echeberri77 » Friday 09 March 2018 20:12

Hi BakSeeDaa, I'd like to post some questions about your configuration if it is possible. Thanks!
BakSeeDaa wrote:
Thursday 23 February 2017 12:28
Create a dummy Text Device in Domoticz and name it "Adolf Status". (Yes, my iRobot Roomba 980 is named Adolf. Your iRobot Roomba 980 may be named differently.)
My roomba980 is named Vicky. I managed to create Vicky Status under Configuration -> Device. I created it as: Dummy (Does nothing, use for virtual switches only).
BakSeeDaa wrote:
Thursday 23 February 2017 12:28
Created a couple of dummy switches (Adolf Start, Adolf Stop, Adolf Pause, Adolf Resume), entered a 2 second delay off on each switch and put some LUA code into work. Then I made the following LUA script:[...]
Whats do you mean? I created 5 virtual devices, text type, and I named them: Vicky Start, Vicky Stop, Vicky Pause, Vicky Resume.
Then..Do I have to put a lua script inside each device? I am confused.....I am a noob sorry.
BakSeeDaa wrote:
Thursday 23 February 2017 12:28

Code: Select all

var domoTextDeviceIdx = 503; // Change this
I changed Idx value putting value "5" that is the value of Dummy Hardware IDX but it is also the value of the first Virtual DEvice tha is called Vicky_Pause.
When Roomba start I can see the Vicky_Pause status changing (from charge to run to dock to pause...). But it is not supposed to work in this way.
I am missing something....

Can you help me?

Thanks

Xavier

Post Reply

Who is online

Users browsing this forum: Egregius, rimram31 and 5 guests