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.
Files changed (48) hide show
  1. {gshock_api-2.0.26/src/gshock_api.egg-info → gshock_api-2.0.28}/PKG-INFO +1 -1
  2. {gshock_api-2.0.26 → gshock_api-2.0.28}/pyproject.toml +1 -1
  3. {gshock_api-2.0.26 → gshock_api-2.0.28}/setup.py +1 -1
  4. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/connection.py +1 -5
  5. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/gshock_api.py +0 -2
  6. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/alarms_io.py +0 -2
  7. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/app_info_io.py +0 -3
  8. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/button_pressed_io.py +1 -4
  9. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/dst_for_world_cities_io.py +0 -4
  10. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/dst_watch_state_io.py +0 -4
  11. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/events_io.py +0 -2
  12. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/settings_io.py +0 -2
  13. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/time_adjustement_io.py +0 -4
  14. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/time_io.py +0 -2
  15. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/timer_io.py +0 -3
  16. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/watch_condition_io.py +0 -3
  17. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/watch_name_io.py +0 -3
  18. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/world_cities_io.py +0 -3
  19. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/message_dispatcher.py +0 -3
  20. gshock_api-2.0.28/src/gshock_api/scanner.py +60 -0
  21. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/watch_info.py +0 -1
  22. {gshock_api-2.0.26 → gshock_api-2.0.28/src/gshock_api.egg-info}/PKG-INFO +1 -1
  23. gshock_api-2.0.26/src/gshock_api/scanner.py +0 -128
  24. {gshock_api-2.0.26 → gshock_api-2.0.28}/LICENSE.txt +0 -0
  25. {gshock_api-2.0.26 → gshock_api-2.0.28}/README.rst +0 -0
  26. {gshock_api-2.0.26 → gshock_api-2.0.28}/setup.cfg +0 -0
  27. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/__init__.py +0 -0
  28. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/alarms.py +0 -0
  29. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/always_connected_watch_filter.py +0 -0
  30. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/app_notification.py +0 -0
  31. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/cancelable_result.py +0 -0
  32. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/casio_constants.py +0 -0
  33. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/event.py +0 -0
  34. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/exceptions.py +0 -0
  35. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/__init__.py +0 -0
  36. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/app_notification_io.py +0 -0
  37. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/error_io.py +0 -0
  38. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/iolib/unknown_io.py +0 -0
  39. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/logger.py +0 -0
  40. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/mailsener.py +0 -0
  41. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/settings.py +0 -0
  42. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api/utils.py +0 -0
  43. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/SOURCES.txt +0 -0
  44. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/dependency_links.txt +0 -0
  45. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/not-zip-safe +0 -0
  46. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/requires.txt +0 -0
  47. {gshock_api-2.0.26 → gshock_api-2.0.28}/src/gshock_api.egg-info/top_level.txt +0 -0
  48. {gshock_api-2.0.26 → gshock_api-2.0.28}/tests/test_code.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gshock_api
3
- Version: 2.0.26
3
+ Version: 2.0.28
4
4
  Summary: Pythgon API for GShock Watches using BLE
5
5
  Home-page: https://github.com/pyscaffold/pyscaffold/
6
6
  Author: Ivo Zivkov
@@ -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.26"
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" }]
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='gshock_api',
5
- version='2.0.26',
5
+ version='2.0.28',
6
6
  package_dir={'': 'src'},
7
7
  packages=find_packages(where='src'),
8
8
  install_requires=[
@@ -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 == None:
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,6 +1,4 @@
1
- import asyncio
2
1
  import json
3
- from typing import Any
4
2
  from gshock_api.alarms import alarms_inst, alarm_decoder
5
3
 
6
4
  from gshock_api.cancelable_result import CancelableResult
@@ -1,7 +1,4 @@
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
3
  from gshock_api.utils import to_compact_string, to_hex_string
7
4
  from gshock_api.casio_constants import CasioConstants
@@ -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.logger import logger
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,6 +1,4 @@
1
- import asyncio
2
1
  import json
3
- from typing import Any
4
2
  from gshock_api.cancelable_result import CancelableResult
5
3
  from gshock_api.logger import logger
6
4
  from gshock_api.casio_constants import CasioConstants
@@ -1,6 +1,4 @@
1
- import asyncio
2
1
  import json
3
- from typing import Any
4
2
  from gshock_api.cancelable_result import CancelableResult
5
3
  from gshock_api.settings import settings
6
4
  from gshock_api.utils import to_compact_string, to_hex_string, to_int_array
@@ -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,6 @@
1
1
  import time
2
2
  import datetime
3
3
  import json
4
- import time
5
- from typing import Any
6
4
  from gshock_api.logger import logger
7
5
 
8
6
  from gshock_api.utils import to_compact_string, to_hex_string
@@ -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
 
@@ -1,7 +1,4 @@
1
- import asyncio
2
- from typing import Any
3
1
 
4
- from gshock_api.casio_constants import CasioConstants
5
2
  from gshock_api.utils import clean_str, to_ascii_string, to_hex_string
6
3
  from gshock_api.cancelable_result import CancelableResult
7
4
 
@@ -1,8 +1,5 @@
1
- import asyncio
2
- from typing import Any
3
1
  from gshock_api.casio_constants import CasioConstants
4
2
  from gshock_api.cancelable_result import CancelableResult
5
- from gshock_api.logger import logger
6
3
 
7
4
  CHARACTERISTICS = CasioConstants.CHARACTERISTICS
8
5
 
@@ -1,7 +1,4 @@
1
- import sys
2
- import asyncio
3
1
  import json
4
- from typing import Any
5
2
  from gshock_api.logger import logger
6
3
  from gshock_api.casio_constants import CasioConstants
7
4
  from gshock_api.iolib.app_info_io import AppInfoIO
@@ -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,4 +1,3 @@
1
- from gshock_api.logger import logger
2
1
 
3
2
  class WATCH_MODEL:
4
3
  GA = 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gshock_api
3
- Version: 2.0.26
3
+ Version: 2.0.28
4
4
  Summary: Pythgon API for GShock Watches using BLE
5
5
  Home-page: https://github.com/pyscaffold/pyscaffold/
6
6
  Author: Ivo Zivkov
@@ -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