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

Get areas and paths #52

Merged
merged 15 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from 13 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[![PyPI Releases][img_pypi]][url_pypi]
[![Supported Python Versions][img_pyversions]][url_pyversions]

[img_version]: https://img.shields.io/static/v1.svg?label=SemVer&message=0.0.1&color=blue
[img_version]: https://img.shields.io/static/v1.svg?label=SemVer&message=0.4.0&color=blue
[url_version]: https://pypi.org/project/pymammotion/

[img_pypi]: https://img.shields.io/badge/PyPI-wheels-green.svg
Expand Down
425 changes: 230 additions & 195 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions pymammotion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@

# TODO make a working device that will work outside HA too.
from pymammotion.mammotion.devices import MammotionBaseBLEDevice
from pymammotion.mqtt.mqtt import LubaMQTT, logger
from pymammotion.mqtt import MammotionMQTT

logger = logging.getLogger(__name__)

# TODO provide interface to pick between mqtt/cloud/bluetooth

Expand All @@ -28,7 +30,7 @@
CLIENT_ID = os.environ.get("CLIENT_ID")
IOT_TOKEN = os.environ.get("IOT_TOKEN")
REGION = os.environ.get("REGION")
luba = LubaMQTT(
luba = MammotionMQTT(
iot_token=IOT_TOKEN,
region_id=REGION,
product_key=PRODUCT_KEY,
Expand Down
46 changes: 14 additions & 32 deletions pymammotion/aliyun/cloud_gateway.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ def get_region(self, country_code: str, auth_code: str):
)

# send request
response = client.do_request(
"/living/account/region/get", "https", "POST", None, body, RuntimeOptions()
)
response = client.do_request("/living/account/region/get", "https", "POST", None, body, RuntimeOptions())
logger.debug(response.status_message)
logger.debug(response.headers)
logger.debug(response.status_code)
Expand Down Expand Up @@ -182,9 +180,7 @@ def aep_handle(self):
)

# send request
response = client.do_request(
"/app/aepauth/handle", "https", "POST", None, body, RuntimeOptions()
)
response = client.do_request("/app/aepauth/handle", "https", "POST", None, body, RuntimeOptions())
logger.debug(response.status_message)
logger.debug(response.headers)
logger.debug(response.status_code)
Expand All @@ -195,9 +191,7 @@ def aep_handle(self):
response_body_dict = json.loads(response_body_str)

if int(response_body_dict.get("code")) != 200:
raise Exception(
"Error in getting mqtt credentials: " + response_body_dict["msg"]
)
raise Exception("Error in getting mqtt credentials: " + response_body_dict["msg"])

self._aep_response = AepResponse.from_dict(response_body_dict)

Expand Down Expand Up @@ -250,14 +244,12 @@ async def connect(self):
header = "".join(f"{k}:{dic[k]}\n" for k in keys).strip()

headers["x-ca-signature-headers"] = sign_headers
string_to_sign = (
"POST\n{}\n\n{}\n{}\n{}\n/api/prd/connect.json?request={}".format(
headers["accept"],
headers["content-type"],
headers["date"],
header,
json.dumps(_bodyParam, separators=(",", ":")),
)
string_to_sign = "POST\n{}\n\n{}\n{}\n{}\n/api/prd/connect.json?request={}".format(
headers["accept"],
headers["content-type"],
headers["date"],
header,
json.dumps(_bodyParam, separators=(",", ":")),
)

hash_val = hmac.new(
Expand Down Expand Up @@ -339,9 +331,7 @@ async def login_by_oauth(self, country_code: str, auth_code: str):
async with session.post(
f"https://{region_url}/api/prd/loginbyoauth.json",
headers=headers,
params={
"loginByOauthRequest": json.dumps(_bodyParam, separators=(",", ":"))
},
params={"loginByOauthRequest": json.dumps(_bodyParam, separators=(",", ":"))},
) as resp:
data = await resp.json()
logger.debug(data)
Expand Down Expand Up @@ -395,9 +385,7 @@ def session_by_auth_code(self):
if int(response_body_dict.get("code")) != 200:
raise Exception("Error in creating session: " + response_body_dict["msg"])

self._session_by_authcode_response = SessionByAuthCodeResponse.from_dict(
response_body_dict
)
self._session_by_authcode_response = SessionByAuthCodeResponse.from_dict(response_body_dict)

return response.body

Expand Down Expand Up @@ -472,9 +460,7 @@ def list_binding_by_account(self):
)

# send request
response = client.do_request(
"/uc/listBindingByAccount", "https", "POST", None, body, RuntimeOptions()
)
response = client.do_request("/uc/listBindingByAccount", "https", "POST", None, body, RuntimeOptions())
logger.debug(response.status_message)
logger.debug(response.headers)
logger.debug(response.status_code)
Expand All @@ -489,9 +475,7 @@ def list_binding_by_account(self):
if int(response_body_dict.get("code")) != 200:
raise Exception("Error in creating session: " + response_body_dict["msg"])

self._listing_dev_by_account_response = ListingDevByAccountResponse.from_dict(
response_body_dict
)
self._listing_dev_by_account_response = ListingDevByAccountResponse.from_dict(response_body_dict)

def send_cloud_command(self, iot_id: str, command: bytes) -> str:
"""Send a cloud command to the specified IoT device."""
Expand Down Expand Up @@ -526,9 +510,7 @@ def send_cloud_command(self, iot_id: str, command: bytes) -> str:
)

# send request
response = client.do_request(
"/thing/service/invoke", "https", "POST", None, body, RuntimeOptions()
)
response = client.do_request("/thing/service/invoke", "https", "POST", None, body, RuntimeOptions())
logger.debug(response.status_message)
logger.debug(response.headers)
logger.debug(response.status_code)
Expand Down
8 changes: 2 additions & 6 deletions pymammotion/aliyun/tmp_constant.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,7 @@ class tmp_constant:
URI_ALINK_SERVICE = "alink/service" # deprecated
URI_AUTH = "/auth" # deprecated
URI_AUTHEN_REGISTER = "/sys/{productKey}/{deviceName}/thing/authen/sub/register"
URI_AUTHEN_REGISTER_REPLY = (
"/sys/{productKey}/{deviceName}/thing/authen/sub/register_reply"
)
URI_AUTHEN_REGISTER_REPLY = "/sys/{productKey}/{deviceName}/thing/authen/sub/register_reply"
URI_BLACKLIST_UPDATE_POST = "/thing/lan/blacklist/update"
URI_BLACKLIST_UPDATE_REPLY_POST = "/thing/lan/blacklist/update_reply"
URI_DEVICE = "/device/core/dev"
Expand All @@ -165,9 +163,7 @@ class tmp_constant:
URI_TOPIC_LOCALDEVICE_STATECHANGE = "group/localstatechange"
URI_TOPIC_REPLY_POST = "_reply"
URI_UPDATE_DEVICE_INFO = "/sys/{productKey}/{deviceName}/thing/deviceinfo/update"
URI_UPDATE_DEVICE_INFO_REPLY = (
"/sys/{productKey}/{deviceName}/thing/deviceinfo/update_reply"
)
URI_UPDATE_DEVICE_INFO_REPLY = "/sys/{productKey}/{deviceName}/thing/deviceinfo/update_reply"
URI_USER = "/user"
VALUE_SHA256 = "sha256"
VERSION = "1.0"
Expand Down
16 changes: 4 additions & 12 deletions pymammotion/bluetooth/ble.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,11 @@ async def disconnect(self) -> bool:
if self.client is not None:
return await self.client.disconnect()

async def notification_handler(
self, _characteristic: BleakGATTCharacteristic, data: bytearray
):
async def notification_handler(self, _characteristic: BleakGATTCharacteristic, data: bytearray):
"""Simple notification handler which prints the data received."""
await self._bleEvt.BleNotification(data)

def service_changed_handler(
self, characteristic: BleakGATTCharacteristic, data: bytearray
):
def service_changed_handler(self, characteristic: BleakGATTCharacteristic, data: bytearray):
"""Simple notification handler which prints the data received."""
print(f"Response 2 {characteristic.description}: {data}")
print(data.decode("utf-8"))
Expand All @@ -63,12 +59,8 @@ def service_changed_handler(

async def notifications(self):
if self.client.is_connected:
await self.client.start_notify(
UUID_NOTIFICATION_CHARACTERISTIC, self.notification_handler
)
await self.client.start_notify(
SERVICE_CHANGED_CHARACTERISTIC, self.service_changed_handler
)
await self.client.start_notify(UUID_NOTIFICATION_CHARACTERISTIC, self.notification_handler)
await self.client.start_notify(SERVICE_CHANGED_CHARACTERISTIC, self.service_changed_handler)

def getClient(self):
return self.client
48 changes: 12 additions & 36 deletions pymammotion/bluetooth/ble_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,11 @@ async def get_device_version_main(self):

async def get_task(self):
hash_map = {"pver": 1, "subCmd": 2, "result": 0}
await self.messageNavigation.post_custom_data(
self.get_json_string(bleOrderCmd.task, hash_map)
)
await self.messageNavigation.post_custom_data(self.get_json_string(bleOrderCmd.task, hash_map))

async def send_ble_alive(self):
hash_map = {"ctrl": 1}
await self.messageNavigation.post_custom_data(
self.get_json_string(bleOrderCmd.bleAlive, hash_map)
)
await self.messageNavigation.post_custom_data(self.get_json_string(bleOrderCmd.bleAlive, hash_map))

def clearNotification(self):
self.notification = None
Expand All @@ -106,9 +102,7 @@ async def send_device_info(self):
seqs=1,
version=1,
subtype=1,
net=dev_net_pb2.DevNet(
todev_ble_sync=1, todev_devinfo_req=dev_net_pb2.DrvDevInfoReq()
),
net=dev_net_pb2.DevNet(todev_ble_sync=1, todev_devinfo_req=dev_net_pb2.DrvDevInfoReq()),
)
byte_arr = luba_msg.SerializeToString()
await self.post_custom_data_bytes(byte_arr)
Expand All @@ -117,9 +111,7 @@ async def requestDeviceStatus(self):
request = False
type = self.messageNavigation.getTypeValue(0, 5)
try:
request = await self.messageNavigation.post(
BleMessage.mEncrypted, BleMessage.mChecksum, False, type, None
)
request = await self.messageNavigation.post(BleMessage.mEncrypted, BleMessage.mChecksum, False, type, None)
# print(request)
except Exception as err:
# Log.w(TAG, "post requestDeviceStatus interrupted")
Expand All @@ -133,9 +125,7 @@ async def requestDeviceVersion(self):
request = False
type = self.messageNavigation.getTypeValue(0, 7)
try:
request = await self.messageNavigation.post(
BleMessage.mEncrypted, BleMessage.mChecksum, False, type, None
)
request = await self.messageNavigation.post(BleMessage.mEncrypted, BleMessage.mChecksum, False, type, None)
# print(request)
except Exception as err:
# Log.w(TAG, "post requestDeviceStatus interrupted")
Expand Down Expand Up @@ -318,9 +308,7 @@ async def post_custom_data_bytes(self, data: bytes):
return
type_val = self.getTypeValue(1, 19)
try:
suc = await self.post(
self.mEncrypted, self.mChecksum, self.mRequireAck, type_val, data
)
suc = await self.post(self.mEncrypted, self.mChecksum, self.mRequireAck, type_val, data)
# int status = suc ? 0 : BlufiCallback.CODE_WRITE_DATA_FAILED
# onPostCustomDataResult(status, data)
# print(suc)
Expand All @@ -333,9 +321,7 @@ async def post_custom_data(self, data_str: str):
return
type_val = self.getTypeValue(1, 19)
try:
suc = await self.post(
self.mEncrypted, self.mChecksum, self.mRequireAck, type_val, data
)
suc = await self.post(self.mEncrypted, self.mChecksum, self.mRequireAck, type_val, data)
# int status = suc ? 0 : BlufiCallback.CODE_WRITE_DATA_FAILED
# onPostCustomDataResult(status, data)
except Exception as err:
Expand All @@ -352,17 +338,11 @@ async def post(
if data is None:
return await self.post_non_data(encrypt, checksum, require_ack, type_of)

return await self.post_contains_data(
encrypt, checksum, require_ack, type_of, data
)
return await self.post_contains_data(encrypt, checksum, require_ack, type_of, data)

async def post_non_data(
self, encrypt: bool, checksum: bool, require_ack: bool, type_of: int
) -> bool:
async def post_non_data(self, encrypt: bool, checksum: bool, require_ack: bool, type_of: int) -> bool:
sequence = self.generateSendSequence()
postBytes = self.getPostBytes(
type_of, encrypt, checksum, require_ack, False, sequence, None
)
postBytes = self.getPostBytes(type_of, encrypt, checksum, require_ack, False, sequence, None)
posted = await self.gatt_write(postBytes)
return posted and (not require_ack or self.receiveAck(sequence))

Expand All @@ -385,9 +365,7 @@ async def post_contains_data(
for index, chunk in enumerate(chunks):
frag = index != len(chunks) - 1
sequence = self.generateSendSequence()
postBytes = self.getPostBytes(
type_of, encrypt, checksum, require_ack, frag, sequence, chunk
)
postBytes = self.getPostBytes(type_of, encrypt, checksum, require_ack, frag, sequence, chunk)
# print("sequence")
# print(sequence)
posted = await self.gatt_write(postBytes)
Expand Down Expand Up @@ -415,9 +393,7 @@ def getPostBytes(
) -> bytes:
byteOS = BytesIO()
dataLength = 0 if data == None else len(data)
frameCtrl = FrameCtrlData.getFrameCTRLValue(
encrypt, checksum, 0, require_ack, hasFrag
)
frameCtrl = FrameCtrlData.getFrameCTRLValue(encrypt, checksum, 0, require_ack, hasFrag)
byteOS.write(type.to_bytes(1, sys.byteorder))
byteOS.write(frameCtrl.to_bytes(1, sys.byteorder))
byteOS.write(sequence.to_bytes(1, sys.byteorder))
Expand Down
4 changes: 1 addition & 3 deletions pymammotion/bluetooth/data/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ def store_sys_data(sys):
tard_state_data_list = sys.systemTardStateTunnel.tard_state_data
longValue8 = tard_state_data_list[0]
longValue9 = tard_state_data_list[1]
print(
"Device status report,deviceState:", longValue8, ",deviceName:", "Luba..."
)
print("Device status report,deviceState:", longValue8, ",deviceName:", "Luba...")
chargeStateTemp = longValue9
longValue10 = tard_state_data_list[6]
longValue11 = tard_state_data_list[7]
1 change: 0 additions & 1 deletion pymammotion/bluetooth/data/notifydata.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,4 @@ def addData(self, bArr, i):
# JADX INFO: Access modifiers changed from: package-private
def getDataArray(self):
"""Generated source for method getDataArray"""
print("data Array")
return self.mDataOS.getvalue()
Loading
Loading