室内清扫机器人部分资料收集汇总

室内清扫机器人多以算法和专利为主。下面有些资料链接:

    

1 https://github.com/koalazak/rest980

2 https://github.com/NickWaterton/Roomba980-Python

3 https://github.com/incmve/roomba-esp8266

4 https://github.com/MaxguN/ld37-dungeoncleaner

5 https://github.com/koalazak/dorita980

6 https://github.com/koalazak

  


----机器翻译----

--------

rest980

建立状态 依赖状态

rest980创建一个http服务器来映射REST API中的所有dorita980方法,以通过HTTP请求来控制iRobot Roomba 980。

安装

$ git clone https://github.com/koalazak/rest980.git
$ cd rest980
$ npm安装

Fimrware版本

检查您的机器人固件版本!并在firmwareVersionrest980 配置中设置固件版本

组态

该服务可以通过编辑config/default.json或设置环境变量进行配置。

配置文件(config/default.json环境描述
港口港口(默认值:3000)要监听的HTTP端口。
blidBLID(必填) Roomba bl。。*
密码密码(必填) Roomba密码。*
robotIPROBOT_IP(可选)如果知道您的机器人IP来跳过发现并加快启动,请设置。
固件版本固件版本(可选)设置为1或2取决于您的机器人固件版本。固件1.6.6默认为1
enableLocalENABLE_LOCAL(可选)如果要禁用本地API,请设置为“否”。默认为“是”。
enableCloudENABLE_CLOUD(可选)如果要禁用云API,请设置为“否”。默认为“是”。
活着活着(可选)如果要在每个请求中连接并断开与机器人的连接,请设置为“否”(缓慢但为官方移动应用程序免费使用连接)。
basicAuthUserBASIC_AUTH_USER(可选)设置为启用基本认证。必须设置用户和通行证。
basicAuthPassBASIC_AUTH_PASS(可选)设置为启用基本认证。必须设置用户和通行证。
sslKeyFileSSL_KEY_FILE(可选)设置密钥文件的路径以启用HTTPS。密钥和证书必须设置。(如何创建自签名证书)

| sslCertFile | SSL_CERT_FILE | (可选)将cert文件的路径设置为启用HTTPS。密钥和证书必须设置。(如何创建自签名证书) |

有关获取机器人blid和密码的更多信息和说明,请参阅dorita980

启动API服务器

$ cd rest980
$ DEBUG=rest980:* npm start
rest980:server Listening on port 3000

DEBUG=rest980:*如果你愿意,请省略 你可以随身携带npm start

或使用Docker Image

您可以使用koalazak / rest980 docker映像在docker容器中运行此服务器。例如,可以运行在Synology上。

拉码头图片:

码头拉Koalazak / rest980

运行Docker图像:

docker run -e BLID=myuser -e PASSWORD=mypass -e ROBOT_IP=myrobotIP koalazak/rest980

Dockerfile

您也可以在本地从泊坞这个构建和测试Dockerfile

docker build . -t koalazak/rest980 

API文档

现在您可以在端口3000上向此服务器发出请求。有两个主要端点:localcloud映射到dorita980本地和云方法。

错误响应:

HTTP状态500和响应:

{"message":"human message","error":{}}

本地

操作

所有清理操作都在/api/local/action/[action]使用GET方法的端点下,而不使用查询参数:

可用操作:

  • 开始
  • 停止
  • 暂停
  • 码头
  • 恢复

示例:开始清理

GET http:// 192.1681.1103000 / api / local / action / start

成功回应:

{"ok":null,"id":23}

信息

所有信息端点正在/api/local/info/[record]使用GET方法而不使用查询参数:

可用记录:

  • 任务
  • 无线
  • lastwireless
  • SYS
  • SKU
  • 状态(仅在固件2中)

示例:获取当前任务变量

GET http:// 192.1681.1103000 / api / local / info / mission

成功回应:

{ "ok":
   { "flags": 0,
     "cycle": "none",
     "phase": "charge",
     "pos": { "theta": 179, "point": {"x": 102, "y": -13} },
     "batPct": 99,
     "expireM": 0,
     "rechrgM": 0,
     "error": 0,
     "notReady": 0,
     "mssnM": 0,
     "sqft": 0 },
  "id": 2 }

配置

所有配置端点正在/api/local/config/[configName]使用GET方法来获取当前配置和POST方法来设置新配置。

可用的configName:

  • ptime(仅固件1中的GET)
  • bbrun(只有GET)
  • 云(仅GET)
  • langs(只有GET preferences,用于设置lang)
  • 时间(固件1中的POST Y GET)固件2中只有GET)
  • 优先
  • carpetBoost / auto(仅POST preferences)用于获取当前配置)
  • carpetBoost /性能(仅POST preferences)用于获取当前配置)
  • carpetBoost / eco(只有POST preferences,用于获取当前配置)
  • edgeClean / on(仅POST preferences,用于获取当前配置)
  • edgeClean / off(仅POST preferences)用于获取当前配置)
  • cleaningPasses / auto(仅POST preferences)用于获取当前配置)
  • cleaningPasses / one(仅POST preferences)用于获取当前配置)
  • cleaningPasses / two(仅POST preferences)用于获取当前配置)
  • alwaysFinish / on(仅POST preferences,用于获取当前配置)
  • alwaysFinish / off(仅POST preferences)用于获取当前配置)

有关每种方法和版本固件的响应和身体参数,请参见dorita980文档。

例子:

获取固件首选项1:
GET http:// 192.1681.1103000 / api / local / config / preferences

成功回应:

{ok  
   {flags  1024//请参阅dorita980文档中的清洁首选项表。
     lang  2
     时区 '美洲/布宜诺斯艾利斯'
     名称 ' myRobotName '
     cleanPreferences  {
        carpetBoost  ' auto '// 'auto','performance',' 
        eco'edgeClean  true
        cleanPasses  ' 1 '// '1','2',' 
        auto'alwaysFinish  true 
      }
    },
 id  2 }

有关固件2中的偏好设置,请参阅dorita980文档。

在固件1中设置首选项:
POST http:// 192.1681.1103000 / api / local / config / preferences

身体:

{ 
  "flags": 1107, // See Cleaning Preferences table in dorita980 documentation.
  "lang": 2,
  "timezone": "America/Buenos_Aires",
  "name": "myRobotName"
}

成功回应:

{"ok":null,"id":293}

有关固件2中的偏好设置,请参阅dorita980文档。

将清洁通行证设置为两个:
POST http:// 192.1681.1103000 / api / local / config / cleaningPasses / two

身体:

{}

成功回应:

{"ok":null,"id":293}

云(仅适用于固件1.6.x)

GETinfo没有查询参数的所有端点中使用

  • / API /云/资讯/状态
  • / API /云/信息/历史
  • / API /云/信息/ missionHistory

GETaction没有查询参数的所有端点中使用

  • / API /云/动作/清洁
  • / API /云/动作/快速
  • / API /云/动作/斑点
  • / API /云/动作/码头
  • / API /云/动作/启动
  • / API /云/动作/停止
  • / API /云/动作/暂停
  • / API /云/动作/简历
  • / API /云/动作/唤醒
  • / API /云/动作/复位
  • / API /云/动作/发现
  • / API /云/动作/擦拭
  • / API /云/动作/睡眠
  • / API /云/动作/关
  • / API /云/动作/ fbeep

例:

GET http:// 192.1681.1103000 / api / cloud / action / clean

成功回应:

{"status":"OK","method":"multipleFieldSet"}

主机图像或文件

您可以将图像或文件添加到public/文件夹以提供静态文件。

实时地图(实验)

访问 http://serverIP:3000/map浏览器,您可以玩这个很酷的实验


--------

Roomba980的Python

非官方iRobot Roomba 980 python库(SDK)。

感谢https://github.com/koalazak/dorita980,其中大部分内部工作来自于。

这是版本1.0,所以它可能是错误的!

忠告

如果您喜欢python980,它适用于您,我建议您阻止互联网访问您的机器人,以避免OTA固件更新。新的固件更改可能导致python980停止工作。可以使用路由器上的家长控制选项来执行阻止固件更新。

当发布新的固件时,您可以来这里验证python980是否仍然兼容。一旦python980兼容,您可以临时启用互联网访问您的机器人来获得固件升级。

固件2.xx注释

此库仅用于固件2.xx 检查您的机器人版本! NEW 现在支持Python 2.7和Python 3.6(感谢pschmitt添加Python 3兼容性)

仅支持本地连接,云连接是未来的项目。该项目是为了允许Openhab2控制,所以如果您将Roomba整合到Openhab2中,您可以从任何地方控制它。

由于当时只有一个连接可以进入Roomba本地mqtt服务器,如果您以连续模式运行,应用程序将通过云连接。在周期模式下,应用程序可以在本地连接,但是库会自动重新连接,直到应用程序断开连接。

测试固件版本为V2.2.5-2 / Ubuntu 14.04

特征

  • 轻松获取用户名/密码
  • 自动发现机器人IP(可选)
  • 本地API控件
  • 远程API控制(通过您的MQTT代理)
  • 简化清洁首选项设置。
  • NOT固件1.6.x兼容。
  • 固件2.xx兼容。
  • 多个Roombas支持(但未测试)
  • 连续或定期连接(允许本地应用访问)
  • 实时地图
  • 地图显示错误的位置,bin已满,已取消运行
  • 自动地图翻译和旋转(清洁完成/错误等)
  • 专为openhab2设计兼容性

实时地图

iRobot Roomba 980清洁地图使用python980 lib

OpenCV的

如果您安装了OpenCV,库将使用它来呈现最终的地图(完成/错误),它使用PIL for Live Maps,因此最终的地图看起来更好。这使用了大量的处理能力/内存,我不知道如果你在RPi或其他有限的平台上尝试这样做会发生什么!此外,如果启用调试模式(-D),则每次报告新的坐标(运行时每秒钟左右),绘制中间地图(edges.png,final_map.png等)。这消耗了大量的资源你被警告!

PIL

请使用最新版本的枕头(至少V 4.1.1),在早期版本的文本处理中存在一些令人讨厌的内存泄漏,这将迅速耗尽所有的RAM并使程序无响应。如果检测到较早版本的PIL,图书馆将发出警告。

如果您没有安装PIL,即使您有OpenCV,系统也不会绘制地图(即使已启用)。PIL用于基本图像处理。如果您没有特别启用地图,则不会绘制任何地图。roomba.py使用地图,但是类默认是禁用地图,所以在你自己的脚本中,如果你想要地图,你必须启用它们(在创建对象之后)。

依赖

此脚本/库旨在将/从本地MQTT服务器转发到roomba数据/命令(这是可选的)。在这种情况下,您需要安装paho-mqtt

<须藤> PIP安装PAHO-MQTT

对于地图绘制,您至少需要安装PIL(最好是最新版本的枕头)

<须藤> PIP安装枕

对于花哨的地图,您需要安装openCV(V2或V3,但未使用V3进行测试)。安装这个可能很复杂,所以我把它留给你。地图的作品没有它,但它更好。

安装

首先您需要安装python 2.7  python 3.6(感谢pschmitt添加Python 3兼容性),然后:

克隆此存储库:

git clone https://github.com/NickWaterton/Roomba980-Python.git
 cd Roomba980-Python

运行./roomba.py -h以获得选项。你会得到什么

nick @ proliant: / Scripts / roomba / Roomba980-Python $ ./roomba.py -h
用法:roomba.py [-h] [-f CONFIGFILE] [-n ROOMBANAME] [-t TOPIC]
                 [-T BROKERFEEDBACK] [-C BROKERCOMMAND] [-S BROKERSETTING]
                 [-b BROKER] [-p PORT] [-U USER] [-P PASSWORD] [-R ROOMBAIP]
                 [-u BLID] [-w ROOMBAPASSWORD] [-i INDENT] [-l LOG] [-e] [-D]
                 [-r] [-j] [-c] [-d DELAY] [-m] [-M MAPPATH] [-s MAPSIZE]
                 [-I ICONPATH] [-x EXCLUDE] [--version]

将Roomba 980的MQTT数据转发到本地 MQTT代理

可选参数:
  -h,--help显示此帮助消息并退出
  -f CONFIGFILE,--configfile CONFIGFILE
                        配置文件名(默认值:./config.ini)
  -n ROOMBANAME,--roombaName ROOMBANAME
                        可选Roomba名称(默认值:
  -t主题, - 主题主题
                        Roomba MQTT主题订阅(可以使用通配符 
                        和+默认值:
  -T BROKERFEEDBACK, -  BrokerFeedback BROKERFEEDBACK
                        经纪人主题发布反馈意见(默认值:
                        /的Roomba /反馈)
  -C BROKERCOMMAND, -  BrokerCommand BROKERCOMMAND
                        代理发布命令的代理主题(默认值:
                        /伦巴/命令
  -S BROKERSETTING, - 经纪人设置BROKERSETTING
                        经纪人发布设置的主题(默认值:
                        /伦巴/设置
  -b BROKER, - 经纪人经销商
                        MQTT代理的ipaddress(默认值:无)
  -p PORT,--port端口MQTT代理端口号(默认值:1883)
  -U USER,--user USER MQTT代理用户名(默认值:无)
  -P PASSWORD, - 密码密码
                        MQTT代理密码(默认值:无)
  -R ROOMBAIP,--roombaIP ROOMBAIP
                        Roomba 980的ipaddress(默认值:无)
  -u BLID,--blid BLID Roomba 980 blid(默认值:无)
  -w ROOMBAPASSWORD,--roomba密码ROOMBAPASSWORD
                        Roomba 980密码(默认值:无)
  -i INDENT,--indent INDENT
                        默认缩进= auto
  -l LOG,--log LOG路径/日志文件的名称(默认值:./Roomba.log)
  -e,--echo回到控制台(默认值:True)
  -D,--debug调试模式
  -r,--raw将原始数据输出到mqtt,不解码json数据
  -j,--pretty_print 日志中打印json
  -c, - 连续连接到Roomba(默认值:True)
  -d DELAY, - 延迟延迟
                        断开周期不连续的连接
                        (默认值:1000ms)
  -m,--drawmap Draw Roomba清除地图(默认值:True)
  -M MAPPATH,--mapPath MAPPATH
                        将地图存储到的位置(默认值:./)
  -s MAPSIZE,--mapSize MAPSIZE
                        地图尺寸,码头偏移和倾斜地图。(800,1500)
                        是大小,(0,0)是码头位置,中心
                        的地图,0是地图的旋转,0是
                        roomba的旋转。使用单引号
                        串。(默认值:'(800,1500,0,0,0,0)'
  -I ICONPATH,--iconPath ICONPATH
                        图标的位置。(默认值: ./ 
  -x EXCLUDE,--exclude EXCLUDE
                        排除有这个主题他们(默认:
  --version秀节目 S版号并退出

快速开始

有了在船坞的roomba 980和充电(并连接到wifi),站在roomba并运行

./roomba.py

要么

python roomba.py

按照说明,脚本将尝试找到roomba,获取IP,blid和密码 - 然后将其保存到本地配置文件。如果这样工作,程序将开始显示来自Roomba的消息,并且每隔几秒打印一次master_state。结果将记录到日志文件(默认情况下为Roomba.log)。

在未来的运行中(一旦成功),这些值将从配置文件中获取,因此您只需执行一次。您可以在命令行上手动指定这些,一些示例提供了启动bash脚本。我建议您尝试地图大小(如果您正在使用地图),因为这是一个不完全自动的变量。码头的大小,位置取决于您的房屋布局。地图布局的语法是(map x,map y,dock x,dock y,map rotation,roomba rotation)。参见示例。

示例输出

python标准日志记录模块支持日志记录

[I 2017-05-09 08:52:10,792 ] ******************* 
[I 2017-05-09 08:52:10,792] *计划开始* 
[我2017-05-09 08:52:10,792 ] *******************
[I 2017-05-09 08:52:10,792] Paho MQTT版本:1002003
[我2017-05-09 08:52:10,792] < CNTRL C >退出
[I 2017-05-09 08:52:10,792] Roomba 980 MQTT数据接口
[I 2017-05-09 08:52:10,792]连接到经纪人
[I 2017-05-09 08:52:10,792]创建Roomba对象192.168.100.181
[I 2017-05-09 08:52:10,793]连续连接
[I 2017-05-09 08:52:10,793]连接Roomba 192.168.100.181
[I 2017-05-09 08:52:10,793]发布DECODED数据
[I 2017-05-09 08:52:10,793]地图:启用地图
[I 2017-05-09 08:52:10,793]地图:打开现有的线路图像
[I 2017-05-09 08:52:10,814]地图:开辟存在的问题形象
[I 2017-05-09 08:52:10,830]地图:home_pos:(100,775)
[I 2017-05-09 08:52:10,834] MAP:初始化完成
[I 2017-05-09 08:52:10,835]连接
[I 2017-05-09 08:52:13,243] Roomba Connected
[I 2017-05-09 08:52:13,262]收到Roomba数据 wifistat,{  state :{  reported :{  netinfo :{  dhcp :true, addr :3232261301, mask :4294967040, gw :3232261121, dns1 :3232261121, dns2 :0, bssid  6c:b0:ce:14:2f:cd  sec :4}}}}
[I 2017-05-09 08:52:13,307]收到Roomba资料 wifistat,{  state :{ 报告:{  wifistat :{  wifi :1, uap :false, cloud :1}}}}
[I 2017-05-09 08:52:13,308]收到Roomba数据 wifistat,{  state :{ 报告:{  netinfo :{  dhcp :true, addr :3232261301, mask :4294967040, gw :3232261121, dns1 :3232261121, dns2 :0, bssid  6c:b0:ce:14:2f:cd  sec :4}}}}
[I 2017-05-09 08:52:13,309]收到Roomba资料 wifistat,{  state :{  reported :{  wlcfg :{  sec :7, ssid  7761746572746F6E73  }} }}
[I 2017-05-09 08:52:13,309]收到Roomba资料 wifistat,{  state :{ 据报:{  mac  f0:03:8c:13:24:5b  }}}
[I 2017-05-09 08:52:13,310]收到Roomba资料 $ aws / things / 3117850851637850 / shadow / update,{  state :{  reported :{  country  US  }}}
[I 2017-05-09 08:52:13,325]收到Roomba数据 $ aws / things / 3117850851637850 / shadow / update,{  state :{  reported :{  cloudEnv  prod  }}}
[I 2017-05-09 08:52:13,331]收到Roomba数据 $ aws / things / 3117850851637850 / shadow / update,{  state :{  reported :{  svcEndpoints :{  svcDeplId  v011  }}}}
[I 2017-05-09 08:52:13,429]收到Roomba数据 $ aws / things / 3117850851637850 / shadow / update,{  state :{  reported :{  mapUploadAllowed :true}}}
[I 2017-05-09 08:52:13,483]收到Roomba数据 wifistat,{  state :{  reported :{  localtimeoffset :-240, utctime :1494334341, pose :{  theta :-179, point :{  x :181, y :-13}}}}}
[I 2017年5月9日08:52:13533]所获的Roomba数据 $ AWS /东西/ 3117850851637850 /阴影/更新,{ 状态:{ 报道:{  batPct :100, :{ 已知:false}, bin :{  present :true, full :false}, audio :{  active :false}}}}
[I 2017-05-09 08:52:13,689]收到Roomba数据 $ aws / things / 3117850851637850 / shadow / update,{  state :{ 已报告:{  cleanMissionStatus :{  cycle  none  phase  charge  expireM :0, rechrgM :0, error :0,未就绪:0,  mssnM :0, 平方英尺:0, 引发剂 localApp  nMssn :109}, 语言:0,  noAutoPasses :假, NOPP :假, ecoCharge :false}}}:0, initiator  localApp  nMssn :109}, language :0, noAutoPasses :false, noPP :false, ecoCharge :false}}}:0, initiator  localApp  nMssn :109}, language :0, noAutoPasses :false, noPP :false, ecoCharge :false}}}noAutoPasses :false, noPP :false, ecoCharge :false}}}noAutoPasses :false, noPP :false, ecoCharge :false}}}
[I 2017-05-09 08:52:13,693]更新状态为:充电
[I 2017年5月9日08:52:13693] MAP:接收:new_co_ords:{ ' ý ':181,' X ':-13,' THETA ':-179} old_co_ords:{ ' ý ':181,' x ':-13,' theta ':-179}相位:充电状态:充电
[I 2017-05-09 08:52:13,693]地图:无视新阶段收费阶段
[我2017年5月9日08:52:13756]所获的Roomba数据 $ AWS /事/ 3117850851637850 /阴影/更新,{ 状态:{ 报道:{  vacHigh :假的, binPause :真, carpetBoost :真实的, openOnly :假的, twoPass :假的, schedHold :假的, lastCommand :{ 命令 dock  time :1494260716, initiator  localApp  }}}}
[I 2017-05-09 08:52:13,821]收到Roomba数据 $ aws / things / 3117850851637850 / shadow / update,{  state :{  reported :{  langs :[{  en-US :0},{  FR-FR :1},{  ES-ES :2},{  DE-DE :3},{ 它-IT :4}],  bbnav :{  aMtrack :98,nGoodLmrks :5, 再次:7,  aExpo :56},  bbpanic :{ 恐慌:[11,8,6,8,6]},  bbpause :{ 暂停:[ 0,14,0,0,0,0,17,0,4,0]}}}}bbpause :{ 暂停:[0,14,0,0,0,0,17,0,4,0]}}}}bbpause :{ 暂停:[0,14,0,0,0,0,17,0,4,0]}}}}
[I 2017-05-09 08:52:14,231]收到Roomba数据 $ aws / things / 3117850851637850 / shadow / update,{  state :{  reported :{  bbmssn :{  nMssn :109, nMssnOk :30, nMssnC :78, nMssnF :0, aMssnM :14, aCycleM :15}, bbrstinfo :{ nNavRst :3,  nMobRst :0, 导致 0000  }}}}
[I 2017年5月9日08:52:14242]所获的Roomba数据 $ AWS /东西/ 3117850851637850 /阴影/更新,{ 状态:{ 报道:{ :{ 姿势:1, OTA :2, 多路径:2,  carpetBoost :1,  PP :1,  binFullDetect :1,  langOta :1, 地图:1, 边缘:1, 生态:1},  SKU  R980020  batteryType 里斯片 soundVer  31  uiSwVer  4582  navSwVer  01.11.02  wifiSwVer  20923  }}}
[我的2017-05-09 08:52:14,245]收到Roomba数据 $ aws / things / 3117850851637850 / shadow / update,{  state :{  reported :{  mobilityVer  5420  bootloaderVer  4042  umiVer  6  softwareVer  v2.2.5-2 TZ :{ 事件:[{  DT :0, :-300},{  DT :0, :-240},{  DT :0, : -300}], ver :3}, timezone  America / Toronto  name  Roomba }}}
[I 2017-05-09 08:52:14,263]收到Roomba数据 $ aws / things / 3117850851637850 / shadow / update,{  state :{ 已报告:{  cleanSchedule :{  cycle :[ 开始开始开始开始开始], h :[0,9,9,9,9,0], m :[0,0,0,0,0,0,0]}, bbchg3 :{  avgMin :81, hOnDock :448, nAvail :163, estCap :12311, nLithChrg :38, nNimhChrg :0, nDocks :45}}}}m :[0,0,0,0,0,0]}, bbchg3 :{  avgMin :81, hOnDock :448, nAvail :163, estCap :12311  nLithChrg :38, nNimhChrg :0, nDocks :45}}}}m :[0,0,0,0,0,0]}, bbchg3 :{  avgMin :81, hOnDock :448, nAvail :163, estCap :12311  nLithChrg :38, nNimhChrg :0, nDocks :45}}}}hOnDock :448, nAvail :163, estCap :12311, nLithChrg :38, nNimhChrg :0, nDocks :45}}}}hOnDock :448, nAvail :163, estCap :12311, nLithChrg :38, nNimhChrg :0, nDocks :45}}}}
[I 2017年5月9日08:52:14304]所获的Roomba数据 $ AWS /东西/ 3117850851637850 /阴影/更新,{ 状态:{ 报道:{  bbchg :{  nChgOk :34, nLithF :0, 中止:[0,0,0]},  bbswitch :{  nBumper :41275,  nClean :37,  nSpot :12, nDock :45, nDrops :187}}}}
[I 2017年5月9日08:52:14310]所获的Roomba数据 $ AWS /东西/ 3117850851637850 /阴影/更新,{ 状态:{ 报道:{  bbrun :{ 小时:48,分钟:18, 平方英尺:190,  nStuck :7,  nScrubs :75,  nPicks :199,  nPanics :51, nCliffF :871, nCliffR :348, nMBStll :1, nWStll :3, nCBump :0}, bbsys :{  hr :518, min :55}}}} bbsys :{  hr :518, min :55}}}} bbsys :{  hr :518, min :55}}}}
[I 2017-05-09 08:52:15,406]收到Roomba资料 wifistat,{  state :{  reported :{  signal :{  rssi :-46, snr :39}}} }

如何获取用户名/ blid和密码

您可以按快速入门的方式自动获取,也可以运行:

./getpassword.py

有或没有你的roomba的IP地址。

./getpassword.py -R < roomba IP >

您还可以指定除默认值以外的配置文件(选项为-h)。结果显示并保存到配置文件。

API

API调用是(有关如何使用密码类的示例,请参阅getpassword.py):

password(address = ' 255.255.255.255 'file = 。\ config.ini 
Roomba(address = Noneblid = Nonepassword = Nonetopic = continuous = Trueclean = Falsecert_name = roombaName = file =  ./config.ini 

Roomba方法

连接()
断开()
send_command(命令)
set_preference(偏好设置)
set_mqtt_client(mqttc = NonebrokerFeedback = 
set_options(raw = Falseindent = 0pretty_print = False
enable_map(enable = FalsemapSize = (800,1500,0,0,0,0)mapPath =  ./ iconPath =  ./ home_icon_file =  home.png roomba_icon_file =  roomba .png roomba_error_file =  roombaerror.png roomba_cancelled_file = roombacancelled.png  roomba_battery_file = 的Roomba-charge.png  bin_full_file =  binfull.png roomba_size =5050),draw_edges  =  15auto_rotate = roomba_size =5050),draw_edges = 15auto_rotate = roomba_size =5050),draw_edges = 15auto_rotate = 
make_icon(input =  ./roomba.png output =  ./roomba_mod.png 

数据结构

布尔值
roomba_connected
bin_full
字符串
cleanMissionStatus_phase
当前状态
错误信息
字典
co_ords
master_state

笔记

如果你有多个roomba的话,这些应该被支持还没有被测试 - 我只有一个roomba!每个roomba都有自己的名字,这将自动用于区分它们。反馈发布到\roomba\feedback\<roomba name>\,命令转到\roomba\command\<roomba name>和设置\roomba\setting\<roomba name>地图等已经提供给他们。您可以在自己的脚本中手动指定对象中的roomba名称,在这种情况下也同样适用。

在你的python脚本中使用库

这两个脚本都在examples目录中,如simple.py和complexity.py。要使用它们,将它们从示例复制到主roomba.py目录(或者将roomba.py拷贝到示例中)。编辑它们以包括您自己的roomba ip地址,blid和密码,然后运行python simple.py对于“complex.py”,您还需要添加您的mqtt代理adddress,用户名和密码。然后跑python complicated.py

简单版本

 roomba 进口 Roomba

取消注释要运行的选项,并用您自己的值替换地址,blid和roombaPassword

address =   192.168.100.181  
blid =   3835850251647850  
roombaPassword =  :1:1493319243:gOizXpQ4lcdSoD1xJ 

myroomba = Roomba(address,blid,roombaPassword)
 或myroomba = Roomba()#如果你有一个配置文件 - 如果你不
myroomba.connect()

myroomba.set_preference( carpetBoost  true  myroomba.set_preference(“twoPass”,“false”)

 myroomba.send_command(“start”)
 myroomba.send_command(“stop”)
 myroomba.send_command(“dock”)

进口 JSON,时间
  范围5):
     打印 json.dumps(myroomba.master_state,缩进= 2
    时间(1
myroomba.disconnect()

更复杂的版本

 roomba 导入 Roomba
 导入 paho.mqtt.client 作为 mqtt
 import time
 import json

把自己的价值观在这里 
券商 =  本地主机     MQTT经纪人的IP 
用户 =  用户            MQTT用户名 
密码 =  密码    MQTT密码
如果不使用本地MQTT券商经纪人=无 
地址 =   192.168.100.181  
blid =   3515850261627850  
roombaPassword =  :1:1492379243:gOiyXpQ4lbRoD1xJ 

def  broker_on_connectclientuserdataflagsrc):
     print Broker Connected with result code  + str(rc))
      subscribe to roomba feedback 
    if rc ==  0
        mqttc.subscribe(brokerCommand)
        mqttc.subscribe(brokerSetting)
                    
DEF  broker_on_message诱蚊诱卵OBJMSG):
    发布到的Roomba 
    如果 命令  msg.topic:
         打印接收到的指令:%S   STR(msg.payload))
        myroomba.send_command(str(msg.payload))
     elif    msg.topic 中的设置print Received SETTING:%s   str(msg.payload))
        cmd =  str(msg.payload).split()
        myroomba.set_preference(cmd [ 0 ],cmd [ 1 ])
    
DEF  broker_on_publish诱蚊诱卵物镜中间):
     

高清 broker_on_subscribe诱蚊诱卵OBJ中期granted_qos):
     打印经纪人认购:%S  %S  STR(MID),STR(granted_qos)))

DEF  broker_on_disconnect诱蚊诱卵OBJRC):
     打印代理断开

高清 broker_on_log诱蚊诱卵OBJ水平字符串):
     打印(串)


mqttc =  
如果经纪人 不是 
    brokerCommand =   / roomba / command  
    brokerSetting =   / roomba / setting  
    brokerFeedback =   / roomba / feedback 
    
    连接到代理 
    mqttc = mqtt.Client()
    分配事件回调 
    mqttc.on_message = broker_on_message
    mqttc.on_connect = broker_on_connect
    mqttc.on_disconnect = broker_on_disconnect
    mqttc.on_publish = broker_on_publish
    mqttc.on_subscribe = broker_on_subscribe
    
    尝试
        mqttc.username_pw_set(用户名,密码)   把自己的MQTT的用户和密码,在这里,如果你使用的是他们,否则注释掉 
        mqttc.connect(经纪人,1883年60平MQTT经纪人每60秒如果没有数据从这个公布脚本。
        
    除了 例外  e:
         print无法连接到MQTT代理:%s   e)
        mqttc =  

myroomba =伦巴()  在Linux上的Debian系统连接所需minnimum,会读取配置文件连接
 myroomba =伦巴(地址,blid,roombaPassword,主题= “#”,连续=真,干净=假cert_name =”。 /ca-certificates.crt“)#手动设置东西

所有这些都是可选的,如果你不包括它们,默认值将会很好
如果你使用地图 
myroomba.enable_map( enable = True mapSize = (800,1650,-300,-50,2, 0) 在MapPath =  ./  iconPath =  ./ 使活地图,类默认是没有地图
,如果经纪人 不是 
    myroomba.set_mqtt_client(mqttc,brokerFeedback)如果要将Roomba数据发布到您自己的mqtt代理(默认情况下不是)如果您有多个roomba,并分配一个roombaName,则将其添加到此主题中(即brokerFeedback / roombaName)
终于连接到Roomba  - (必填!)
myroomba.connect()

print <CMTRL C>退出print订阅/ roomba / feedback /#查看已发布数据

尝试如果 mqttc   
        mqttc.loop_forever()
    elsewhile  Trueprint Roomba Data:%s   json.dumps(myroomba.master_state,indent = 2))
            时间(5
        
除了KeyboardInterruptSystemExit):
     print System exit Received  -  Exiting program 
    myroomba.disconnect()
    如果 mqttc   
        mqttc.disconnect()

数据/信息反馈

master_state启动空,并填写时间,默认情况下每5分钟完整发布一次(但是更新即将发布)

master_state应该包含:

{
    state  {
      reported  {
        netinfo  {
          dhcp  true addr  3232261301 mask  4294967040 gw  3232261121 dns1  3232261121 dns2  0 bssid   6c:b0:ce:14:2f:cd  sec  4
      },
       wifistat  {
         wifi  1 uap  false 1
      },
       wlcfg  {
         sec  7 ssid   7761746572746F6E73 
      },
       mac   f0:03:8c:13:24:5b  country   US  cloudEnv   prod  svcEndpoints  {
         svcDeplId   v011 
      },
       mapUploadAllowed  true localtimeoffset  - 240 utctime  1494331734 pose  {
         θ  - 179 point  {
           x  181 y  - 13
        }
      },
       batPct  100 dock  {
        已知 false
      },
       bin  {
         present  true full  false
      },
       audio  {
         active  true
      },
       cleanMissionStatus  {
        循环  充电 expireM  0 rechrgM  0错误 0未就绪 0 mssnM  0 sqft  0 initiator   localApp  nMssn  109
      },
      语言 0 noAutoPasses  假的 NOPP  假的 ecoCharge  假的 vacHigh  假的 binPause  真实的 carpetBoost  真实的 openOnly  假的twoPass  false schedHold  false lastCommand  { command   dock  time  1494260716 initiator   localApp  lastCommand  { command  dock  time 1494260716 initiator  localApp  lastCommand  {
         command  dock  time 1494260716 initiator  localApp 启动器 localApp 启动器 localApp 
      },
       langs  [
        {
           en-US  0
        },
        {
           fr-FR  1
        },
        {
           es-ES  2
        },
        {
           de-DE  3
        },
        {
           it-IT  4
        }
      ]
       bbnav  {
         aMtrack  98 nGoodLmrks  5 aGain  7 aExpo  56
      },
       bbpanic  {
        恐慌 [
           11 8 6 8 6
        ]
      },
       bbpause  {
        暂停 [
           0 14 0 0 0 0 17 0 4 0
        ]
      },
       bbmssn  {
         nMssn  109 nMssnOk  30 nMssnC  78 nMssnF  0 aMssnM  14 aCycleM  15
      },
       bbrstinfo  {
         nNavRst  3 nMobRst  0导致  0000 
      },
       cap  {
         pose  1 ota  2 multiPass  2 carpetBoost  1 pp  1 binFullDetect  1 langOta  1 maps  1边缘 1生态 1
      },
       SKU   R980020  batteryType  里斯片 soundVer   31  uiSwVer   4582  navSwVer   02年11月1日 wifiSwVer   20923 mobilityVer   5420  bootloaderVer   4042  umiVer   6  softwareVer   v2.2.5-2  TZ  {事件 [ bootloaderVer  4042  umiVer  6  softwareVer  v2.2.5-2  TZ  {事件 [ bootloaderVer  4042  umiVer  6  softwareVer  v2.2.5-2  TZ  {事件 [ softwareVer  v2.2.5-2  tz  { events  [ softwareVer  v2.2.5-2  tz  {
         events  [
          {
             dt  0 - 300
          },
          {
             dt  0 off  - 240
          },
          {
             dt  0 - 300
          }
        ]
         ver  3
      },
      时区 美国/多伦多 伦巴 cleanSchedule  {
        循环 [
          开始开始开始开始开始
        ]
         ħ  [
           0 9 9 9 9 9 0
        ]
         [
           0 0 0 0 0 0 0
        ]
      },
       bbchg3  {
         avgMin  81 hOnDock  448 nAvail  163 estCap  12311 nLithChrg  38 nNimhChrg  0 nDocks  45
      },
       bbchg  {
         nChgOk  34 nLithF  0中止 [
           0 0 0
        ]
      },
       bbswitch  {
         nBumper  41275 nClean  37 nSpot  12 nDock  45 nDrops  187
      },
       bbrun  {
         hr  48 min  18 sqft  190 nStuck  7 nScrubs  75 nPicks  199 nPanics  51 nCliffsF  871 nCliffR  348 nMBStll  1 nWStll  3 nCBump  000
      },
       bbsys  {
         hr  518 min  11
      },
       signal  {
         rssi  - 36 snr  53
      }
    }
  }
}

在原始模式下,来自Roomba的json直接传递到mqtt主题(通常为/ roomba / feedback),在正常模式下,每个json项被解码并作为一个单独的主题发布。要查看发布的主题及其值运行:

mosquitto_sub -v -t / roomba / feedback / 

输出应如下所示:

/ roomba / feedback / netinfo_dhcp True
/ roomba / feedback / netinfo_addr 3232261301
/ roomba / feedback / netinfo_mask 4294967040
/ roomba / feedback / netinfo_gw 3232261121
/ roomba / feedback / netinfo_dns1 3232261121
/ roomba / feedback / netinfo_dns2 0
/ roomba / feedback / netinfo_bssid 6c:b0:ce:14:2f:cd
/ roomba / feedback / netinfo_sec 4
/ roomba / feedback / wifistat_wifi 1
/ roomba / feedback / wifistat_uap False
/ roomba / feedback / wifistat_cloud 1
/ roomba / feedback / netinfo_dhcp True
/ roomba / feedback / netinfo_addr 3232261301
/ roomba / feedback / netinfo_mask 4294967040
/ roomba / feedback / netinfo_gw 3232261121
/ roomba / feedback / netinfo_dns1 3232261121
/ roomba / feedback / netinfo_dns2 0
/ roomba / feedback / netinfo_bssid 6c:b0:ce:14:2f:cd
/ roomba / feedback / netinfo_sec 4
/ roomba / feedback / wlcfg_sec 7
/ roomba / feedback / wlcfg_ssid 7761746572746F6E73
/ roomba / feedback / mac f0:03:8c:13:24:5b
/ roomba / feedback / country US
/ roomba / feedback / cloudEnv prod
/ roomba / feedback / svcEndpoints_svcDeplId v011
/ roomba / feedback / mapUploadAllowed True
/ roomba / feedback / localtimeoffset -240
/ roomba / feedback / utctime 1494330872
/ roomba / feedback / pose_theta -179
/ roomba / feedback / pose_point_x 181
/ roomba / feedback / pose_point_y -13
/ roomba / feedback / batPct 100
/ roomba / feedback / dock_known False
/ roomba / feedback / bin_present True
/ roomba / feedback / bin_full False
/ roomba / feedback / audio_active False
/ roomba / feedback / cleanMissionStatus_cycle none
/ roomba / feedback / cleanMissionStatus_phase charge
/ roomba / feedback / cleanMissionStatus_expireM 0
/ roomba / feedback / cleanMissionStatus_rechrgM 0
/ roomba / feedback / cleanMissionStatus_error 0
/ roomba / feedback / cleanMissionStatus_notReady 0
/ roomba / feedback / cleanMissionStatus_mssnM 0
/ roomba / feedback / cleanMissionStatus_sqft 0
/ roomba / feedback / cleanMissionStatus_initiator localApp
/ roomba / feedback / cleanMissionStatus_nMssn 109
/ roomba / feedback / language 0
/ roomba / feedback / noAutoPasses False
/ roomba / feedback / noPP虚假
/ roomba / feedback / ecoCharge False
/ roomba /反馈/状态充电
/ roomba / feedback / vacHigh False
/ roomba / feedback / binPause True
/ roomba / feedback / carpetBoost True
/ roomba / feedback / openOnly False
/ roomba / feedback / twoPass False
/ roomba / feedback / schedHold False
/ roomba / feedback / lastCommand_command码头
/ roomba / feedback / lastCommand_time 1494260716
/ roomba / feedback / lastCommand_initiator localApp
/ roomba /反馈/状态充电
/的Roomba /反馈/ LANGS [('的en-US ',0),(' FR-FR ',1),(' ES-ES ',2),('脱DE ',3),('它-IT ',4)]
/ roomba / feedback / bbnav_aMtrack 98
/ roomba / feedback / bbnav_nGoodLmrks 5
/ roomba / feedback / bbnav_aGain 7
/ roomba / feedback / bbnav_aExpo 56
/ roomba / feedback / bbpanic_panics [11,8,6,8,6]
/ roomba / feedback / bbpause_pauses [0,14,0,0,0,0,17,0,4,0]
/ roomba /反馈/状态充电
/ roomba / feedback / bbmssn_nMssn 109
/ roomba / feedback / bbmssn_nMssnOk 30
/ roomba / feedback / bbmssn_nMssnC 78
/ roomba / feedback / bbmssn_nMssnF 0
/ roomba / feedback / bbmssn_aMssnM 14
/ roomba / feedback / bbmssn_aCycleM 15
/ roomba / feedback / bbrstinfo_nNavRst 3
/ roomba / feedback / bbrstinfo_nMobRst 0
/ roomba / feedback / bbrstinfo_causes 0000
/ roomba /反馈/状态充电
/ roomba / feedback / cap_pose 1
/ roomba / feedback / cap_ota 2
/ roomba / feedback / cap_multiPass 2
/ roomba / feedback / cap_carpetBoost 1
/ roomba / feedback / cap_pp 1
/ roomba / feedback / cap_binFullDetect 1
/ roomba / feedback / cap_langOta 1
/ roomba / feedback / cap_maps 1
/ roomba / feedback / cap_edge 1
/ roomba / feedback / cap_eco 1
/ roomba / feedback / sku R980020
/ roomba / feedback / batteryType lith
/ roomba / feedback / soundVer 31
/ roomba / feedback / uiSwVer 4582
/ roomba / feedback / navSwVer 01.11.02
/ roomba / feedback / wifiSwVer 20923
/ roomba /反馈/状态充电
/ roomba / feedback / mobilityVer 5420
/ roomba / feedback / bootloaderVer 4042
/ roomba / feedback / umiVer 6
/ roomba / feedback / softwareVer v2.2.5-2
/ roomba / feedback / tz_events [(' dt ',0),(' off ',-300),(' dt ',0),(' off ',-240),(' dt ',0),(' off ',-300)]
/ roomba / feedback / tz_ver 3
/ roomba / feedback / timezone美洲/多伦多
/ roomba / feedback / name Roomba
/ roomba /反馈/状态充电
/ roomba / feedback / cleanSchedule_cycle [ ' none '' start '' start '' start '' start '' start '' none ' ]
/ roomba / feedback / cleanSchedule_h [0,9,9,9,9,9,0]
/ roomba / feedback / cleanSchedule_m [0,0,0,0,0,0,0]
/ roomba / feedback / bbchg3_avgMin 81
/ roomba / feedback / bbchg3_hOnDock 448
/ roomba / feedback / bbchg3_nAvail 163
/ roomba / feedback / bbchg3_estCap 12311
/ roomba / feedback / bbchg3_nLithChrg 38
/ roomba / feedback / bbchg3_nNimhChrg 0
/ roomba / feedback / bbchg3_nDocks 45
/ roomba /反馈/状态充电
/ roomba / feedback / bbchg_nChgOk 34
/ roomba / feedback / bbchg_nLithF 0
/ roomba / feedback / bbchg_aborts [0,0,0]
/ roomba / feedback / bbswitch_nBumper 41275
/ roomba / feedback / bbswitch_nClean 37
/ roomba / feedback / bbswitch_nSpot 12
/ roomba / feedback / bbswitch_nDock 45
/ roomba / feedback / bbswitch_nDrops 187
/ roomba /反馈/状态充电
/ roomba / feedback / bbrun_hr 48
/ roomba / feedback / bbrun_min 18
/ roomba / feedback / bbrun_sqft 190
/ roomba / feedback / bbrun_nStuck 7
/ roomba / feedback / bbrun_nScrubs 75
/ roomba / feedback / bbrun_nPicks 199
/ roomba / feedback / bbrun_nPanics 51
/ roomba / feedback / bbrun_nCliffsF 871
/ roomba / feedback / bbrun_nCliffsR 348
/ roomba / feedback / bbrun_nMBStll 1
/ roomba / feedback / bbrun_nWStll 3
/ roomba / feedback / bbrun_nCBump 0
/ roomba / feedback / bbsys_hr 517
/ roomba / feedback / bbsys_min 57
/ roomba /反馈/状态充电
/ roomba / feedback / signal_rssi -35
/ roomba / feedback / signal_snr 54
/ roomba /反馈/状态充电
/ roomba / feedback / signal_rssi -36
/ roomba / feedback / signal_snr 53
/ roomba /反馈/状态充电

另外state并且error_message是由类派生的。

命令/设置

命令

  • 命令是:
    • “开始”
    • “停止”
    • “暂停”
    • “恢复”
    • “码头”

设置

  • 设置有:
    • 地毯真正
    • 真的真的
    • openOnly true 这是边缘清洁 - 设置为false以启用边缘清洁
    • noAutoPasses是真的
    • twoPass真的
    • binPause为true

你发布这个字符串到你的mqtt代理主题/ roomba / command或/ roomba /设置(或任何你已经定义,如果你更改这些默认)Ubuntu示例(假设代理在你的本地主机) - 应该适用于任何linux系统安装了蚊子

mosquitto_pub -t  / roomba / command  -m  start  
mosquitto_pub -t  / roomba / setting  -m  carpetBoost true 

或直接从python脚本调用(参见上面的简单示例)。

Openhab / Openhab2界面

这是我的Openhab2文件:

项目

/* Roomba items */
Group roomba_items  "Roomba"        <roomba>        (gGF)

/* Roomba Commands */
String roomba_command "Roomba" <roomba> (roomba_items) {mqtt=">[proliant:/roomba/command:command:*:${command}]", autoupdate=false}
/* Settings */
Switch roomba_edgeClean    "Edge Clean [%s]" <switch> (roomba_items) {mqtt=">[proliant:/roomba/setting:command:ON:openOnly false],>[proliant:/roomba/setting:command:OFF:openOnly true],<[proliant:/roomba/feedback/openOnly:state:MAP(inverse_switch.map)]", autoupdate=false}
Switch roomba_carpetBoost  "Auto carpet Boost [%s]" <switch> (roomba_items) {mqtt=">[proliant:/roomba/setting:command:ON:carpetBoost true],>[proliant:/roomba/setting:command:OFF:carpetBoost false],<[proliant:/roomba/feedback/carpetBoost:state:MAP(switch.map)]", autoupdate=false}
Switch roomba_vacHigh      "Vacuum Boost [%s]" <switch> (roomba_items) {mqtt=">[proliant:/roomba/setting:command:ON:vacHigh true],>[proliant:/roomba/setting:command:OFF:vacHigh false],<[proliant:/roomba/feedback/vacHigh:state:MAP(switch.map)]", autoupdate=false}
Switch roomba_noAutoPasses "Auto Passes [%s]" <switch> (roomba_items) {mqtt=">[proliant:/roomba/setting:command:ON:noAutoPasses false],>[proliant:/roomba/setting:command:OFF:noAutoPasses true],<[proliant:/roomba/feedback/noAutoPasses:state:MAP(inverse_switch.map)]", autoupdate=false}
Switch roomba_twoPass      "Two Passes [%s]" <switch> (roomba_items) {mqtt=">[proliant:/roomba/setting:command:ON:twoPass true],>[proliant:/roomba/setting:command:OFF:twoPass false],<[proliant:/roomba/feedback/twoPass:state:MAP(switch.map)]", autoupdate=false}
Switch roomba_binPause     "Always Complete (even if bin is full) [%s]" <switch> (roomba_items) {mqtt=">[proliant:/roomba/setting:command:ON:binPause false],>[proliant:/roomba/setting:command:OFF:binPause true],<[proliant:/roomba/feedback/binPause:state:MAP(inverse_switch.map)]", autoupdate=false}
/* Roomba Feedback */
String roomba_softwareVer  "Software Version [%s]" <text> (roomba_items) {mqtt="<[proliant:/roomba/feedback/softwareVer:state:default]"}
Number roomba_batPct "Battery [%d%%]" <battery> (roomba_items, Battery)  {mqtt="<[proliant:/roomba/feedback/batPct:state:default]"}
String roomba_lastcommand  "Last Command [%s]" <roomba> (roomba_items) {mqtt="<[proliant:/roomba/feedback/lastCommand_command:state:default]"}
Switch roomba_bin_present  "Bin Present [%s]" <trashpresent> (roomba_items) {mqtt="<[proliant:/roomba/feedback/bin_present:state:MAP(switch.map)]"}
Switch roomba_full   "Bin Full [%s]" <trash> (roomba_items) {mqtt="<[proliant:/roomba/feedback/bin_full:state:MAP(switch.map)]"}
/* Mission values */
String roomba_mission  "Mission [%s]" <msg> (roomba_items) {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_cycle:state:default]"}
Number roomba_nMssn    "Cleaning Mission Number [%d]" <number> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_nMssn:state:default]"}
String roomba_phase    "Phase [%s]" <msg> (roomba_items) {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_phase:state:default]"}
String roomba_initiator  "Initiator [%s]" <msg> (roomba_items) {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_initiator:state:default]"}
Switch roomba_error "Error [%]" <roombaerror> (roomba_items) {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_error:state:MAP(switchFromMqtt.map)]"}
String roomba_errortext  "Error Message [%s]" <msg> (roomba_items) {mqtt="<[proliant:/roomba/feedback/error_message:state:default]"}
Number roomba_mssnM "Cleaning Elapsed Time [%d m]" <clock> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_mssnM:state:default]"}
Number roomba_sqft "Square Ft Cleaned [%d]" <groundfloor> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_sqft:state:default]"}
Number roomba_expireM "Mission Recharge Time [%d m]" <clock> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_expireM:state:default]"}
Number roomba_rechrgM "Remaining Time To Recharge [%d m]" <clock> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/cleanMissionStatus_rechrgM:state:default]"}
String roomba_status    "Status [%s]" <msg> (roomba_items) {mqtt="<[proliant:/roomba/feedback/state:state:default]"}
Dimmer roomba_percent_complete    "Mission % Completed [%d%%]" <humidity> (roomba_items)
DateTime roomba_lastmissioncompleted "Last Mission Completed [%1$ta %1$tR]" <calendar>
/* Schedule */
String roomba_cycle   "Day of Week [%s]" <calendar> (roomba_items) {mqtt="<[proliant:/roomba/feedback/cleanSchedule_cycle:state:default]"}
String roomba_cleanSchedule_h   "Hour of Day [%s]" <clock> (roomba_items) {mqtt="<[proliant:/roomba/feedback/cleanSchedule_h:state:default]"}
String roomba_cleanSchedule_m   "Minute of Hour [%s]" <clock> (roomba_items) {mqtt="<[proliant:/roomba/feedback/cleanSchedule_m:state:default]"}
String roomba_cleanSchedule "Schedule [%s]" <calendar> (roomba_items)
/* General */
Switch roomba_control "Roomba ON/OFF [%s]" <switch> (roomba_items)
Number roomba_theta "Theta [%d]" <angle> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/pose_theta:state:default]"}
Number roomba_x "X [%d]" <map> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/pose_point_x:state:default]"}
Number roomba_y "Y [%d]" <map> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/pose_point_y:state:default]"}
Number roomba_rssi "RSSI [%d]" <network> (roomba_items)  {mqtt="<[proliant:/roomba/feedback/signal_rssi:state:default]"}
DateTime roomba_lastheardfrom "Last Update [%1$ta %1$tR]" <clock>

网站地图

Group item=roomba_items {
            Switch item=roomba_command mappings=[start="Start",stop="Stop",pause="Pause",dock="Dock",resume="Resume"]
            Switch item=roomba_control
            Group label="Map" icon="map" {
                Frame label="Map" {
                    //Image icon="map" url="http://your_OH_ip_address:port/static/map.png" label="Map" refresh=1000
                    Webview icon="map" url="http://your_OH_ip_address:port/static/roomba_map.html" height=40 label="Map"
                }
            }
            Group label="Settings" icon="select"{
                Text item=roomba_cleanSchedule
                Switch item=roomba_edgeClean
                Switch item=roomba_carpetBoost
                Switch item=roomba_vacHigh visibility=[roomba_carpetBoost==OFF]
                Switch item=roomba_noAutoPasses
                Switch item=roomba_twoPass visibility=[roomba_noAutoPasses==OFF]
                Switch item=roomba_binPause
            }
            Frame label="Status" {
                Text item=roomba_softwareVer
                Text item=roomba_batPct
                Text item=roomba_phase
                Text item=roomba_lastcommand
                Switch item=roomba_full mappings=[ON="FULL", OFF="Not Full"]
                Switch item=roomba_bin_present mappings=[OFF="Removed", ON="Installed"]
                Text item=roomba_rssi
                Text item=roomba_lastheardfrom
            }
            Frame label="Mission" {
                Text item=roomba_status
                Text item=roomba_rechrgM visibility=[roomba_status=="Recharging"]
                Text item=roomba_mission
                Text item=roomba_percent_complete
                Switch item=roomba_error mappings=[ON="ERROR!", OFF="Normal"]
                Text item=roomba_errortext
                Text item=roomba_mssnM
                Text item=roomba_sqft
                Text item=roomba_nMssn
                Text item=roomba_lastmissioncompleted
                Text item=roomba_initiator
            }
            Frame label="Location" {
                Text item=roomba_theta
                Text item=roomba_x
                Text item=roomba_y
            }
        }

变换

/etc/openhab2/transform/switch.map
ON=ON
OFF=OFF
0=OFF
1=ON
True=ON
False=OFF
true=ON
false=OFF
-=Unknown
NULL=Unknown

/etc/openhab2/transform/inverse_switch.map
ON=OFF
OFF=ON
0=ON
1=OFF
True=OFF
False=ON
true=OFF
false=ON
-=Unknown
NULL=Unknown

/etc/openhab2/transform/switchFromMqtt.map
-=Unknonwn
NULL=Unknown
OFF=OFF
0=OFF
1=ON
2=ON
3=ON
4=ON
5=ON
6=ON
7=ON
8=ON
9=ON
10=ON
11=ON
12=ON
13=ON
14=ON
15=ON
16=ON
17=ON
18=ON
19=ON
20=ON
21=ON
22=ON
23=ON
24=ON
25=ON
26=ON
27=ON
28=ON
29=ON
30=ON
31=ON
32=ON
33=ON
34=ON
35=ON
36=ON
37=ON
38=ON
39=ON
40=ON
41=ON
42=ON
43=ON
44=ON
45=ON
46=ON
47=ON
48=ON
49=ON
50=ON
51=ON
52=ON
53=ON
54=ON
55=ON
56=ON
57=ON
58=ON
59=ON
60=ON
61=ON
62=ON
63=ON
64=ON
65=ON
66=ON
67=ON
68=ON
69=ON
70=ON
71=ON
72=ON
73=ON
74=ON
75=ON
76=ON
77=ON
78=ON
79=ON
80=ON
81=ON
82=ON
83=ON
84=ON
85=ON
86=ON
87=ON
88=ON
89=ON
90=ON
91=ON
92=ON
93=ON
94=ON
95=ON
96=ON
97=ON
98=ON
99=ON
100=ON
101=ON
102=ON
103=ON
104=ON
105=ON
106=ON
107=ON
108=ON
109=ON
110=ON
111=ON
112=ON
113=ON
114=ON
115=ON
116=ON
117=ON
118=ON
119=ON
120=ON
121=ON
122=ON
123=ON
124=ON
125=ON
126=ON
127=ON
128=ON
129=ON
130=ON
131=ON
132=ON
133=ON
134=ON
135=ON
136=ON
137=ON
138=ON
139=ON
140=ON
141=ON
142=ON
143=ON
144=ON
145=ON
146=ON
147=ON
148=ON
149=ON
150=ON
151=ON
152=ON
153=ON
154=ON
155=ON
156=ON
157=ON
158=ON
159=ON
160=ON
161=ON
162=ON
163=ON
164=ON
165=ON
166=ON
167=ON
168=ON
169=ON
170=ON
171=ON
172=ON
173=ON
174=ON
175=ON
176=ON
177=ON
178=ON
179=ON
180=ON
181=ON
182=ON
183=ON
184=ON
185=ON
186=ON
187=ON
188=ON
189=ON
190=ON
191=ON
192=ON
193=ON
194=ON
195=ON
196=ON
197=ON
198=ON
199=ON
200=ON
201=ON
202=ON
203=ON
204=ON
205=ON
206=ON
207=ON
208=ON
209=ON
210=ON
211=ON
212=ON
213=ON
214=ON
215=ON
216=ON
217=ON
218=ON
219=ON
220=ON
221=ON
222=ON
223=ON
224=ON
225=ON
226=ON
227=ON
228=ON
229=ON
230=ON
231=ON
232=ON
233=ON
234=ON
235=ON
236=ON
237=ON
238=ON
239=ON
240=ON
241=ON
242=ON
243=ON
244=ON
245=ON
246=ON
247=ON
248=ON
249=ON
250=ON
251=ON
252=ON
253=ON
254=ON
255=ON
256=ON
ON=ON

规则

这些使用我的一个函数getTimestamp,这里是:

val Functions$Function2<GenericItem, String, String> getTimestamp = [  //function (lambda) to get a timestamp. Returns formatted string and optionally updates an item
    item,
    date_format |
    
    var date_time_format = date_format
    if(date_format == "" || date_format == null) date_time_format = "%1$ta %1$tT" //default format Day Hour:Minute:Seconds
    var String Timestamp = String::format( date_time_format, new Date() )
    if(item != NULL && item != null) {
        var Integer time = now().getMillis()    //current time (/1000?)
        var cal = new java.util.GregorianCalendar()
        cal.setTimeInMillis(time)  //timestamp in unix format
        var t = new DateTimeType(cal)
        
        if(item instanceof DateTimeItem) {
            postUpdate(item, t)
            logInfo("Last Update", item.name + " DateTimeItem updated at: " + Timestamp )
            }
        else if(item instanceof StringItem) {
            postUpdate(item, Timestamp)
            logInfo("Last Update", item.name + " StringItem updated at: " + Timestamp )
            }
        else
            logWarn("Last Update", item.name + " is not DateTime or String - not updating")
    }
    Timestamp
    ]

这里是我的roomba规则,其中一些假设你有电子邮件和pushNotification设置:

/* Roomba Rules */
rule "Roomba start and stop"
when 
    Item roomba_control received command
then
    logInfo("Roomba", "Roomba ON/OFF received command: " + receivedCommand)
    if (receivedCommand == ON)
        sendCommand(roomba_command, "start")
    if (receivedCommand == OFF) {
        sendCommand(roomba_command, "stop")
        Thread::sleep(1000)
        sendCommand(roomba_command, "dock")
    }
end

rule "Roomba Auto Boost Control"
when 
    Item roomba_carpetBoost changed
then
    logInfo("Roomba", "Roomba Boost changed to: Auto " + roomba_carpetBoost.state + " Manual: " + roomba_vacHigh.state)
    if (roomba_carpetBoost.state == ON && roomba_vacHigh.state == ON)
        sendCommand(roomba_vacHigh, OFF)
end

rule "Roomba Manual Boost Control"
when 
    Item roomba_vacHigh changed
then
    logInfo("Roomba", "Roomba Boost changed to: Auto " + roomba_carpetBoost.state + " Manual: " + roomba_vacHigh.state)
    if (roomba_carpetBoost.state == ON && roomba_vacHigh.state == ON)
        sendCommand(roomba_carpetBoost, OFF)
end

rule "Roomba Auto Passes Control"
when 
    Item roomba_noAutoPasses changed or
    Item roomba_twoPass changed
then
    logInfo("Roomba", "Roomba Passes changed to: Auto " + roomba_noAutoPasses.state + " Manual: " + roomba_twoPass.state)
    if (roomba_noAutoPasses.state == ON && roomba_twoPass.state == ON)
        sendCommand(roomba_twoPass, OFF)
end

rule "Roomba Last Update Timestamp"
when 
    Item roomba_rssi received update
then
    getTimestamp.apply(roomba_lastheardfrom, "%1$ta %1$tR")
end

rule "Roomba Bin Full"
when 
    Item roomba_full changed from OFF to ON
then
    val Timestamp = getTimestamp.apply(roomba_lastheardfrom, "%1$ta %1$tR")
    pushNotification("Roomba", "BIN FULL reported by Roomba at: " + Timestamp)
end

rule "Roomba Error"
when 
    Item roomba_error changed from OFF to ON
then
    val Timestamp = getTimestamp.apply(roomba_lastheardfrom, "%1$ta %1$tR")
    pushNotification("Roomba", "ERROR reported by Roomba at: " + Timestamp)
    sendMail(mailTo, "Roomba", "ERROR reported by Roomba at: " + Timestamp + "See attachment for details", "http://your_OH_ip:port/static/map.png")
end

rule "Roomba percent completed"
when 
    Item roomba_sqft received update
then
    var sqft_completed = roomba_sqft.state as Number 
    
    var max_sqft = 470  //insert max square footage here
    var min_sqft = 0

    var Number completed_percent = 0
    
    if (sqft_completed < min_sqft) {completed_percent = 0)      
    else if (sqft_completed > max_sqft) {completed_percent = 100} 
    else {
        completed_percent = (((sqft_completed - min_sqft) * 100) / (max_sqft-min_sqft)).intValue
        }
    logInfo("Roomba", "Roomba percent complete "+roomba_sqft.state+" of "+max_sqft.toString+" calculated as " + completed_percent.toString + "%")
    postUpdate(roomba_percent_complete,completed_percent)
end

rule "Roomba update command"
when 
    Item roomba_phase received update
then
    logInfo("Roomba", "Roomba phase received update: " + roomba_phase.state}
    switch(roomba_phase.state) {
        case "run"          : postUpdate(roomba_command,"start")
        case "hmUsrDock"    : postUpdate(roomba_command,"pause")
        case "hmMidMsn"     : postUpdate(roomba_command,"pause")
        case "hmPostMsn"    : {
                              postUpdate(roomba_command,"dock")
                              getTimestamp.apply(roomba_lastmissioncompleted, "%1$ta %1$tR")
                              }
        case "charge"       : postUpdate(roomba_command,"dock")
        case "stop"         : postUpdate(roomba_command,"stop")
        case "pause"        : postUpdate(roomba_command,"pause")
        case "stuck"        : postUpdate(roomba_command,"stop")
    }
end

rule "Roomba Notifications"
when 
    Item roomba_status changed
then
    logInfo("Roomba", "Roomba status is: " + roomba_status.state}
    val Timestamp = getTimestamp.apply(roomba_lastheardfrom, "%1$ta %1$tR")
    switch(roomba_status.state) {
        case "Running"                  : pushNotification("Roomba", "Roomba is RUNNING at: " + Timestamp)
        case "Docking - End Mission"    : {
                                          createTimer(now.plusSeconds(2)) [|
                                              pushNotification("Roomba", "Roomba has FINISHED cleaning at: " + Timestamp)
                                              sendMail(mailTo, "Roomba", "Roomba has FINISHED cleaning at: " + Timestamp + "See attachment for details", "http://your_OH_ip:port/static/map.png")
                                              ]
                                          }
        case "Stuck"                    : {
                                          pushNotification("Roomba", "HELP! Roomba is STUCK at: " + Timestamp)
                                          sendMail(mailTo, "Roomba", "HELP! Roomba is STUCK at: " + Timestamp + "See attachment for location", "http://your_OH_ip:port/static/map.png")
                                          }
    }
end

rule "Roomba Schedule Display"
when 
    Item roomba_cycle changed or
    Item roomba_cleanSchedule_h changed or
    Item roomba_cleanSchedule_m changed
then
    logInfo("Roomba", "Roomba Schedule: Day " + roomba_cycle.state + " Hour: " + roomba_cleanSchedule_h.state + " Minute: " + roomba_cleanSchedule_m.state)
    var String schedule = ""
    var String days = (roomba_cycle.state as StringType).toString
    var String hours = (roomba_cleanSchedule_h.state as StringType).toString
    var String minutes = (roomba_cleanSchedule_m.state as StringType).toString
    val ArrayList daysOfWeek = newArrayList("Sun","Mon","Tues","Wed","Thur","Fri","Sat")
    val ArrayList<String> daysList = new ArrayList(days.replace("[","").replace("]","").replace("'","").split(","))
    val ArrayList<String> hoursList = new ArrayList(hours.replace("[","").replace("]","").split(","))
    val ArrayList<String> minutesList = new ArrayList(minutes.replace("[","").replace("]","").split(","))
    daysList.forEach[ item, i | 
        if(item.trim() == "start") {
            schedule += daysOfWeek.get(i) + ": " + hoursList.get(i) + ":" + minutesList.get(i) + ", "
        }
    ]
    postUpdate(roomba_cleanSchedule, schedule.trim())
end

图标

我还在/ etc / openhab2 / icons / classic中有各种各样的roomba图标

这些是在openhab /图标,将它们复制到/ etc / openhab2 / icons / classic。项目和转型也在那里。

一般

start_openhab_roomba是一个bash脚本,可以在openhab2的正确位置(在Ubuntu上)启动roomba,您可能需要根据安装Openhab2的方式为其他系统(Windows,RPi等)更改此位置。您还需要安装mqtt绑定。在上述规则/站点地图替换your_OH_ip:port您自己的Openhab2 ip和端口 - 从任何地方使用,这些应该是外部可用(从您自己的网络外部)地址,否则您只能从您自己的网络(电子邮件附件应该工作)。

待办事项的

我正在使用我在网上找到的一些roomba图标,如果你有更好的roomba图标,请让我知道,我知道这些不是Roomba 980图标...更新这里显示的示例图,它是一个较旧的版本,新的更好一点。编写一个不错的web界面脚本。完成!(还有网页地图显示)。请参阅roomba_map.html- 对于openhab2将其复制到/ etc / openhab2 / html(与map.png相同的位置),现在可以通过http://your_OH_ip:port/static/roomba_map.html浏览器查看实时地图我使用一个子目录来避免混乱根html目录,只需在路径名中保持一致,并确保在运行roomba.py之前存在目录(具有写权限)!


--------

--------

--------

--------



这是一个乱码的文件名,无法直接读取。如果您知道该文件名的正确编码方式,可以使用相应的编码方式进行读取。如果您不知道该文件名的编码方式,可以尝试使用一些常见的编码方式进行读取,如UTF-8、GBK等。例如,您可以使用以下Java代码读取该文件名: ``` import java.io.File; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; public class ReadFileName { public static void main(String[] args) { String fileName = "�����š���ħ����-��-ʮ����.txt"; File file = new File(fileName); if (file.exists()) { System.out.println("文件存在,文件名为:" + decodeFileName(fileName)); } else { System.out.println("文件不存在!"); } } public static String decodeFileName(String fileName) { Charset[] charsets = new Charset[]{Charset.forName("UTF-8"), Charset.forName("GBK"), Charset.forName("ISO-8859-1")}; for (Charset charset : charsets) { try { String decodedName = new String(fileName.getBytes(charset), "UTF-8"); if (new File(decodedName).exists()) { return decodedName; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return fileName; } } ``` 在上述代码中,我们定义了一个 `decodeFileName()` 方法来尝试使用UTF-8、GBK、ISO-8859-1等编码方式进行读取。如果读取成功,则返回解码后的文件名;否则,返回原始文件名。在 `main()` 方法中,我们先判断文件是否存在,然后输出解码后的文件名。您可以根据实际情况修改该代码以适应您的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值