Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DeviceInfo refactor, do not crash on missing fields #1083

Merged
merged 1 commit into from
Jun 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 1 addition & 82 deletions miio/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import click

from .click_common import DeviceGroupMeta, LiteralParamType, command, format_output
from .deviceinfo import DeviceInfo
from .exceptions import DeviceInfoUnavailableException, PayloadDecodeException
from .miioprotocol import MiIOProtocol

Expand All @@ -20,88 +21,6 @@ class UpdateState(Enum):
Idle = "idle"


class DeviceInfo:
"""Container of miIO device information.

Hardware properties such as device model, MAC address, memory information, and
hardware and software information is contained here.
"""

def __init__(self, data):
"""Response of a Xiaomi Smart WiFi Plug.

{'ap': {'bssid': 'FF:FF:FF:FF:FF:FF', 'rssi': -68, 'ssid': 'network'},
'cfg_time': 0,
'fw_ver': '1.2.4_16',
'hw_ver': 'MW300',
'life': 24,
'mac': '28:FF:FF:FF:FF:FF',
'mmfree': 30312,
'model': 'chuangmi.plug.m1',
'netif': {'gw': '192.168.xxx.x',
'localIp': '192.168.xxx.x',
'mask': '255.255.255.0'},
'ot': 'otu',
'ott_stat': [0, 0, 0, 0],
'otu_stat': [320, 267, 3, 0, 3, 742],
'token': '2b00042f7481c7b056c4b410d28f33cf',
'wifi_fw_ver': 'SD878x-14.76.36.p84-702.1.0-WM'}
"""
self.data = data

def __repr__(self):
return "%s v%s (%s) @ %s - token: %s" % (
self.data["model"],
self.data["fw_ver"],
self.data["mac"],
self.network_interface["localIp"],
self.data["token"],
)

@property
def network_interface(self):
"""Information about network configuration."""
return self.data["netif"]

@property
def accesspoint(self):
"""Information about connected wlan accesspoint."""
return self.data["ap"]

@property
def model(self) -> Optional[str]:
"""Model string if available."""
if self.data["model"] is not None:
return self.data["model"]
return None

@property
def firmware_version(self) -> Optional[str]:
"""Firmware version if available."""
if self.data["fw_ver"] is not None:
return self.data["fw_ver"]
return None

@property
def hardware_version(self) -> Optional[str]:
"""Hardware version if available."""
if self.data["hw_ver"] is not None:
return self.data["hw_ver"]
return None

@property
def mac_address(self) -> Optional[str]:
"""MAC address if available."""
if self.data["mac"] is not None:
return self.data["mac"]
return None

@property
def raw(self):
"""Raw data as returned by the device."""
return self.data


class DeviceStatus:
"""Base class for status containers.

Expand Down
91 changes: 91 additions & 0 deletions miio/deviceinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
from typing import Dict, Optional


class DeviceInfo:
"""Container of miIO device information.

Hardware properties such as device model, MAC address, memory information, and
hardware and software information is contained here.
"""

def __init__(self, data):
"""Response of a Xiaomi Smart WiFi Plug.

{'ap': {'bssid': 'FF:FF:FF:FF:FF:FF', 'rssi': -68, 'ssid': 'network'},
'cfg_time': 0,
'fw_ver': '1.2.4_16',
'hw_ver': 'MW300',
'life': 24,
'mac': '28:FF:FF:FF:FF:FF',
'mmfree': 30312,
'model': 'chuangmi.plug.m1',
'netif': {'gw': '192.168.xxx.x',
'localIp': '192.168.xxx.x',
'mask': '255.255.255.0'},
'ot': 'otu',
'ott_stat': [0, 0, 0, 0],
'otu_stat': [320, 267, 3, 0, 3, 742],
'token': '2b00042f7481c7b056c4b410d28f33cf',
'wifi_fw_ver': 'SD878x-14.76.36.p84-702.1.0-WM'}
"""
self.data = data

def __repr__(self):
return "%s v%s (%s) @ %s - token: %s" % (
self.model,
self.firmware_version,
self.mac_address,
self.ip_address,
self.token,
)

@property
def network_interface(self) -> Dict:
"""Information about network configuration.

If unavailable, returns an empty dictionary.
"""
return self.data.get("netif", {})

@property
def accesspoint(self):
"""Information about connected wlan accesspoint.

If unavailable, returns an empty dictionary.
"""
return self.data.get("ap", {})

@property
def model(self) -> Optional[str]:
"""Model string if available."""
return self.data.get("model")

@property
def firmware_version(self) -> Optional[str]:
"""Firmware version if available."""
return self.data.get("fw_ver")

@property
def hardware_version(self) -> Optional[str]:
"""Hardware version if available."""
return self.data.get("hw_ver")

@property
def mac_address(self) -> Optional[str]:
"""MAC address, if available."""
return self.data.get("mac")

@property
def ip_address(self) -> Optional[str]:
"""IP address, if available."""
return self.network_interface.get("localIp")

@property
def token(self) -> Optional[str]:
"""Return the current device token."""
return self.data.get("token")

@property
def raw(self):
"""Raw data as returned by the device."""
return self.data