{"id":5,"date":"2020-09-11T20:12:01","date_gmt":"2020-09-11T18:12:01","guid":{"rendered":"https:\/\/blog.kihr.online\/?p=5"},"modified":"2020-09-14T09:23:28","modified_gmt":"2020-09-14T07:23:28","slug":"roomba-steuern-mit-fhem","status":"publish","type":"post","link":"https:\/\/blog.kihr.online\/?p=5","title":{"rendered":"Roomba steuern mit FHEM"},"content":{"rendered":"<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Lesedauer<\/span> <span class=\"rt-time\"> 4<\/span> <span class=\"rt-label rt-postfix\">Minuten<\/span><\/span>\n<p class=\"wp-block-paragraph\">Es gibt f\u00fcr die neueren Roomba mit WLAN Anbindung ein FHEM Modul Namens <a rel=\"noreferrer noopener\" href=\"https:\/\/forum.fhem.de\/index.php?topic=67632.0\" data-type=\"URL\" data-id=\"https:\/\/forum.fhem.de\/index.php?topic=67632.0\" target=\"_blank\">Roomba980<\/a>. Ich habe dieses einige Zeit benutzt, aber leider funktioniert es nicht immer zuverl\u00e4ssig. Es geht gerne mal die Verbindung zum Roomba verloren. Das geschah bei mir auch wieder einmal vor ein paar Wochen und es ist mir bisher nicht gelungen, das ganze wieder zum laufen zu bringen. Ich hatte dazu auch im Forum (siehe Link oben) nachgefragt, aber es gibt dort auch seit einigen Wochen vom Entwickler keine Antwort mehr.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ich hatte schon vorher, als mein Roomba980 noch neu war und es dieses Modul noch nicht gab, eine Steuerung mit Hilfe von <a href=\"https:\/\/fhem.de\/commandref.html#HTTPMOD\" data-type=\"URL\" data-id=\"https:\/\/fhem.de\/commandref.html#HTTPMOD\" target=\"_blank\" rel=\"noreferrer noopener\">HTTPMOD<\/a>, <a href=\"https:\/\/github.com\/koalazak\/dorita980\" data-type=\"URL\" data-id=\"https:\/\/github.com\/koalazak\/dorita980\" target=\"_blank\" rel=\"noreferrer noopener\">Dorita980<\/a> und <a href=\"https:\/\/github.com\/koalazak\/rest980\" data-type=\"URL\" data-id=\"https:\/\/github.com\/koalazak\/rest980\" target=\"_blank\" rel=\"noreferrer noopener\">Rest980<\/a> eingerichtet und habe das ganze jetzt wieder so getan. Wie das funktioniert, m\u00f6chte ich hier kurz erkl\u00e4ren.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\">Bei mir l\u00e4uft das Ganze auf ein Raspberry PI 4 Model B mit 4GB Speicher unter Raspbian GNU\/Linux Buster (10). Wer ein anderes System verwendet muss u.U. einige Anpassungen vornehmen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ich setzte voraus, dass FHEM bereits installiert und funktionst\u00fcchtig ist und node.js und npm auch bereits installiert sind.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zun\u00e4chst holen wir uns rest980 und installieren es (Ich habe das im FHEM home Verzeichnis getan):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/koalazak\/rest980.git\ncd rest980\nnpm install<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Dann m\u00fcssen wir uns f\u00fcr die Einrichtung von rest980 die Logindaten des Irobot hohlen. Da in dem rest980 das dorita980 bereits enthalten ist, m\u00fcssen wir uns das nicht extra hohlen. Wir k\u00f6nnen sofort das entsprechende Modul daf\u00fcr verwenden. Wir stehen noch immer im rest980 Verzeichnis:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run getpassword &lt;IP Robot IP><\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Einfach den Anweisungen folgen, dann sollte das auch funktionieren. Das ganze sollte in etwa so aussehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run getpassword 192.168.1.1\n\n> rest980@2.1.0 getpassword \/opt\/fhem\/rest980\n> node .\/node_modules\/dorita980\/bin\/getpassword.js \"192.168.1.1\"\n\nMake sure your robot is on the Home Base and powered on (green lights on). Then press and hold the HOME button on your robot until it plays a series of tones (about 2 seconds). Release the button and your robot will flash WIFI light.\nThen press any key here...\n\n{ ver: '2',\n  hostname: 'Roomba-xxxxxxxxxxxxx',\n  robotname: 'Dorita',\n  ip: '192.168.1.103',\n  mac: '12:12:12:12:12:12',\n  sw: 'v2.0.0-34',\n  sku: 'R98----',\n  nc: 0,\n  proto: 'mqtt',\n  blid: 'xxxxxxxxxxxxx' &lt;---- username\/blid\n}\nPassword=> :1:1486937829:gktkDoYpWaDxCfGh &lt;= Yes, all this string.\nUse this credentials in dorita980 lib :)<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Mit diesen Daten m\u00fcssen wir dann rest980 konfigurieren. Hierzu editieren wir config\/default.json. Die sollte dann etwa so aus sehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"port\": 3000,\n  \"blid\": \"xxxxxxxxxxxxx\",\n  \"password\": \":1:1486937829:gktkDoYpWaDxCfGh\",\n  \"robotIP\": \"192.168.1.1,\n  \"firmwareVersion\": 2,\n  \"enableLocal\": \"yes\",\n  \"enableCloud\": \"yes\",\n  \"keepAlive\": \"yes\",\n  \"basicAuthUser\": null,\n  \"basicAuthPass\": null,\n  \"sslKeyFile\": null,\n  \"sslCertFile\": null\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">F\u00fcr jede SW Version ab 2 muss die firmwareVersion auf 2 gestellt werden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Nun haben wir bereits ein rest980 das funktionieren sollte. Das k\u00f6nnen wir testen, indem wir im rest980 Verzeichnis ein<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm start<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">ausf\u00fchren. Wenn alles funktioniert erh\u00e4lt man diese Ausgabe:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> rest980@2.1.0 start \/opt\/fhem\/rest980\n> node .\/bin\/www<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Jeden request den man nun an die rest API schickt, kann man dann hier in der console sehen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wir richten nun das FHEM device ein. Das sieht so aus:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>define Roomba HTTPMOD http:\/\/localhost:3000\/api\/local\/info\/state 120\nattr Roomba userattr reading01JSON requestData requestHeader1 requestHeader2 set01Name set01NoArg:0,1 set01URL set02Name set02NoArg:0,1 set02URL\nattr Roomba enableControlSet 0\nattr Roomba event-on-change-reading cleanMissionStatus_phase\nattr Roomba extractAllJSON 1\nattr Roomba requestHeader1 Content-Type: application\/json\nattr Roomba requestHeader2 Accept: *\/*\nattr Roomba set01Name start\nattr Roomba set01NoArg 1\nattr Roomba set01URL http:\/\/localhost:3000\/api\/local\/action\/start\nattr Roomba set02Name dock\nattr Roomba set02NoArg 1\nattr Roomba set02URL http:\/\/localhost:3000\/api\/local\/action\/dock\nattr Roomba stateFormat {sprintf(\"%s, Battery at %d%%\", ReadingsVal($name,\"cleanMissionStatus_phase\",0),ReadingsVal($name,\"batPct\",0))}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Mit der define Anweisung wird das Device erzeugt und von der rest api der aktuelle Status alle 120 Sekunden ausgelesen. Mit dem stateFormat legen wir fast, das in der Statuszeile des Roomba dann der aktuelle Status und der Batteriezustand angezeigt wird.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn das Device so konfiguriert ist, sollte man dann auch die ersten Readings bekommen. Die Ausgabe in der console des rest980 sollte etwa so aussehen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> rest980@2.1.0 start \/opt\/fhem\/rest980\n> node .\/bin\/www\n\nGET \/api\/local\/info\/state 200 120.717 ms - 2395<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nun kann man auch bereits testen, ob das ganze funktioniert. Dazu einfach oben im Device <em>set Roomba start<\/em> ausw\u00e4hlen, oder diesen Befehl im input Bereich eingeben. Schon sollte der Roomba los rollen. Mit <em>set Roomba dock<\/em> hohlen wir ihn wieder zur\u00fcck. In der console wehen wir dann:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>> rest980@2.1.0 start \/opt\/fhem\/rest980\n> node .\/bin\/www\n\nGET \/api\/local\/info\/state 200 120.717 ms - 2395\nGET \/api\/local\/action\/start 200 2.438 ms - 2395\nGET \/api\/local\/action\/dock 200 2.486 ms - 2395<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn wir jetzt noch wollen, da\u00df die rest980 API nach jedem Systemstart zur Verf\u00fcgung steht, sollten wir uns daf\u00fcr eine service Konfiguration einrichten. Dazu erzeugen wir eine Datei \/etc\/systemd\/system\/rest980.service mit folgendem Inhalt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;Unit]\nDescription=Rest980 Interface to Dorita980\nWants=network.target\nAfter=fhem.service\nRequires=fhem.service\n\n&#91;Service]\nType=simple\nUser=fhem\nGroup=dialout\nWorkingDirectory=\/opt\/fhem\/rest980\nExecStart= \/usr\/bin\/npm start\nExecStop= \/usr\/bin\/npm stop\nRestart=on-failure\n\n&#91;Install]\nWantedBy=multi-user.target<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit l\u00e4sst sich der service dann starten und stoppen. Jetzt k\u00f6nnen wir das testen und aktivieren:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl daemon-reload\nsystemctl start rest980\nsystemctl status rest980\n\u25cf rest980.service - Rest980 Interface to Dorita980\n   Loaded: loaded (\/etc\/systemd\/system\/rest980.service; disabled; vendor preset: enabled)\n   Active: active (running) since Fri 2020-09-11 20:00:35 CEST; 10s ago\n Main PID: 9116 (node)\n    Tasks: 19 (limit: 4915)\n   CGroup: \/system.slice\/rest980.service\n           \u251c\u25009116 npm\n           \u251c\u25009127 sh -c node .\/bin\/www\n           \u2514\u25009128 node .\/bin\/www\n\nSep 11 20:00:35 raspfhem systemd&#91;1]: Started Rest980 Interface to Dorita980.\nSep 11 20:00:36 raspfhem npm&#91;9116]: > rest980@2.1.0 start \/opt\/fhem\/rest980\nSep 11 20:00:36 raspfhem npm&#91;9116]: > node .\/bin\/www\nsystemctl enable rest980\nCreated symlink \/etc\/systemd\/system\/multi-user.target.wants\/rest980.service \u2192 \/etc\/systemd\/system\/rest980.service.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Damit w\u00e4re das Device jetzt bereit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ich verwende es zum Beispiel daf\u00fcr, den Roomba zu starten, wenn der letzte das Haus verlassen hat. Der Roomba selbst hat keinen Schedule. Ich m\u00f6chte nicht, da\u00df der herumrattert, wenn jemand zu Hause ist. Wenn die FHEM erkannt hat, da\u00df sich f\u00fcr l\u00e4ngere Zeit niemand im Haus befindet, reinigt der Roomba dann selbst\u00e4ndig 2 mal pro Woche.<br>Da sich das Dock des Roomba bei mir an einer schlecht einsehbaren Stelle befindet, habe ich in der TabletUI auch eine Anzeige zum Zustand der Roomba und ob der Beh\u00e4lter voll ist.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Lesedauer<\/span> <span class=\"rt-time\"> 4<\/span> <span class=\"rt-label rt-postfix\">Minuten<\/span><\/span>Es gibt f\u00fcr die neueren Roomba mit WLAN Anbindung ein FHEM Modul Namens Roomba980. Ich habe dieses einige Zeit benutzt, aber leider funktioniert es nicht immer zuverl\u00e4ssig. Es geht gerne mal die Verbindung zum Roomba verloren. Das geschah bei mir auch wieder einmal vor ein paar Wochen und es ist mir bisher nicht gelungen, das [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[2],"tags":[18,16,15,12,11,5,17,3,13,14,21,20,6,4,10,9,8,7,19],"class_list":["post-5","post","type-post","status-publish","format-standard","hentry","category-fhem","tag-18","tag-16","tag-15","tag-12","tag-api","tag-dorita980","tag-e5","tag-fhem","tag-i7","tag-irobot","tag-nodej","tag-npm","tag-rest980","tag-roomba","tag-roomba-690","tag-roomba-960","tag-roomba-i7","tag-roomba980","tag-systemd","entry"],"_links":{"self":[{"href":"https:\/\/blog.kihr.online\/index.php?rest_route=\/wp\/v2\/posts\/5","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.kihr.online\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.kihr.online\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.kihr.online\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.kihr.online\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5"}],"version-history":[{"count":2,"href":"https:\/\/blog.kihr.online\/index.php?rest_route=\/wp\/v2\/posts\/5\/revisions"}],"predecessor-version":[{"id":16,"href":"https:\/\/blog.kihr.online\/index.php?rest_route=\/wp\/v2\/posts\/5\/revisions\/16"}],"wp:attachment":[{"href":"https:\/\/blog.kihr.online\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.kihr.online\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.kihr.online\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}