Coder Social home page Coder Social logo

pybotvac's Introduction

pybotvac

This is an unofficial API for controlling Neato Botvac Connected vacuum robots. The code is based on https://github.com/kangguru/botvac and credit for reverse engineering the API goes to Lars Brillert @kangguru

Disclaimer

This API is experimental. Use at your own risk. Feel free to contribute if things are not working.

Installation

Install using pip

pip install pybotvac

Alternatively, clone the repository and run

python setup.py install

Usage

Robot

If the serial and secret for your robot is known, simply run

>>> from pybotvac import Robot
>>> robot = Robot('OPS01234-0123456789AB', '0123456789ABCDEF0123456789ABCDEF', 'my_robot_name')
>>> print(robot)
Name: sample_robot, Serial: OPS01234-0123456789AB, Secret: 0123456789ABCDEF0123456789ABCDEF

The format of the serial should be 'OPSxxxxx-xxxxxxxxxxxx', and the secret should be a string of hex characters 32 characters long. These can be found by using the Account class.

To start cleaning

robot.start_cleaning()

If no exception occurred, your robot should now get to work.

Currently the following methods are available in the Robot class:

  • get_robot_state()
  • start_cleaning()
  • start_spot_cleaning()
  • pause_cleaning()
  • stop_cleaning()
  • send_to_base()
  • enable_schedule()
  • disable_schedule()
  • get_schedule()

For convenience, properties exist for state and schedule

# Get state
state = robot.state

# Check if schedule is enabled
robot.schedule_enabled

# Disable schedule
robot.schedule_enabled = False

Account

If the serial and secret are unknown, they can be retrieved using the Account class. You need a session instance to create an account. There are three different types of sessions available. It depends on your provider which session is suitable for you.

  • PasswordSession lets you authenticate via E-Mail and Password. Even though this works fine, it is not recommended.
  • OAuthSession lets you authenticate via OAuth2. You have to create an application here in order to generate client_id, client_secret and redirect_url.
  • PasswordlessSession is known to work for users of the new MyKobold App. The only known client_id is KY4YbVAvtgB7lp8vIbWQ7zLk3hssZlhR.
from pybotvac import Account, Neato, OAuthSession, PasswordlessSession, PasswordSession, Vorwerk

email = "Your email"
password = "Your password"
client_id = "Your client it"
client_secret = "Your client secret"
redirect_uri = "Your redirect URI"

# Authenticate via Email and Password
password_session = PasswordSession(email=email, password=password, vendor=Neato())

# Authenticate via OAuth2
oauth_session = OAuthSession(client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri, vendor=Neato())
authorization_url = oauth_session.get_authorization_url()
print("Visit: " + authorization_url)
authorization_response = input("Enter the full callback URL: ")
token = oauth_session.fetch_token(authorization_response)

# Authenticate via One Time Password
passwordless_session = PasswordlessSession(client_id=client_id, vendor=Vorwerk())
passwordless_session.send_email_otp(email)
code = input("Enter the code: ")
passwordless_session.fetch_token_passwordless(email, code)

# Create an account with one of the generated sessions
account = Account(password_session)

# List all robots associated with account
for robot in account.robots:
    print(robot)

Information about maps and download of maps can be done from the Account class:

>>> from pybotvac import Account
>>> # List all maps associated with a specific robot
>>> for map_info in Account(PasswordSession('[email protected]', 'sample_password')).maps:
...     print(map_info)

A cleaning map can be downloaded with the account class. Returns the raw image response. Example shows latest map. You need the url from the map output to do that:

>>> from pybotvac import Account
>>> # List all maps associated with a specific robot
>>> map = Account(PasswordSession('[email protected]', 'sample_password')).maps
>>> download_link = map['robot_serial']['maps'][0]['url']
>>> Account('[email protected]', 'sample_password').get_map_image(download_link)

pybotvac's People

Contributors

chemelli74 avatar darookee avatar dshokouhi avatar esteve avatar fermulator avatar herojc avatar jabesq avatar kvermilion avatar larsvinc avatar newam avatar raymccarthy avatar romrider avatar santobert avatar simontegelid avatar stephan1827 avatar stianaske avatar trunneml avatar turbokongen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pybotvac's Issues

No robots listed when schema verification fails on non-required fields

Issue

Running the latest commit (34b5941), I am unable to list any robots because the response verification fails.

Steps to recreate

Running

account = pybotvac.Account(pybotvac.PasswordSession(email=<email>, password=<password>))
for robot in list(account.robots):
  ...

on my account prints the following

Bad response from robots endpoint: expected str for dictionary value @ data['timezone']. Got: {'serial': 'OPSblabla', ... 'timezone': None, ...}

and the for loop returns.

Explanation

The reason for this appears to be that self._robots.add(robot_object) is being skipped if response verification throws in refresh_robots() in account.py, regardless of whether the exception is due to a required or non-required field missmatch:

    def refresh_robots(self):
        """
        Get information about robots connected to account.

        :return:
        """

        resp = self._session.get("users/me/robots")

        for robot in resp.json():
            _LOGGER.debug("Create Robot: %s", robot)
            try:
                ROBOT_SCHEMA(robot)
                robot_object = Robot(
                    name=robot["name"],
                    vendor=self._session.vendor,
                    serial=robot["serial"],
                    secret=robot["secret_key"],
                    traits=robot["traits"],
                    endpoint=robot["nucleo_url"],
                )
                self._robots.add(robot_object)
            except MultipleInvalid as ex:
                # Robot was not described accordingly by neato
                _LOGGER.warning(
                    "Bad response from robots endpoint: %s. Got: %s", ex, robot
                )
                continue
...

Proposed fixes

  1. ROBOT_SCHEMA should allow None as timezone entry
  2. Verification of a non-required field should create a log entry, but the rest of the code should execute as normal. If this is not possible, non-required fields should not be verified.

.maps response

Thanks for this great API!

Default commands like Start, Stop, Dock are now working great in my home automation Domoticz. Now I would like to go a little deeper and download de latest Map but I think something is wrong. I have a Botvac D5.

When running this command:
from pybotvac import Account
for robot in Account('[email protected]', 'sample_password').robots:
print(robot)

I get this reply:
Name: , Serial: -****, Secret: *****************************
Traits: Brutus Bot

When running this command:
from pybotvac import Account
for map_info in Account('[email protected]', 'sample_password').maps:
print(map_info)

I only get the serial number of the D5 in return.
So I can't get the "download_link" URL for the following command:

from pybotvac import Account
map = Account('[email protected]', 'sample_password').maps
download_link = map['robot_serial']['maps'][0]['url']
Account('[email protected]', 'sample_password').get_map_image('download_link')

Any Ideas?

Greetings.

sample.py issues

Has something changed in Neato side??

Running sample produces an error;

Robots:
Traceback (most recent call last):
File "./sample.py", line 12, in
for robot in account.robots:
File "/usr/lib/python2.6/site-packages/pybotvac-0.0.1-py2.6.egg/pybotvac/account.py", line 53, in robots
self.refresh()
File "/usr/lib/python2.6/site-packages/pybotvac-0.0.1-py2.6.egg/pybotvac/account.py", line 68, in refresh
secret=robot['secret_key']))
File "/usr/lib/python2.6/site-packages/pybotvac-0.0.1-py2.6.egg/pybotvac/robot.py", line 26, in init
self._url = 'https://nucleo.neatocloud.com/vendors/neato/robots/{}/messages'.format(self.serial)
ValueError: zero length field name in format

Locale is causing error

With the latest version 15 I receive the following error, version 13 works fine. I am located in germany and use MACOS 10.14.5 with Python3

Traceback (most recent call last):
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/startWohnzimmer.py", line 14, in
for robot in account.robots:
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/account.py", line 65, in robots
self.refresh_robots()
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/account.py", line 113, in refresh_robots
endpoint=robot['nucleo_url']))
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/robot.py", line 46, in init
if self.service_version not in SUPPORTED_SERVICES:
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/robot.py", line 231, in service_version
return self.available_services['houseCleaning']
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/robot.py", line 227, in available_services
return self.state['availableServices']
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/robot.py", line 223, in state
return self.get_robot_state().json()
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/robot.py", line 181, in get_robot_state
return self._message({'reqId': "1", 'cmd': "getRobotState"})
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/robot.py", line 63, in _message
headers=self._headers)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/api.py", line 116, in post
return request('post', url, data=data, json=json, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/api.py", line 60, in request
return session.request(method=method, url=url, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/sessions.py", line 519, in request
prep = self.prepare_request(req)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/sessions.py", line 462, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/models.py", line 317, in prepare
self.prepare_auth(auth, url)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests-2.22.0-py3.7.egg/requests/models.py", line 548, in prepare_auth
r = auth(self)
File "/Users/stephan/Documents/Development/Phyton/Neato/robot/pybotvac/robot.py", line 245, in call
locale.setlocale(locale.LC_TIME, 'en_US.utf8')
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/locale.py", line 604, in setlocale
return _setlocale(category, locale)
locale.Error: unsupported locale setting

HTTPError: 400 Client Error: Bad Request for url [neatocloud url]

Coming from #29

So after applying the quickfix in the aforementioned issue, I ran into this :

Traceback (most recent call last):
  File "botvac.py", line 165, in <module>
    ui.setupUi(MainWindow)
  File "botvac.py", line 114, in setupUi
    robot = Robot('[REDACTED]','[REDACTED]',u'maps','[REDACTED]')
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 41, in __init__
    if self.service_version not in SUPPORTED_SERVICES:
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 213, in service_version
    return self.available_services['houseCleaning']
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 209, in available_services
    return self.state['availableServices']
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 205, in state
    return self.get_robot_state().json()
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 163, in get_robot_state
    return self._message({'reqId': "1", 'cmd': "getRobotState"})
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 60, in _message
    response.raise_for_status()
  File "/usr/lib/python2.7/dist-packages/requests/models.py", line 935, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://nucleo.neatocloud.com/vendors/neato/robots/[REDACTED]/messages

By any chance, is the SSL reversable with the cert and thus decryptable ? So I could get an idea of what is going on with Wireshark.

BotVac D5 Does Not Work

It appears that it assumed that each service is expected to be a particular version, which causes BotVac D5 not to work.

Would you mind if I work on a pull request to at least support other service versions (according to Neato's documentation), and possibly add other stuff that is now documented, but not exposed by pybotvac?

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)

Long story short, one of my relatives got a Neato rob and I quickly searched the web to see if it was remotely usable.
I found your repo and since I'm currently experimenting with PyQt4, I decided to write a very basic UI for controlling the robot.

  • Installed with pip
  • python --version : Python 2.7.15rc1
  • Works without hiccups with the interpreter

However, things go wrong when I try to initialize the robot.

PyQt code (important bits)

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'botvac.ui'
#
# Created by: PyQt4 UI code generator 4.12.1
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
from pybotvac import Robot

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

[
.
.
.
]

        robot = Robot('[REDACTED]','[REDACTED]',u'maps','[REDACTED]')
        def __start(self):
            robot.start_cleaning()
            
        def __stop(self):
            robot.stop_cleaning()

        def __return(self):
            robot.send_to_base()
        
        self.startButton.clicked.connect(__start)
        self.stopButton.clicked.connect(__stop)
        self.returnButton.clicked.connect(__return)

Console output

Traceback (most recent call last):
  File "botvac.py", line 161, in <module>
    ui.setupUi(MainWindow)
  File "botvac.py", line 110, in setupUi
    robot = Robot('[REDACTED]','[REDACTED]',u'maps','[REDACTED]')
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 41, in __init__
    if self.service_version not in SUPPORTED_SERVICES:
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 213, in service_version
    return self.available_services['houseCleaning']
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 209, in available_services
    return self.state['availableServices']
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 205, in state
    return self.get_robot_state().json()
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 163, in get_robot_state
    return self._message({'reqId': "1", 'cmd': "getRobotState"})
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 59, in _message
    headers=self._headers)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 112, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 58, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 506, in request
    prep = self.prepare_request(req)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 449, in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
  File "/usr/lib/python2.7/dist-packages/requests/models.py", line 309, in prepare
    self.prepare_auth(auth, url)
  File "/usr/lib/python2.7/dist-packages/requests/models.py", line 540, in prepare_auth
    r = auth(self)
  File "/home/lili/.local/lib/python2.7/site-packages/pybotvac/robot.py", line 228, in __call__
    msg = '\n'.join([self.serial.lower(), date, request.body.decode('utf8')])
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)

Temporary fix

I found this answer on StackOverflow, but I feel it is bad practice and kind of hackish.

Not able to fetch maps

I'm trying the example:

from pybotvac import Account
for map_info in Account('[email protected]', 'sample_password').maps:
print(map_info)

But I get no output in terminal. If I do the same for .robots it shows serial, key, name and Traits: ['maps'] like it should. I have 20 maps available in the Neato app.

Recent cloud issues require botvac to get reconnected resulting in cached list of robots to be invalid for current session

I noticed that Neato had some cloud issues recently which caused my botvac to go offline in the app. I honestly believe that every botvac has this issue as I had to walk several users through going into the app and making sure the robot does not show "Robot Offline". This was with various botvac models as well and it also appears to be random. When this happens the botvac needs to be reset so it can be reconnected to Neato servers in the app. There is not much we can do here but I think a different problem may be fixed here. In Home Assistant we have to restart once reconnected as well because I believe the existing robot list is cached and needs to be refreshed?

https://github.com/stianaske/pybotvac/blob/master/pybotvac/account.py#L63

So what happens when the botvac goes offline is we continue to get a 404 error like below

requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://nucleo.neatocloud.com/vendors/neato/robots/OPS31116-04A316B0F207/messages

I know that when I reconnect the botvac the same endpoint is enabled again however I believe the list of robots is not refreshed for the state update? It seems to only refresh once according to the current logic I believe. I am not sure if this is something we should try to address in Home Assistant or in this library so wanted to open this up for discussion. Should we see if we can catch the 404 and force a robot refresh? I don't really know if that will fix it but I assume others that use this library has the same problem I described.

cant install

Hi,

if i want to install pybotvac, i get this:

pip install pybotvac

pip install pybotvac
Collecting pybotvac
  Using cached https://files.pythonhosted.org/packages/2c/69/2c33e5abadad7571ccf21c702cc36cb21defb90314efcf20bd79d5572b34/pybotvac-0.0.10.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-BtvPPK/pybotvac/setup.py", line 2, in <module>
        from pybotvac import __version__
      File "pybotvac/__init__.py", line 1, in <module>
        from .account import Account
      File "pybotvac/account.py", line 5, in <module>
        import urllib.parse
    ImportError: No module named parse

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-build-BtvPPK/pybotvac/

python setup.py install

Traceback (most recent call last):
  File "setup.py", line 2, in <module>
    from pybotvac import __version__
  File "/root/pybotvac/pybotvac/__init__.py", line 1, in <module>
    from .account import Account
  File "/root/pybotvac/pybotvac/account.py", line 5, in <module>
    import urllib.parse
ImportError: No module named parse

i installed requests:
pip list

DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.
ansible (2.6.4)
asn1crypto (0.24.0)
bcrypt (3.1.4)
certifi (2018.8.24)
cffi (1.11.5)
chardet (3.0.4)
chicken (0.1.0)
cryptography (2.3.1)
decorator (4.0.11)
egg (0.2.0)
enum34 (1.1.6)
feedparser (5.1.3)
gevent (1.3.6)
greenlet (0.4.15)
idna (2.7)
ipaddress (1.0.17)
Jinja2 (2.10)
keyring (10.1)
keyrings.alt (1.3)
MarkupSafe (1.0)
musicbrainzngs (0.6)
mutagen (1.36)
numpy (1.12.1)
paramiko (2.4.2)
pip (9.0.1)
pyasn1 (0.1.9)
pycparser (2.19)
pycrypto (2.6.1)
pygobject (3.22.0)
pyinotify (0.9.6)
PyNaCl (1.3.0)
pyOpenSSL (18.0.0)
python-dateutil (2.5.3)
pyxdg (0.25)
PyYAML (3.13)
quodlibet (3.7.1)
requests (2.19.1)
SecretStorage (2.3.1)
setuptools (40.4.3)
six (1.10.0)
urllib3 (1.23)
uTidylib (0.3)
version (0.1.1)
websocket (0.2.1)
wheel (0.29.0)

How can i fix it?

URL-lib

Imported pybotvac version 0.11 into my home assistant on docker by making a custom component and increasing the dependency on the version. It seems that removing the urlib did not work gracefully.

Parts of log output:
File "/config/custom_components/neato.py", line 179, in init
self._hass.data[NEATO_MAP_DATA] = self.my_neato.maps
File "/config/deps/lib/python3.6/site-packages/pybotvac/account.py", line 74, in maps
self.refresh_maps()
File "/config/deps/lib/python3.6/site-packages/pybotvac/account.py", line 86, in refresh_maps
requests.get(urllib.parse.urljoin(self.ENDPOINT,
NameError: name 'urllib' is not defined

I have confirmed that the library i pulled in is 0.11. I have also confirmed that it is working again by reverting to a import urllib as in the previous release.

HTTPError when using sample code

I managed to grab the serial and secret via password authentication, but when trying to run the sample code to print robot.state, I run into the following exception in robot.py:

Traceback (most recent call last):
  File "/home/zelmor/software_projects/python_projects/domovoi-desktop/venv/lib/python3.9/site-packages/pybotvac/robot.py", line 182, in _message
    response.raise_for_status()
  File "/home/zelmor/software_projects/python_projects/domovoi-desktop/venv/lib/python3.9/site-packages/requests/models.py", line 953, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://nucleo.neatocloud.com/vendors/neato/robots/OPSredacted/messages

The above exception was the direct cause of the following exception:


Traceback (most recent call last):
  File "/home/zelmor/software_projects/python_projects/domovoi-desktop/main.py", line 4, in <module>
    robot = Robot('OPSredacted',
  File "/home/zelmor/software_projects/python_projects/domovoi-desktop/venv/lib/python3.9/site-packages/pybotvac/robot.py", line 149, in __init__
    state = self.get_robot_state().json()
  File "/home/zelmor/software_projects/python_projects/domovoi-desktop/venv/lib/python3.9/site-packages/pybotvac/robot.py", line 337, in get_robot_state
    return self._message({"reqId": "1", "cmd": "getRobotState"}, STATE_SCHEMA)
  File "/home/zelmor/software_projects/python_projects/domovoi-desktop/venv/lib/python3.9/site-packages/pybotvac/robot.py", line 188, in _message
    raise NeatoRobotException("Unable to communicate with robot") from ex
pybotvac.exceptions.NeatoRobotException: Unable to communicate with robot

Not sure how to proceed here.

Zone Cleaning

I figured since a few of us with D7's have gotten zoned cleaning that we can use this issue to report on the data we have seen and how to best add zoned cleaning. Just now I was able to pull the botvac state while it was cleaning a specific zone and it seems like the user may need to do their own research to get the proper variables in place.

Here is the state output

{'version': 1, 'reqId': '1', 'result': 'ok', 'data': {}, 'error': None, 'alert': None, 'state': 2, 'action': 11, 'cleaning': {'category': 4, 'mode': 2, 'modifier': 1, 'navigationMode': 1, 'mapId': '2018-06-26T02:45:10Z', 'boundary': {'id': '009cdabd-5b38-4804-bdf2-da7de2e3f2d7', 'name': 'Hallway'}, 'spotWidth': 0, 'spotHeight': 0}, 'details': {'isCharging': False, 'isDocked': False, 'isScheduleEnabled': False, 'dockHasBeenSeen': True, 'charge': 94}, 'availableCommands': {'start': False, 'stop': True, 'pause': True, 'resume': False, 'goToBase': True}, 'availableServices': {'findMe': 'basic-1', 'generalInfo': 'basic-1', 'houseCleaning': 'basic-4', 'IECTest': 'advanced-1', 'logCopy': 'basic-1', 'manualCleaning': 'basic-1', 'maps': 'basic-2', 'preferences': 'basic-1', 'schedule': 'basic-2', 'softwareUpdate': 'basic-1', 'spotCleaning': 'basic-3', 'wifi': 'basic-1'}, 'meta': {'modelName': 'BotVacD7Connected', 'firmware': '4.3.1-180'}}

Major differences I see here is that mapId is required whereas before with category: 4 it would take the latest floorplan. I am not sure how we can get the boundary id without using pybotvac but the name is something the user will know.

Will need to play around with the above parameters to see exactly what we need to give.

If anyone has any ideas on how we can retrieve the boundary id and mapId easily that would be great, the only way I can think of for now is to run individual zone cleanings to get the proper data.

When I get a chance to play with this more I will report back but lets make sure the data lines up with everyone else :)

No releases

Hi.
I'm trying to use your awesome library with home-assistant. To do it I need your repository to have some releases. Could you please create some tags (at least for version 0.0.4)?

ImportError: No module named requests

I keep getting ImportError: No module named requests when I attempt to run the sample.

Zeus:sample Nick$ python sample.py Traceback (most recent call last): File "sample.py", line 1, in <module> from pybotvac import Account File "/Library/Python/2.7/site-packages/pybotvac-0.0.1-py2.7.egg/pybotvac/__init__.py", line 1, in <module> from .account import Account File "/Library/Python/2.7/site-packages/pybotvac-0.0.1-py2.7.egg/pybotvac/account.py", line 3, in <module> import requests ImportError: No module named requests

Any ideas?

No-go lines not used in Botvac D7?

When using the start_cleaning() function, I would expect my Botvac D7 Connected to use the no-go-lines I defined.
When I start the robot via Neato's app, the app displays "no-go lines enabled"; however, when I start via pybotvac, the app displays "no-go lines disabled".

From this code I would expect the robot to use the persistent maps and no-go lines when available (category=4):

        if category is None:
            category = (
                4
                if self.service_version in ["basic-3", "basic-4"]
                and self.has_persistent_maps
                else 2
            )

Am I missing something, and do I need to pass certain parameters to the start_cleaning function to enable the no-go lines?

Crash when listing robots

Hi!

Gets this message when I try to use the code:


$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pybotvac import Account
>>> for robot in Account('[email protected]', '<hidden>').robots: print(robot)
... 
/usr/lib/python3/dist-packages/urllib3/connection.py:266: SubjectAltNameWarning: Certificate for nucleo.neatocloud.com has no `subjectAltName`, falling back to check for a `commonName` for now. This feature is being removed by major browsers and deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 for details.)
  SubjectAltNameWarning
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/account.py", line 64, in robots
    self.refresh_robots()
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/account.py", line 108, in refresh_robots
    traits=robot['traits']))
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/robot.py", line 37, in __init__
    if self.service_version not in SUPPORTED_SERVICES:
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/robot.py", line 150, in service_version
    return self.available_services['houseCleaning']
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/robot.py", line 146, in available_services
    return self.state['availableServices']
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/robot.py", line 142, in state
    return self.get_robot_state().json()
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/robot.py", line 118, in get_robot_state
    return self._message({'reqId': "1", 'cmd': "getRobotState"})
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/robot.py", line 55, in _message
    headers=self._headers)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 107, in post
    return request('post', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/api.py", line 53, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 454, in request
    prep = self.prepare_request(req)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 388, in prepare_request
    hooks=merge_hooks(request.hooks, self.hooks),
  File "/usr/lib/python3/dist-packages/requests/models.py", line 297, in prepare
    self.prepare_auth(auth, url)
  File "/usr/lib/python3/dist-packages/requests/models.py", line 490, in prepare_auth
    r = auth(self)
  File "/usr/local/lib/python3.5/dist-packages/pybotvac/robot.py", line 170, in __call__
    signing = hmac.new(key=self.secret.encode('utf8'),
AttributeError: 'NoneType' object has no attribute 'encode'

I have two robots listed at my Neato account.

404 Client Error with my robot

I try to use pybotvac. when I get from https://beehive.neatocloud.com/users/me/robots/ the response will see my robot like this:

[{
        "serial": "GPC11418-7C3****E3F3",
        "prefix": "SN",
        "name": "my_robot",
        "model": "BotVacD5Connected",
        "timezone": null,
        "secret_key": "E42B******379C0",
        "purchased_at": "2018-06-16T00:00:00Z",
        "linked_at": "2018-07-11T13:32:08Z",
        "nucleo_url": "https://ap-nucleo.neatocloud.com:4443",
        "traits": [
            "maps"
        ],
        "proof_of_purchase_url": null,
        "proof_of_purchase_url_valid_for_seconds": 900,
        "proof_of_purchase_generated_at": null,
        "mac_address": "*********",
        "created_at": "2018-06-23T23:20:56Z"
    }]

but when I post for https://nucleo.neatocloud.com/vendors/neato/robots/GPC11418-7C3****E3F3/messages, I will get the error with "requests.exceptions.HTTPError: 404 Client Error: Not Found for url https://nucleo.neatocloud.com/vendors/neato/robots/GPC11418-7C3****E3F3/messages"

Neato D8, D9 and D10 Support

Hi there,

I use this API for some years now for my D5 Connected.

But now I have an D8. When searching for the new serial and secret I only see my old D5 robot.

Is this API compatible with the new D8, D9 and D10?

Greetings Brutus.

the `requests` dependency is missing in setup.py

Hi,

When doing pip install pybotvac it fails to install the requests dependency.
The problem is that the setup.py doesn't contain the install_requires directive,
and even if the dependency is mentioned in requrements.txt this file is not analyzed by pip.

Please add following line to setup.py:

install_requires=['requests']

CERTIFICATE_VERIFY_FAILED for nucleo.neatocloud.com

Hello!

I am trying the library and I am running into this issue

HTTPSConnectionPool(host='nucleo.neatocloud.com', port=443): Max retries exceeded with url: /vendors/neato/robots/xxxxxxxxx/messages (Caused by SSLError(SSLCertVerificationError(1, "[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'nucleo.neatocloud.com'. (_ssl.c:1000)")))

here:

raise NeatoRobotException("Unable to communicate with robot") from ex

This goes away if you change the verify parameter to False... not sure this is OK though. Thanks.

Not sure if this is related but in my local I commented:

urllib3.disable_warnings(urllib3.exceptions.SubjectAltNameWarning)

because I am using 2.2.1 and I was getting a
AttributeError: module 'urllib3.exceptions' has no attribute 'SubjectAltNameWarning'

Can't access to my neato Connected

Hi,

I just start to play with your API, but I can't use any robot method. There is no problem to retreive my robot throught my credentials, but when I want to run a robot method (ie: robot.get_current_state) I get the following error message

Traceback (most recent call last):
File "sample/sample.py", line 13, in
print("State:\n", robot.state)
File "/usr/local/lib/python3.4/dist-packages/pybotvac-0.0.1-py3.4.egg/pybotvac/robot.py", line 94, in state
return self.get_robot_state().json()
File "/usr/local/lib/python3.4/dist-packages/pybotvac-0.0.1-py3.4.egg/pybotvac/robot.py", line 70, in get_robot_state
return self._message({'reqId': "1", 'cmd': "getRobotState"})
File "/usr/local/lib/python3.4/dist-packages/pybotvac-0.0.1-py3.4.egg/pybotvac/robot.py", line 43, in _message
headers=self._headers)
File "/usr/local/lib/python3.4/dist-packages/requests/api.py", line 110, in post
return request('post', url, data=data, json=json, *_kwargs)
File "/usr/local/lib/python3.4/dist-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, *_kwargs)
File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 461, in request
prep = self.prepare_request(req)
File "/usr/local/lib/python3.4/dist-packages/requests/sessions.py", line 394, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/usr/local/lib/python3.4/dist-packages/requests/models.py", line 298, in prepare
self.prepare_auth(auth, url)
File "/usr/local/lib/python3.4/dist-packages/requests/models.py", line 500, in prepare_auth
r = auth(self)
File "/usr/local/lib/python3.4/dist-packages/pybotvac-0.0.1-py3.4.egg/pybotvac/robot.py", line 108, in call
msg='\n'.join([self.serial.lower(), date, request.body]).encode('utf8'),
TypeError: sequence item 2: expected str instance, bytes found

Use oauth?

Hello @stianaske!
Let me introduce myself, I am Roberto Ostinelli, Neato Robotics' Director of Cloud Services.

I'm impressed with the work that you've put into integrating with our robots! Great job!

Given the interest that we've seen from developers like yourself and around the forums we've listened and have just released the Neato Developer Network. In there, amongst other things you will find official documentation and SDKs for JavaScript, iOS and Android (for now, we plan on expanding to other languages too!).

This issue is for you to consider switching to proper OAuth instead of the internal logins mechanisms that you are using in this gem.

It would be the official way to proceed, and you would avoid some improper implementations. For example, you should not pass token and platform here: they are not needed, raise errors on our systems - since tokens are invalid - and this could eventually result in the blocking of user accounts by our automated systems if abused. We definitely wouldn't want that!

Please note that all of this is in Beta, we're a small team but are doing our best!

All the best,
r.

PS: I've opened the same issue on the gem that, to my knowledge, started it all. :)

Error 403 (Permission denied) while trying to retrieve my serial and secret

Hello,

when I try to retrieve the serialnumber and secret of my robot, I only get the following error message. I tried to do it manually and used the sample.py-script, both without success.

Traceback (most recent call last):
File "sample.py", line 6, in
account = Account(email, password)
File "/usr/lib/python3.5/site-packages/pybotvac-0.0.1-py3.5.egg/pybotvac/account.py", line 21, in init
self._login(email, password)
File "/usr/lib/python3.5/site-packages/pybotvac-0.0.1-py3.5.egg/pybotvac/account.py", line 37, in _login
response.raise_for_status()
File "/usr/lib/python3.5/site-packages/requests/models.py", line 844, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://beehive.neatocloud.com/sessions

It looks like Neato tries to prevent this way of acessing their data. Is it still possible to use this script?

Thanks
Scorpion008

Botvac D3: start_cleaning method does not work without floorplan

Hi,

In relation to home-assistant/core#24119, the Botvac D3 Connected appears to respond with an unexpected error code when there is no floorplan. The vacuum will start when either the floorplan is in place of if it is instructed to run without a floorplan using category 2.

Please see the original issue for further detail. I have pybotvac locally set up on my laptop, so I'm happy to do any debugging you may need to resolve this.

Thanks in advance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.