Skip to content

Commit

Permalink
Merge branch 'master' into feature/mdns-device-map
Browse files Browse the repository at this point in the history
  • Loading branch information
rytilahti authored Sep 3, 2017
2 parents 802b227 + b0aa3d6 commit 5e03300
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 18 deletions.
8 changes: 8 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sudo: false
language: python
python:
- "3.4"
- "3.5"
- "3.6"
install: pip install tox-travis
script: tox
2 changes: 2 additions & 0 deletions mirobo/airpurifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def humidity(self) -> int:
def temperature(self) -> float:
if self.data["temp_dec"] is not None:
return self.data["temp_dec"] / 10.0
return None

@property
def mode(self) -> OperationMode:
Expand All @@ -150,6 +151,7 @@ def led(self) -> bool:
def led_brightness(self) -> LedBrightness:
if self.data["led_b"] is not None:
return LedBrightness(self.data["led_b"])
return None

@property
def buzzer(self) -> bool:
Expand Down
8 changes: 4 additions & 4 deletions mirobo/ceil.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ def automatic_color_temperature(self) -> int:
def __str__(self) -> str:
s = "<CeilStatus power=%s, brightness=%s, " \
"color_temperature=%s, scene=%s, dv=%s, " \
"smart_night_light=%s, automatic_color_temperature=%, >" % \
(self.power, self.brightness,
self.color_temperature, self.scene, self.dv,
self.smart_night_light, self.automatic_color_temperature)
"smart_night_light=%s, automatic_color_temperature=%s>" % (
self.power, self.brightness,
self.color_temperature, self.scene, self.dv,
self.smart_night_light, self.automatic_color_temperature)
return s


Expand Down
4 changes: 3 additions & 1 deletion mirobo/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def __repr__(self):
self.data["mac"],
self.netif["localIp"],
self.data["token"])

@property
def netif(self):
return self.data["netif"]
Expand Down Expand Up @@ -170,7 +171,8 @@ def send(self, command: str, parameters: Any=None, retry_count=3) -> Any:
except OSError as ex:
_LOGGER.error("Got error when receiving: %s", ex)
if retry_count > 0:
_LOGGER.warning("Retrying with incremented id, retries left: %s" % retry_count)
_LOGGER.warning("Retrying with incremented id, "
"retries left: %s" % retry_count)
self.__id += 100
return self.send(command, parameters, retry_count-1)
raise DeviceException from ex
Expand Down
8 changes: 6 additions & 2 deletions mirobo/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
import inspect
import codecs
from mirobo import (Device, Vacuum, Plug, PlugV1, Strip, AirPurifier, Ceil,
PhilipsEyecare, )
PhilipsEyecare)
from typing import Union, Callable, Dict

_LOGGER = logging.getLogger(__name__)


def other_package_info(info, desc):
return "%s @ %s, check %s" % (info.name, ipaddress.ip_address(info.address), desc)
return "%s @ %s, check %s" % (
info.name,
ipaddress.ip_address(info.address),
desc)


class Listener:
Expand Down
3 changes: 1 addition & 2 deletions mirobo/philips_eyecare.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,5 @@ def __str__(self) -> str:
"dvalue=%s >" % \
(self.power, self.bright,
self.notifystatus, self.ambstatus, self.ambvalue,
self.eyecare, self.scene_num,
self.bls)
self.eyecare, self.scene_num, self.bls, self.dvalue)
return s
1 change: 1 addition & 0 deletions mirobo/plug.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def load_power(self) -> float:
# The constant of 110V is used intentionally. The current was
# calculated with a wrong reference voltage already.
return self.data["current"] * 110
return None

def __str__(self) -> str:
s = "<PlugStatus power=%s, temperature=%s, load_power=%s>" % \
Expand Down
1 change: 1 addition & 0 deletions mirobo/plug_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ast
import sys
import ipaddress
from typing import Any

if sys.version_info < (3, 4):
print("To use this script you need python 3.4 or newer, got %s" %
Expand Down
13 changes: 13 additions & 0 deletions mirobo/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
class Utils:
""" This class is adapted from the original xpn.py code by gst666 """

@staticmethod
def verify_token(token: bytes):
if not isinstance(token, bytes):
raise TypeError("Token must be bytes")
if len(token) != 32:
raise ValueError("Token must be of length 32")

@staticmethod
def md5(data: bytes) -> bytes:
checksum = hashlib.md5()
Expand All @@ -48,6 +55,9 @@ def key_iv(token: bytes) -> Tuple[bytes, bytes]:

@staticmethod
def encrypt(plaintext: bytes, token: bytes) -> bytes:
if not isinstance(plaintext, bytes):
raise TypeError("plaintext requires bytes")
Utils.verify_token(token)
key, iv = Utils.key_iv(token)
padder = padding.PKCS7(128).padder()

Expand All @@ -60,6 +70,9 @@ def encrypt(plaintext: bytes, token: bytes) -> bytes:

@staticmethod
def decrypt(ciphertext: bytes, token: bytes) -> bytes:
if not isinstance(ciphertext, bytes):
raise TypeError("ciphertext requires bytes")
Utils.verify_token(token)
key, iv = Utils.key_iv(token)
cipher = Cipher(algorithms.AES(key), modes.CBC(iv),
backend=default_backend())
Expand Down
Empty file added mirobo/tests/__init__.py
Empty file.
34 changes: 34 additions & 0 deletions mirobo/tests/test_protocol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from unittest import TestCase
from .. import Message, Utils


class TestProtocol(TestCase):
def test_non_bytes_payload(self):
payload = "hello world"
valid_token = 32 * b'0'
with self.assertRaises(TypeError):
Utils.encrypt(payload, valid_token)
with self.assertRaises(TypeError):
Utils.decrypt(payload, valid_token)

def test_encrypt(self):
payload = b"hello world"
token = 32 * b'0'

encrypted = Utils.encrypt(payload, token)
decrypted = Utils.decrypt(encrypted, token)
self.assertEquals(payload, decrypted)

def test_invalid_token(self):
payload = b"hello world"
wrong_type = 1234
wrong_length = 31 * b'0'
with self.assertRaises(TypeError):
Utils.encrypt(payload, wrong_type)
with self.assertRaises(TypeError):
Utils.decrypt(payload, wrong_type)

with self.assertRaises(ValueError):
Utils.encrypt(payload, wrong_length)
with self.assertRaises(ValueError):
Utils.decrypt(payload, wrong_length)
2 changes: 1 addition & 1 deletion mirobo/vacuum_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def backward(vac: mirobo.Vacuum, amount:float):
@click.argument('rotation', type=float)
@click.argument('velocity', type=float)
@click.argument('duration', type=int)
def move(vac: mirobo.Vacuum, rotation: float, velocity: float, duration: int):
def move(vac: mirobo.Vacuum, rotation: int, velocity: float, duration: int):
"""Pass raw manual values"""
return vac.manual_control(rotation, velocity, duration)

Expand Down
1 change: 1 addition & 0 deletions mirobo/yeelight.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ def rgb(self):
def color_temp(self) -> int:
if self.color_mode == YeelightMode.ColorTemperature:
return int(self.data["ct"])
return None

@property
def name(self) -> str:
Expand Down
23 changes: 15 additions & 8 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
[tox]
envlist=flake8,typing
envlist=py34,py35,py36,flake8,typing

#[tox:travis]
#3.4 = py34
#3.5 = py35
#3.6 = py36
[tox:travis]
3.4 = py34
3.5 = py35
3.6 = py36

#[testenv]
#deps=
#commands=py.test mirobo
[testenv]
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
deps=
pytest
pytest-cov
voluptuous
coveralls
commands=
py.test --cov mirobo
coveralls

[testenv:flake8]
deps=flake8
Expand Down

0 comments on commit 5e03300

Please sign in to comment.