-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added wyze sdk tools, update silicone emu
1 parent
7bfff82
commit 7edb179
Showing
19 changed files
with
653 additions
and
15 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
Empty file.
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
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
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
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 |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import os | ||
import requests | ||
import websockets | ||
import asyncio | ||
import json | ||
import time | ||
import queue | ||
import wyze_sdk | ||
from wyze_sdk.service.base import WpkNetServiceClient | ||
import wyze_sdk.errors | ||
|
||
## We need to get device credentials from the Wyze API for a desired device | ||
## We are going to find all devices with the GW_BE1 device model prefix and take the first one | ||
## Once we have a device, we can query Wyze for the P2P connection information | ||
## Once we have the P2P connection information, we can send that info to the wyze server | ||
## Server will hopefully send us back video frames | ||
## Play video frames with opencv or similar | ||
|
||
WYZE_EMAIL = os.environ['WYZE_EMAIL'] # Your Wyze email | ||
WYZE_PASSWORD = os.environ['WYZE_PASSWORD'] # Your Wyze password | ||
WYZE_KEY_ID = os.environ['WYZE_KEY_ID'] # Your Wyze key ID | ||
WYZE_API_KEY = os.environ['WYZE_API_KEY'] |
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 |
---|---|---|
@@ -0,0 +1,139 @@ | ||
import os | ||
import requests | ||
import websockets | ||
import asyncio | ||
import keyboard | ||
import json | ||
import time | ||
import queue | ||
import wyze_sdk | ||
from wyze_sdk.service.base import WpkNetServiceClient | ||
import wyze_sdk.errors | ||
|
||
# p2pUrl = '|wyze-test-list.cloudlinks.cn|42.194.219.201' | ||
# wyzeP2pUrl = '|wyze-mars-asrv.wyzecam.com' | ||
# mars_url = 'https://wyze-mars-service.wyzecam.com/plugin/mars/v2/regist_gw_user/GW_BE1_7C78B2A2AD34' | ||
# mars_path_url = '/plugin/mars/v2/regist_gw_user/GW_BE1_7C78B2A2AD34' | ||
|
||
wyze_sdk.set_file_logger('wyze_sdk', filepath='wyze_out.txt', level=wyze_sdk.logging.DEBUG) | ||
mars_base_url = 'https://wyze-mars-service.wyzecam.com' | ||
email = '[email protected]' | ||
psswd = '@Lacylulu123!!!' | ||
key_id = '94458b0d-2e6a-4e9e-b438-5914f735461b' | ||
api_key='4yWuIM9jaSRvDQJ9aIEwqlNYSe0GHDx0LJvudthmiiy1Ju3OAHiMvmiZmBju' | ||
deviceId = "GW_BE1_7C78B2A2AD34" | ||
|
||
|
||
last_token_fetch_time = 0 | ||
current_response = None | ||
|
||
async def getLoginInfo(): | ||
global last_token_fetch_time, current_response | ||
current_time = time.time() | ||
if current_time - last_token_fetch_time < 30 and current_response is not None: | ||
return current_response | ||
|
||
client = wyze_sdk.Client() | ||
response = client.login( | ||
email=email, | ||
password=psswd, | ||
key_id=key_id, | ||
api_key=api_key | ||
) | ||
|
||
wpk = WpkNetServiceClient(token=client._token, base_url=mars_base_url) | ||
nonce = wpk.request_verifier.clock.nonce() | ||
json_dict = {"ttl_minutes" : 10080, 'nonce' : str(nonce), 'unique_id' : wpk.phone_id } | ||
header_dict = { 'appid' : wpk.app_id} | ||
|
||
try: | ||
resp = wpk.api_call(api_method=mars_path_url, json=json_dict, headers=header_dict, nonce=str(nonce)) | ||
print("Got new login info!") | ||
last_token_fetch_time = time.time() | ||
current_response = resp | ||
return resp | ||
except requests.HTTPError as e: | ||
print(f'HTTP Request Error') | ||
print(e.response) | ||
except wyze_sdk.errors.WyzeApiError as e: | ||
print(f'Wyze API Error:') | ||
print(e.response) | ||
except wyze_sdk.errors.WyzeRequestError as e: | ||
print('Request error: ') | ||
print(e.args) | ||
|
||
return None | ||
|
||
|
||
|
||
async def send_message(websocket): | ||
resp = await getLoginInfo() | ||
if resp is None: | ||
print("No login info") | ||
return | ||
accessId = resp["data"]["accessId"] | ||
accessToken = resp["data"]["accessToken"] | ||
expireTime = resp["data"]["expireTime"] | ||
|
||
print(accessId) | ||
print(accessToken) | ||
# Send a chat message | ||
chat_message = { | ||
"type": "login-info", | ||
"topic": "login-info", | ||
"data": { | ||
"accessId": "".join(accessId), | ||
"accessToken": accessToken, | ||
"expireTime": expireTime, | ||
"deviceId": deviceId, | ||
"timestamp": time.time() | ||
} | ||
} | ||
await websocket.send(json.dumps(chat_message)) | ||
print("Sent message") | ||
|
||
message_queue = queue.Queue() | ||
|
||
def spacebar_event(e): | ||
message_queue.put("Your message") | ||
|
||
async def subscribeToLoginInfo(websocket): | ||
chat_message = { | ||
"type": "Subscribe", | ||
"topic": "login-info" | ||
} | ||
await websocket.send(json.dumps(chat_message)) | ||
|
||
async def websocket_client(): | ||
uri = "ws://localhost:3030" | ||
try: | ||
async with websockets.connect(uri, ping_timeout=None) as websocket: # disable the library's automatic pinging | ||
websocket.ping_interval = None # disable the library's automatic pinging | ||
keyboard.on_press_key('right option', spacebar_event) | ||
await subscribeToLoginInfo(websocket) | ||
while True: | ||
try: | ||
while not message_queue.empty(): | ||
message = message_queue.get() | ||
await send_message(websocket) | ||
await asyncio.sleep(1) | ||
except KeyboardInterrupt: | ||
print("Ctrl+C pressed. Closing WebSocket connection...") | ||
await websocket.close() | ||
break | ||
except websockets.ConnectionClosedError as e: | ||
print(f"Connection closed: {e}") | ||
except websockets.InvalidStatusCode as e: | ||
print(f"Invalid status code: {e}") | ||
except websockets.InvalidURI as e: | ||
print(f"Invalid URI: {e}") | ||
except websockets.WebSocketProtocolError as e: | ||
print(f"WebSocket protocol error: {e}") | ||
except websockets.WebSocketException as e: | ||
print(f"WebSocket exception: {e}") | ||
except OSError as e: | ||
print(f"OS error: {e}") | ||
|
||
if __name__ == "__main__": | ||
print("Starting websocket client") | ||
asyncio.get_event_loop().run_until_complete(websocket_client()) |
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 |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import asyncio | ||
import websockets | ||
import os | ||
import json | ||
|
||
async def websocket_handler(uri): | ||
message_count = 0 | ||
async with websockets.connect(uri) as websocket: | ||
await websocket.send(json.dumps({"type": "Subscribe", "topic": "video-stream"})) | ||
|
||
async for message in websocket: | ||
if isinstance(message, bytes): | ||
with open(f'frames/message_{message_count}.bin', 'wb') as f: | ||
f.write(message) | ||
message_count += 1 | ||
print(f"Message saved to message_{message_count}.bin") | ||
|
||
# Replace with your WebSocket server URI | ||
uri = "ws://localhost:3030" | ||
asyncio.get_event_loop().run_until_complete(websocket_handler(uri)) |
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 |
---|---|---|
@@ -0,0 +1,22 @@ | ||
from PIL import Image | ||
import io | ||
import numpy as np | ||
import cv2 | ||
|
||
# Load the binary data from the file | ||
with open('frames/message_11.bin', 'rb') as f: | ||
binary_data = f.read() | ||
|
||
# Convert the binary data to a bytes-like object | ||
bytes_data = io.BytesIO(binary_data) | ||
|
||
# Open the bytes-like object as an image | ||
img = Image.open(bytes_data) | ||
|
||
# Convert the image to a numpy array | ||
frame_array = np.array(img) | ||
|
||
# Display the frame | ||
cv2.imshow('Frame', frame_array) | ||
cv2.waitKey(0) | ||
cv2.destroyAllWindows() |
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 |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import os | ||
import cv2 | ||
import asyncio | ||
import websockets | ||
import numpy as np | ||
import json | ||
|
||
# WebSocket URL | ||
websocket_url = "ws://localhost:3030" | ||
|
||
# OpenCV window name | ||
window_name = "Decoded Frames" | ||
|
||
# Named pipe for H264 data | ||
h264_pipe = "local_pipe" | ||
|
||
# Function to handle WebSocket messages | ||
async def on_message(message): | ||
# Write H264 data to the pipe | ||
with open(h264_pipe, 'wb+') as f: | ||
f.write(message) | ||
|
||
# Decode H264 data into frames | ||
decoded_frame = decode_h264() | ||
if decoded_frame is None: | ||
print("Error decoding frame") | ||
return | ||
# Display the decoded frame using OpenCV | ||
cv2.imshow(window_name, decoded_frame) | ||
cv2.waitKey(1) | ||
|
||
# Function to decode H264 data into frames | ||
def decode_h264(): | ||
cap = cv2.VideoCapture(h264_pipe) | ||
|
||
ret, frame = cap.read() | ||
|
||
if not ret: | ||
print("Error reading frame from pipe") | ||
return None | ||
|
||
return frame | ||
|
||
# Function to start a WebSocket connection | ||
async def start_websocket(): | ||
async with websockets.connect(websocket_url) as ws: | ||
# Subscribe to the video stream | ||
await ws.send(json.dumps({"type": "Subscribe", "topic": "video-stream"})) | ||
|
||
async for message in ws: | ||
print("Received message of length " + str(len(message))) | ||
if isinstance(message, bytes): | ||
# Handle H264 data | ||
await on_message(message) | ||
else: | ||
# Handle control messages | ||
data = json.loads(message) | ||
print(data["message"]) | ||
|
||
# Start the WebSocket connection | ||
asyncio.get_event_loop().run_until_complete(start_websocket()) |
Binary file not shown.
Oops, something went wrong.