aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FereFit_sendMessage_BLE.py44
-rw-r--r--README.md51
2 files changed, 95 insertions, 0 deletions
diff --git a/FereFit_sendMessage_BLE.py b/FereFit_sendMessage_BLE.py
new file mode 100644
index 0000000..f180c07
--- /dev/null
+++ b/FereFit_sendMessage_BLE.py
@@ -0,0 +1,44 @@
+import asyncio
+import sys
+try:
+ from bleak import BleakScanner, BleakClient
+except ModuleNotFoundError:
+ print("Error importing bleak, are you sure you installed it?")
+ print("Try running the following command: \"pip3 install bleak\"")
+ print("If that fails, try this: \"pip3 install bleak --break-system-packages\"")
+ sys.exit(1)
+
+WRITE_UUID = "6E40FC20-B5A3-F393-E0A9-E50E24DCCA9E"
+
+async def send_message(device_name: str, message: str, msg_type: int = 1):
+ print(f"Scanning for {device_name}...")
+ device = await BleakScanner.find_device_by_name(device_name, timeout=10)
+ if not device:
+ print("Watch not found!")
+ return
+ print(f"Found at {device.address}")
+
+ encoded = message.encode('utf-8')
+ chunks = [encoded[i:i+17] for i in range(0, len(encoded), 17)]
+
+ async with BleakClient(device) as client:
+ print("Enabling all message notification settings...")
+ settings = bytes([0x02, 0x02, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 3])
+ await client.write_gatt_char(WRITE_UUID, settings)
+ await asyncio.sleep(1)
+ for i, chunk in enumerate(chunks):
+ packet = bytes([0x23, i, msg_type]) + chunk
+ if i == len(chunks) - 1:
+ packet = packet + bytes([0xFF])
+ print(f"Sending chunk {i}: {packet.hex()}")
+ try:
+ await client.write_gatt_char(WRITE_UUID, packet)
+ print(f"Sent chunk {i}")
+ except Exception as e:
+ print(f"Failed to send chunk {i}: {e}")
+ await asyncio.sleep(5)
+
+if __name__ == "__main__":
+ watch_name = input("Enter watch name (default: Watch ULTRA): ") or "Watch ULTRA"
+ message = input("Enter message to send: ")
+ asyncio.run(send_message(watch_name, message))
diff --git a/README.md b/README.md
index 931bc06..4a1a8f7 100644
--- a/README.md
+++ b/README.md
@@ -84,6 +84,57 @@ Heart rate possible responses:
Other responses (blood oxygen, blood pressure, blood sugar) have not been tested yet.
+### sendMessageByZk (push notification to watch)
+
+Must send `configDeviceSettings` first to enable notifications on the watch, otherwise messages will not display.
+
+Notification enable packet (write/6E40FC20)
+```
+byte[0] = 0x02 (command)
+byte[1] = 0x02 (subcommand)
+byte[2] = skype enabled (0/1)
+byte[3] = line enabled (0/1)
+byte[4] = long time sit reminder interval
+byte[5] = long time sit enabled (0/1)
+byte[6] = call notice enabled (0/1)
+byte[7] = SMS notice enabled (0/1)
+byte[8] = WeChat enabled (0/1)
+byte[9] = QQ enabled (0/1)
+byte[10] = KakaoTalk enabled (0/1)
+byte[11] = Facebook enabled (0/1)
+byte[12] = Twitter enabled (0/1)
+byte[13] = WhatsApp enabled (0/1)
+byte[14] = LinkedIn enabled (0/1)
+byte[15] = heart rate monitor (0/1)
+byte[16] = hands up screen on (0/1)
+byte[17] = heart rate loop monitor (0/1)
+byte[18] = heart rate monitor interval time
+byte[19] = Instagram enabled (0/1)
+byte[20] = other push enabled (0/1)
+byte[21] = Zalo (bit 0) + Messenger (bit 1) flags
+```
+
+Message packet structure (write/6E40FC20), one packet per 17 byte chunk:
+```
+byte[0] = 0x23 (command)
+byte[1] = chunk index (0, 1, 2...)
+byte[2] = notification type
+ 0x01 = SMS
+ 0x02 = WeChat
+ 0x03 = QQ
+ 0x04 = DingTalk
+ 0x05 = WhatsApp
+ 0x06 = Facebook
+ 0x07 = Twitter
+ 0x08 = LinkedIn
+byte[3-19] = up to 17 bytes of UTF-8 message text
+byte[20] = 0xFF end marker (last chunk only, appended after text)
+```
+
+Message format: `"Title: Content"`, title truncated to 23 bytes, content to 240 bytes.
+
+Send chunks sequentially with ~100ms delay between each.
+
### enterMakeDial (watch face)
Watch face header packet (write/6E40FC20)