-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor PlugInstance to cache mac/device_id generation (#63)
* Refactor PlugInstance to cache mac/device_id generation * fix
- Loading branch information
Showing
1 changed file
with
107 additions
and
87 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,107 @@ | ||
# Copyright 2020, Charles Powell | ||
|
||
import hashlib | ||
from time import time | ||
|
||
|
||
class PlugInstance: | ||
def __init__(self, id, start_time=None, alias=None, power=0, current=0, voltage=120, mac=None, device_id=None): | ||
self.id = id | ||
|
||
self.voltage = voltage | ||
self.power = power | ||
self.current = current | ||
|
||
if alias: | ||
self.alias = alias | ||
else: | ||
self.alias = id | ||
|
||
if start_time: | ||
self.start_time = start_time | ||
else: | ||
self.start_time = time() - 1 | ||
|
||
if not self.power: | ||
self.power = self.voltage * self.current | ||
if not self.current: | ||
self.current = self.power / self.voltage | ||
|
||
if device_id: | ||
self.device_id = device_id | ||
else: | ||
self.device_id = self.generate_deviceid() | ||
|
||
if mac: | ||
self.mac = mac | ||
else: | ||
self.mac = self.generate_mac() | ||
|
||
def generate_mac(self): | ||
end = [int(self.device_id[i : i + 2], 16) for i in range(0, len(self.device_id), 2)] | ||
mac = [53, 75, 31] + end[:3] | ||
return ":".join("%02x" % b for b in mac) | ||
|
||
def generate_deviceid(self): | ||
return hashlib.sha1(self.id.encode("utf-8")).hexdigest() | ||
|
||
def generate_response(self): | ||
# Response dict | ||
response = { | ||
"emeter": { | ||
"get_realtime": { | ||
"current": self.current, | ||
"voltage": self.voltage, | ||
"power": self.power, | ||
"total": 0, # Unsure if this needs a value, appears not to | ||
"err_code": 0, # No errors here! | ||
} | ||
}, | ||
"system": { | ||
"get_sysinfo": { | ||
"err_code": 0, | ||
"sw_ver": "1.2.5 Build 171206 Rel.085954", | ||
"hw_ver": "1.0", | ||
"type": "IOT.SMARTPLUGSWITCH", | ||
"model": "HS110(US)", | ||
"mac": self.mac.upper(), | ||
"deviceId": self.device_id.upper(), | ||
"hwId": "60FF6B258734EA6880E186F8C96DDC61", | ||
"fwId": "00000000000000000000000000000000", | ||
"oemId": "FFF22CFF774A0B89F7624BFC6F50D5DE", | ||
"alias": self.alias, | ||
"dev_name": "Wi-Fi Smart Plug With Energy Monitoring", | ||
"icon_hash": "", | ||
"relay_state": 1 if self.power > 0 else 0, | ||
"on_time": time() - self.start_time, | ||
"active_mode": "none", | ||
"feature": "TIM:ENE", | ||
"updating": 0, | ||
"rssi": -60, # Great wifi signal | ||
"led_off": 0, # Probably not important | ||
"latitude": 39.8283, # Center of the US | ||
"longitude": -98.5795, # Center of the US | ||
} | ||
}, | ||
} | ||
return response | ||
# Copyright 2020, Charles Powell | ||
|
||
import hashlib | ||
from time import time | ||
from typing import Optional, Dict, Any | ||
from functools import lru_cache | ||
|
||
|
||
@lru_cache(maxsize=256) | ||
def _generate_mac(device_id: str) -> str: | ||
"""Generate a MAC address from the device ID only once.""" | ||
end = [int(device_id[i : i + 2], 16) for i in range(0, len(device_id), 2)] | ||
mac = [53, 75, 31] + end[:3] | ||
return ":".join("%02X" % b for b in mac) | ||
|
||
|
||
@lru_cache(maxsize=256) | ||
def _generate_device_id(id: str) -> str: | ||
"""Generate a device ID from the ID only once.""" | ||
return hashlib.sha1(id.encode("utf-8")).hexdigest().upper() | ||
|
||
|
||
class PlugInstance: | ||
"""Class to represent a single plug instance.""" | ||
|
||
__slots__ = ( | ||
"id", | ||
"voltage", | ||
"power", | ||
"current", | ||
"alias", | ||
"start_time", | ||
"device_id", | ||
"mac", | ||
) | ||
|
||
def __init__( | ||
self, | ||
id: str, | ||
start_time: Optional[float] = None, | ||
alias: Optional[str] = None, | ||
power=0.0, | ||
current=0.0, | ||
voltage=120.0, | ||
mac: Optional[str] = None, | ||
device_id: Optional[str] = None, | ||
) -> None: | ||
"""Initialize a plug instance.""" | ||
self.id = id | ||
self.voltage = voltage | ||
self.power = power | ||
self.current = current | ||
if not self.power: | ||
self.power = self.voltage * self.current | ||
if not self.current: | ||
self.current = self.power / self.voltage | ||
self.alias = alias or id | ||
self.start_time = start_time or time() - 1 | ||
if device_id: | ||
self.device_id = device_id.upper() | ||
else: | ||
self.device_id = _generate_device_id(id) | ||
if mac: | ||
self.mac = mac.upper() | ||
else: | ||
self.mac = _generate_mac(self.device_id) | ||
|
||
def generate_response(self) -> Dict[str, Dict[str, Any]]: | ||
"""Generate a response dict for the plug.""" | ||
# Response dict | ||
return { | ||
"emeter": { | ||
"get_realtime": { | ||
"current": self.current, | ||
"voltage": self.voltage, | ||
"power": self.power, | ||
"total": 0, # Unsure if this needs a value, appears not to | ||
"err_code": 0, # No errors here! | ||
} | ||
}, | ||
"system": { | ||
"get_sysinfo": { | ||
"err_code": 0, | ||
"sw_ver": "1.2.5 Build 171206 Rel.085954", | ||
"hw_ver": "1.0", | ||
"type": "IOT.SMARTPLUGSWITCH", | ||
"model": "HS110(US)", | ||
"mac": self.mac, | ||
"deviceId": self.device_id, | ||
"hwId": "60FF6B258734EA6880E186F8C96DDC61", | ||
"fwId": "00000000000000000000000000000000", | ||
"oemId": "FFF22CFF774A0B89F7624BFC6F50D5DE", | ||
"alias": self.alias, | ||
"dev_name": "Wi-Fi Smart Plug With Energy Monitoring", | ||
"icon_hash": "", | ||
"relay_state": 1 if self.power > 0 else 0, | ||
"on_time": time() - self.start_time, | ||
"active_mode": "none", | ||
"feature": "TIM:ENE", | ||
"updating": 0, | ||
"rssi": -60, # Great wifi signal | ||
"led_off": 0, # Probably not important | ||
"latitude": 39.8283, # Center of the US | ||
"longitude": -98.5795, # Center of the US | ||
} | ||
}, | ||
} |