gshock-api 2.0.26__tar.gz → 2.0.28__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gshock_api-2.0.26/src/gshock_api.egg-info → gshock_api-2.0.28}/PKG-INFO +1 -1
- {gshock_api-2.0.26 → gshock_api-2.0.28}/pyproject.toml +1 -1
- {gshock_api-2.0.26 → gshock_api-2.0.28}/setup.py +1 -1
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/connection.py +1 -5
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/gshock_api.py +0 -2
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/alarms_io.py +0 -2
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/app_info_io.py +0 -3
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/button_pressed_io.py +1 -4
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/dst_for_world_cities_io.py +0 -4
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/dst_watch_state_io.py +0 -4
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/events_io.py +0 -2
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/settings_io.py +0 -2
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/time_adjustement_io.py +0 -4
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/time_io.py +0 -2
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/timer_io.py +0 -3
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/watch_condition_io.py +0 -3
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/watch_name_io.py +0 -3
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/world_cities_io.py +0 -3
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/message_dispatcher.py +0 -3
- gshock_api-2.0.28/src/gshock_api/scanner.py +60 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/watch_info.py +0 -1
- {gshock_api-2.0.26 → gshock_api-2.0.28/src/gshock_api.egg-info}/PKG-INFO +1 -1
- gshock_api-2.0.26/src/gshock_api/scanner.py +0 -128
- {gshock_api-2.0.26 → gshock_api-2.0.28}/LICENSE.txt +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/README.rst +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/setup.cfg +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/__init__.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/alarms.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/always_connected_watch_filter.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/app_notification.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/cancelable_result.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/casio_constants.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/event.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/exceptions.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/__init__.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/app_notification_io.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/error_io.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/unknown_io.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/logger.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/mailsener.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/settings.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/utils.py +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/SOURCES.txt +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/dependency_links.txt +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/not-zip-safe +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/requires.txt +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/top_level.txt +0 -0
- {gshock_api-2.0.26 → gshock_api-2.0.28}/tests/test_code.py +0 -0
|
@@ -5,7 +5,7 @@ requires = ["setuptools>=61.0"]
|
|
|
5
5
|
|
|
6
6
|
[project]
|
|
7
7
|
name = "gshock_api" # Change to your project name
|
|
8
|
-
version = "2.0.
|
|
8
|
+
version = "2.0.28"
|
|
9
9
|
description = "Pythgon API for GShock Watches using BLE"
|
|
10
10
|
readme = "README.rst"
|
|
11
11
|
authors = [{ name = "Ivo Zivkov", email = "izivkov@gmail.com" }]
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import asyncio, time
|
|
2
|
-
from tracemalloc import start
|
|
3
1
|
from bleak import BleakClient
|
|
4
2
|
from bleak.exc import BleakDBusError
|
|
5
3
|
from bleak.backends.characteristic import BleakGATTCharacteristic
|
|
@@ -7,8 +5,6 @@ from gshock_api.casio_constants import CasioConstants
|
|
|
7
5
|
from gshock_api import message_dispatcher
|
|
8
6
|
from gshock_api.utils import to_casio_cmd
|
|
9
7
|
from gshock_api.logger import logger
|
|
10
|
-
from gshock_api.watch_info import watch_info
|
|
11
|
-
from bleak.backends.device import BLEDevice
|
|
12
8
|
from gshock_api.scanner import scanner
|
|
13
9
|
from gshock_api.exceptions import GShockIgnorableException, GShockConnectionError
|
|
14
10
|
|
|
@@ -36,7 +32,7 @@ class Connection:
|
|
|
36
32
|
async def connect(self, watch_filter=None) -> bool:
|
|
37
33
|
try:
|
|
38
34
|
# Scan for device if address not provided
|
|
39
|
-
if self.address
|
|
35
|
+
if self.address is None:
|
|
40
36
|
device = await scanner.scan(
|
|
41
37
|
device_address=self.address if self.address else None,
|
|
42
38
|
watch_filter=watch_filter
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import json
|
|
3
|
-
import time
|
|
4
3
|
|
|
5
4
|
from gshock_api.iolib.dst_watch_state_io import DtsState
|
|
6
5
|
from gshock_api.iolib.button_pressed_io import WatchButton
|
|
@@ -12,7 +11,6 @@ from gshock_api.utils import (
|
|
|
12
11
|
to_compact_string,
|
|
13
12
|
)
|
|
14
13
|
from gshock_api.alarms import alarms_inst
|
|
15
|
-
from gshock_api.event import Event
|
|
16
14
|
from gshock_api.watch_info import watch_info
|
|
17
15
|
|
|
18
16
|
class GshockAPI:
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import asyncio
|
|
2
1
|
from enum import IntEnum
|
|
3
|
-
from typing import Any
|
|
4
2
|
from gshock_api.cancelable_result import CancelableResult
|
|
5
|
-
from gshock_api.
|
|
6
|
-
from gshock_api.utils import to_compact_string, to_hex_string, to_int_array
|
|
3
|
+
from gshock_api.utils import to_hex_string, to_int_array
|
|
7
4
|
from gshock_api.casio_constants import CasioConstants
|
|
8
5
|
|
|
9
6
|
CHARACTERISTICS = CasioConstants.CHARACTERISTICS
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from typing import Any
|
|
3
1
|
from gshock_api.cancelable_result import CancelableResult
|
|
4
|
-
from gshock_api.logger import logger
|
|
5
2
|
|
|
6
|
-
from gshock_api.utils import to_compact_string, to_hex_string
|
|
7
3
|
from gshock_api.casio_constants import CasioConstants
|
|
8
4
|
|
|
9
5
|
CHARACTERISTICS = CasioConstants.CHARACTERISTICS
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import asyncio
|
|
2
1
|
from enum import IntEnum
|
|
3
|
-
from typing import Any
|
|
4
2
|
from gshock_api.cancelable_result import CancelableResult
|
|
5
|
-
from gshock_api.logger import logger
|
|
6
|
-
from gshock_api.utils import to_compact_string, to_hex_string
|
|
7
3
|
from gshock_api.casio_constants import CasioConstants
|
|
8
4
|
|
|
9
5
|
CHARACTERISTICS = CasioConstants.CHARACTERISTICS
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import asyncio
|
|
2
1
|
import json
|
|
3
|
-
import logging
|
|
4
|
-
from typing import Any
|
|
5
2
|
from gshock_api.cancelable_result import CancelableResult
|
|
6
|
-
from gshock_api.settings import settings
|
|
7
3
|
from gshock_api.utils import to_compact_string, to_hex_string, to_int_array
|
|
8
4
|
from gshock_api.casio_constants import CasioConstants
|
|
9
5
|
from gshock_api.iolib.error_io import ErrorIO
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import asyncio
|
|
2
1
|
import json
|
|
3
|
-
from typing import Any
|
|
4
2
|
from gshock_api.cancelable_result import CancelableResult
|
|
5
|
-
from gshock_api.logger import logger
|
|
6
3
|
|
|
7
4
|
from gshock_api.utils import to_compact_string, to_hex_string
|
|
8
5
|
from gshock_api.casio_constants import CasioConstants
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from typing import Any
|
|
3
1
|
from gshock_api.cancelable_result import CancelableResult
|
|
4
2
|
from gshock_api.watch_info import watch_info
|
|
5
3
|
from gshock_api.casio_constants import CasioConstants
|
|
6
|
-
from gshock_api.logger import logger
|
|
7
4
|
|
|
8
5
|
CHARACTERISTICS = CasioConstants.CHARACTERISTICS
|
|
9
6
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from gshock_api.watch_info import watch_info
|
|
5
|
+
from gshock_api.logger import logger
|
|
6
|
+
from bleak.backends.device import BLEDevice
|
|
7
|
+
from bleak import BleakScanner, BLEDevice
|
|
8
|
+
from bleak.exc import BleakError
|
|
9
|
+
from typing import Optional
|
|
10
|
+
|
|
11
|
+
class Scanner:
|
|
12
|
+
def __init__(self):
|
|
13
|
+
self._found_device: Optional[BLEDevice] = None
|
|
14
|
+
self._event = asyncio.Event()
|
|
15
|
+
|
|
16
|
+
async def scan(
|
|
17
|
+
self,
|
|
18
|
+
device_address: str | None = None,
|
|
19
|
+
watch_filter=None,
|
|
20
|
+
max_retries: int = 60
|
|
21
|
+
) -> BLEDevice | None:
|
|
22
|
+
|
|
23
|
+
CASIO_SERVICE_UUID = "00001804-0000-1000-8000-00805f9b34fb"
|
|
24
|
+
found = None
|
|
25
|
+
|
|
26
|
+
if not device_address:
|
|
27
|
+
for _ in range(max_retries):
|
|
28
|
+
await asyncio.sleep(1)
|
|
29
|
+
try:
|
|
30
|
+
def uuid_filter(d: BLEDevice, ad):
|
|
31
|
+
su = ad.service_uuids or []
|
|
32
|
+
return CASIO_SERVICE_UUID in su and (watch_filter is None or watch_filter(d.name))
|
|
33
|
+
found = await BleakScanner().find_device_by_filter(uuid_filter, timeout=10)
|
|
34
|
+
if found:
|
|
35
|
+
logger.info(f"✅ Found: {found.name} ({found.address})")
|
|
36
|
+
watch_info.set_name_and_model(found.name)
|
|
37
|
+
return found
|
|
38
|
+
logger.debug("⚠️ No matching device found, retrying...")
|
|
39
|
+
except BleakError as e:
|
|
40
|
+
logger.warning(f"⚠️ BleakError: BLE scan error: {e}")
|
|
41
|
+
except Exception as e:
|
|
42
|
+
logger.warning(f"⚠️ BLE scan error: {e}")
|
|
43
|
+
|
|
44
|
+
logger.error("⚠️ Max retries reached. No device found.")
|
|
45
|
+
else:
|
|
46
|
+
logger.info(f"⚠️ Waiting for specific device by address: {device_address}...")
|
|
47
|
+
try:
|
|
48
|
+
found = await BleakScanner().find_device_by_address(
|
|
49
|
+
device_address, timeout=sys.float_info.max
|
|
50
|
+
)
|
|
51
|
+
except BleakError as e:
|
|
52
|
+
logger.error(f"⚠️ Error finding device by address: {e}")
|
|
53
|
+
return None
|
|
54
|
+
if not found:
|
|
55
|
+
logger.warning("⚠️ Device not found by address.")
|
|
56
|
+
return None
|
|
57
|
+
watch_info.set_name_and_model(found.name)
|
|
58
|
+
return found
|
|
59
|
+
|
|
60
|
+
scanner = Scanner()
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
|
|
3
|
-
import asyncio
|
|
4
|
-
from bleak import BleakScanner
|
|
5
|
-
from gshock_api.watch_info import watch_info
|
|
6
|
-
from gshock_api.logger import logger
|
|
7
|
-
from bleak.backends.device import BLEDevice
|
|
8
|
-
from bleak import BleakScanner, BLEDevice
|
|
9
|
-
from bleak.exc import BleakError
|
|
10
|
-
from typing import Optional
|
|
11
|
-
|
|
12
|
-
class Scanner:
|
|
13
|
-
def __init__(self):
|
|
14
|
-
self._found_device: Optional[BLEDevice] = None
|
|
15
|
-
self._event = asyncio.Event()
|
|
16
|
-
|
|
17
|
-
async def scan(
|
|
18
|
-
self,
|
|
19
|
-
device_address: str | None = None,
|
|
20
|
-
watch_filter = None,
|
|
21
|
-
max_retries: int = 60, # Optional: to prevent infinite loops
|
|
22
|
-
) -> BLEDevice | None:
|
|
23
|
-
scanner = BleakScanner()
|
|
24
|
-
|
|
25
|
-
retries = 0
|
|
26
|
-
device = None
|
|
27
|
-
|
|
28
|
-
if device_address is None:
|
|
29
|
-
while retries < max_retries:
|
|
30
|
-
await asyncio.sleep(1)
|
|
31
|
-
try:
|
|
32
|
-
def casio_filter(device: BLEDevice, advertisement_data) -> bool:
|
|
33
|
-
if not device.name:
|
|
34
|
-
return False
|
|
35
|
-
|
|
36
|
-
parts = device.name.split(" ", 1)
|
|
37
|
-
if not parts:
|
|
38
|
-
return False
|
|
39
|
-
|
|
40
|
-
is_casio = parts[0].lower() == "casio"
|
|
41
|
-
passed = is_casio and (watch_filter is None or watch_filter(device.name))
|
|
42
|
-
return passed
|
|
43
|
-
|
|
44
|
-
device = await scanner.find_device_by_filter(
|
|
45
|
-
casio_filter,
|
|
46
|
-
timeout=10,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
if device:
|
|
50
|
-
logger.info(f"✅ Found: {device.name} ({device.address})")
|
|
51
|
-
watch_info.set_name_and_model(device.name)
|
|
52
|
-
return device
|
|
53
|
-
else:
|
|
54
|
-
retries += 1
|
|
55
|
-
logger.debug(f"⚠️ No matching device found, retry {retries}...")
|
|
56
|
-
|
|
57
|
-
except BleakError as e:
|
|
58
|
-
logger.warning(f"⚠️ BLE scan error: {e}")
|
|
59
|
-
retries += 1
|
|
60
|
-
|
|
61
|
-
logger.error("⚠️ Max retries reached. No device found.")
|
|
62
|
-
return None
|
|
63
|
-
|
|
64
|
-
else:
|
|
65
|
-
logger.info(f"⚠️ Waiting for specific device by address: {device_address}...")
|
|
66
|
-
try:
|
|
67
|
-
device = await scanner.find_device_by_address(
|
|
68
|
-
device_address, timeout=sys.float_info.max
|
|
69
|
-
)
|
|
70
|
-
except BleakError as e:
|
|
71
|
-
logger.error(f"⚠️ Error finding device by address: {e}")
|
|
72
|
-
return None
|
|
73
|
-
|
|
74
|
-
if device is None:
|
|
75
|
-
logger.warning("⚠️ Device not found by address.")
|
|
76
|
-
return None
|
|
77
|
-
|
|
78
|
-
if any(device.name.lower().startswith(p.lower()) for p in excluded_watches):
|
|
79
|
-
logger.info(f"Excluded device found: {device.name}")
|
|
80
|
-
return None
|
|
81
|
-
|
|
82
|
-
watch_info.set_name_and_model(device.name)
|
|
83
|
-
return device
|
|
84
|
-
|
|
85
|
-
async def scan_with_discover(self, device_address: Optional[str] = None, excluded_watches: Optional[list[str]] = None) -> Optional[BLEDevice]:
|
|
86
|
-
if excluded_watches is None:
|
|
87
|
-
excluded_watches = []
|
|
88
|
-
|
|
89
|
-
logger.info("🔍 Scanning for CASIO device...")
|
|
90
|
-
|
|
91
|
-
try:
|
|
92
|
-
while True:
|
|
93
|
-
try:
|
|
94
|
-
devices = await BleakScanner.discover(timeout=5.0)
|
|
95
|
-
except Exception as e:
|
|
96
|
-
logger.warning(f"⚠️ Scan error: {e}")
|
|
97
|
-
await asyncio.sleep(1)
|
|
98
|
-
continue
|
|
99
|
-
|
|
100
|
-
if not devices:
|
|
101
|
-
logger.debug("No BLE devices found.")
|
|
102
|
-
await asyncio.sleep(1)
|
|
103
|
-
continue
|
|
104
|
-
|
|
105
|
-
for device in devices:
|
|
106
|
-
name = device.name or ""
|
|
107
|
-
parts = name.split(" ", 1)
|
|
108
|
-
is_casio = parts[0].lower() == "casio"
|
|
109
|
-
is_excluded = len(parts) > 1 and parts[1] in excluded_watches
|
|
110
|
-
if is_excluded:
|
|
111
|
-
logger.info(f"{name} excluded!")
|
|
112
|
-
|
|
113
|
-
if is_casio and not is_excluded:
|
|
114
|
-
logger.info(f"✅ Found: {name} ({device.address})")
|
|
115
|
-
watch_info.set_name_and_model(device.name)
|
|
116
|
-
return device
|
|
117
|
-
|
|
118
|
-
await asyncio.sleep(1) # ✅ Wait before next loop
|
|
119
|
-
|
|
120
|
-
except asyncio.CancelledError:
|
|
121
|
-
logger.info("🔁 Scan loop cancelled.")
|
|
122
|
-
raise
|
|
123
|
-
|
|
124
|
-
except Exception as e:
|
|
125
|
-
logger.exception(f"❌ Unexpected scan error: {e}")
|
|
126
|
-
return None
|
|
127
|
-
|
|
128
|
-
scanner = Scanner()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|