gshock-api 2.0.5__tar.gz → 2.0.7__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.5/src/gshock_api.egg-info → gshock_api-2.0.7}/PKG-INFO +1 -1
  2. {gshock_api-2.0.5 → gshock_api-2.0.7}/pyproject.toml +3 -2
  3. {gshock_api-2.0.5 → gshock_api-2.0.7}/setup.py +1 -1
  4. gshock_api-2.0.7/src/gshock_api/cancelable_result.py +23 -0
  5. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/connection.py +13 -11
  6. gshock_api-2.0.7/src/gshock_api/exceptions.py +9 -0
  7. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/gshock_api.py +1 -3
  8. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/alarms_io.py +2 -5
  9. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/app_info_io.py +2 -6
  10. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/button_pressed_io.py +2 -8
  11. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/dst_for_world_cities_io.py +2 -5
  12. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/dst_watch_state_io.py +3 -5
  13. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/events_io.py +2 -7
  14. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/settings_io.py +2 -7
  15. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/time_adjustement_io.py +3 -8
  16. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/time_io.py +9 -5
  17. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/timer_io.py +3 -8
  18. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/watch_condition_io.py +2 -9
  19. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/watch_name_io.py +2 -3
  20. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/world_cities_io.py +2 -5
  21. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/message_dispatcher.py +0 -1
  22. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/scanner.py +0 -2
  23. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/watch_info.py +0 -2
  24. {gshock_api-2.0.5 → gshock_api-2.0.7/src/gshock_api.egg-info}/PKG-INFO +1 -1
  25. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api.egg-info/SOURCES.txt +1 -0
  26. gshock_api-2.0.5/src/gshock_api/cancelable_result.py +0 -38
  27. {gshock_api-2.0.5 → gshock_api-2.0.7}/LICENSE.txt +0 -0
  28. {gshock_api-2.0.5 → gshock_api-2.0.7}/README.rst +0 -0
  29. {gshock_api-2.0.5 → gshock_api-2.0.7}/setup.cfg +0 -0
  30. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/__init__.py +0 -0
  31. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/alarms.py +0 -0
  32. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/app_notification.py +0 -0
  33. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/casio_constants.py +0 -0
  34. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/configurator.py +0 -0
  35. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/event.py +0 -0
  36. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/__init__.py +0 -0
  37. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/app_notification_io.py +0 -0
  38. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/error_io.py +0 -0
  39. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/iolib/unknown_io.py +0 -0
  40. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/logger.py +0 -0
  41. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/mailsener.py +0 -0
  42. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/settings.py +0 -0
  43. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api/utils.py +0 -0
  44. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api.egg-info/dependency_links.txt +0 -0
  45. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api.egg-info/not-zip-safe +0 -0
  46. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api.egg-info/requires.txt +0 -0
  47. {gshock_api-2.0.5 → gshock_api-2.0.7}/src/gshock_api.egg-info/top_level.txt +0 -0
  48. {gshock_api-2.0.5 → gshock_api-2.0.7}/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.5
3
+ Version: 2.0.7
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,10 +1,11 @@
1
1
  [build-system]
2
- requires = ["setuptools", "wheel"]
2
+ # requires = ["setuptools", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
+ requires = ["setuptools>=61.0"]
4
5
 
5
6
  [project]
6
7
  name = "gshock_api" # Change to your project name
7
- version = "2.0.5"
8
+ version = "2.0.7"
8
9
  description = "Pythgon API for GShock Watches using BLE"
9
10
  readme = "README.rst"
10
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.5',
5
+ version='2.0.7',
6
6
  package_dir={'': 'src'},
7
7
  packages=find_packages(where='src'),
8
8
  install_requires=[
@@ -0,0 +1,23 @@
1
+ import asyncio
2
+ from typing import Any
3
+ from gshock_api.exceptions import GShockConnectionError
4
+
5
+ class CancelableResult:
6
+ def __init__(self, timeout: float = 10.0):
7
+ self._timeout = timeout
8
+ self._future: asyncio.Future[Any] = asyncio.Future()
9
+
10
+ async def get_result(self) -> Any:
11
+ try:
12
+ result = await asyncio.wait_for(self._future, timeout=self._timeout)
13
+ return result
14
+ except asyncio.TimeoutError as e:
15
+ if not self._future.done():
16
+ self._future.set_result('') # or raise an exception instead
17
+ raise GShockConnectionError(f"Timeout occured waiting for response from the watch: {e}") from e
18
+
19
+ def set_result(self, result: Any) -> None:
20
+ if not self._future.done():
21
+ self._future.set_result(result)
22
+
23
+ cancelable_result = CancelableResult()
@@ -1,4 +1,5 @@
1
- import asyncio
1
+ import asyncio, time
2
+ from tracemalloc import start
2
3
  from bleak import BleakClient
3
4
  from bleak.backends.characteristic import BleakGATTCharacteristic
4
5
  from gshock_api.casio_constants import CasioConstants
@@ -8,6 +9,7 @@ from gshock_api.logger import logger
8
9
  from gshock_api.watch_info import watch_info
9
10
  from bleak.backends.device import BLEDevice
10
11
  from gshock_api.scanner import scanner
12
+ from gshock_api.exceptions import GShockConnectionError
11
13
 
12
14
  class Connection:
13
15
  def __init__(self, address = None):
@@ -25,7 +27,7 @@ class Connection:
25
27
  """
26
28
  Prints all services and characteristics of the connected BLE device.
27
29
  """
28
- services = await self.client.get_services()
30
+ services = self.client.services
29
31
  for service in services:
30
32
  for char in service.characteristics:
31
33
  self.characteristics_map[char.uuid] = char.uuid # Store in map
@@ -35,7 +37,6 @@ class Connection:
35
37
  # Scan for device if address not provided
36
38
  device = await scanner.scan(device_address=self.address if self.address else None)
37
39
  self.address = device.address # Always update with actual device found
38
- logger.info(f"Found device: {device.name} ({self.address})")
39
40
 
40
41
  self.client = BleakClient(self.address)
41
42
  await self.client.connect()
@@ -50,7 +51,7 @@ class Connection:
50
51
  return True
51
52
 
52
53
  except Exception as e:
53
- logger.warning(f"[GShock Connect] Connection failed: {e}")
54
+ logger.info(f"[GShock Connect] Connection failed: {e}")
54
55
  return False
55
56
 
56
57
  async def disconnect(self):
@@ -59,30 +60,31 @@ class Connection:
59
60
  def is_service_supported(self, handle):
60
61
  uuid = self.handles_map.get(handle)
61
62
  supported = (uuid not in self.characteristics_map)
62
- print(f"write, service with handle {handle} is supported: {supported}")
63
63
  return supported
64
64
 
65
65
  async def write(self, handle, data):
66
66
  try:
67
67
  uuid = self.handles_map.get(handle)
68
+
68
69
  if (uuid not in self.characteristics_map):
69
- logger.error(
70
+ logger.info(
70
71
  "write failed: handle {} not in characteristics map".format(handle)
71
72
  )
72
73
  if (handle == 13):
73
- logger.error(
74
- "Your watch does not suppot notifications..."
74
+ logger.info(
75
+ "Your watch does not support notifications..."
75
76
  )
76
77
  return
77
-
78
+
78
79
  await self.client.write_gatt_char(
79
80
  uuid, to_casio_cmd(data)
80
81
  )
82
+
81
83
  except Exception as e:
82
- logger.debug("write failed with exception: {}".format(e))
84
+ print("Exception type:", type(e))
85
+ raise GShockConnectionError(f"Unable to write to G-Shock device: {e}") from e
83
86
 
84
87
  async def request(self, request):
85
- logger.info("write: {}".format(request))
86
88
  await self.write(0xC, request)
87
89
 
88
90
  def init_handles_map(self):
@@ -0,0 +1,9 @@
1
+ # gshock_api/exceptions.py
2
+
3
+ class GShockError(Exception):
4
+ """Base exception for all G-Shock errors."""
5
+ pass
6
+
7
+ class GShockConnectionError(GShockError):
8
+ """Raised when BLE connection to G-Shock device fails."""
9
+ pass
@@ -205,8 +205,6 @@ class GshockAPI:
205
205
  if current_time == None:
206
206
  current_time = time.time()
207
207
 
208
- self.logger.info(f"=======> passed: ${current_time}, ${time.time()}")
209
-
210
208
  await self.initialize_for_setting_time()
211
209
  await self._set_time(current_time)
212
210
  current_time = None
@@ -231,7 +229,7 @@ class GshockAPI:
231
229
 
232
230
  async def _get_alarms(self):
233
231
  result = await message_dispatcher.AlarmsIO.request(self.connection)
234
- return await result
232
+ return result
235
233
 
236
234
  async def set_alarms(self, alarms):
237
235
  """Sets alarms to the watch. Up to 5 alarms are supported on the watch.
@@ -9,14 +9,12 @@ from gshock_api.casio_constants import CasioConstants
9
9
 
10
10
  CHARACTERISTICS = CasioConstants.CHARACTERISTICS
11
11
 
12
-
13
12
  class AlarmsIO:
14
13
  result: CancelableResult = None
15
14
  connection = None
16
15
 
17
16
  @staticmethod
18
17
  async def request(connection):
19
- await connection.request("GET_ALARMS")
20
18
  AlarmsIO.connection = connection
21
19
 
22
20
  alarms_inst.clear()
@@ -27,9 +25,8 @@ class AlarmsIO:
27
25
  async def _get_alarms(connection):
28
26
  await connection.sendMessage("""{ "action": "GET_ALARMS"}""")
29
27
 
30
- loop = asyncio.get_running_loop()
31
- AlarmsIO.result = loop.create_future()
32
- return AlarmsIO.result
28
+ AlarmsIO.result = CancelableResult()
29
+ return await AlarmsIO.result.get_result()
33
30
 
34
31
  @staticmethod
35
32
  async def send_to_watch(message=""):
@@ -15,13 +15,11 @@ class AppInfoIO:
15
15
 
16
16
  @staticmethod
17
17
  async def request(connection):
18
- logger.info(f"AppInfoIO request")
19
18
  AppInfoIO.connection = connection
20
19
  await connection.request("22")
21
20
 
22
- loop = asyncio.get_running_loop()
23
- AppInfoIO.result = loop.create_future()
24
- return AppInfoIO.result
21
+ AppInfoIO.result = CancelableResult()
22
+ return AppInfoIO.result.get_result()
25
23
 
26
24
  @staticmethod
27
25
  async def send_to_watch(connection):
@@ -29,8 +27,6 @@ class AppInfoIO:
29
27
 
30
28
  @staticmethod
31
29
  def on_received(data):
32
- logger.info(f"AppInfoIO onReceived")
33
-
34
30
  def set_app_info(data: str):
35
31
  # App info:
36
32
  # This is needed to re-enable button D (Lower-right) after the watch has been reset or BLE has been cleared.
@@ -26,9 +26,8 @@ class ButtonPressedIO:
26
26
  ButtonPressedIO.connection = connection
27
27
  await connection.request("10")
28
28
 
29
- loop = asyncio.get_running_loop()
30
- ButtonPressedIO.result = loop.create_future()
31
- return ButtonPressedIO.result
29
+ ButtonPressedIO.result = CancelableResult()
30
+ return ButtonPressedIO.result.get_result()
32
31
 
33
32
  @staticmethod
34
33
  async def send_to_watch(connection):
@@ -36,14 +35,10 @@ class ButtonPressedIO:
36
35
 
37
36
  @staticmethod
38
37
  async def send_to_watch_set(data):
39
- logger.info(f"TimerIO sendToWatchSet: {data}")
40
-
41
38
  await ButtonPressedIO.connection.write(0x000E, data)
42
39
 
43
40
  @staticmethod
44
41
  def on_received(data):
45
- logger.info(f"ButtonPressedIO onReceived")
46
-
47
42
  def button_pressed_callback(data):
48
43
  """
49
44
  RIGHT BUTTON: 0x10 17 62 07 38 85 CD 7F ->04<- 03 0F FF FF FF FF 24 00 00 00
@@ -57,7 +52,6 @@ class ButtonPressedIO:
57
52
  if len(data) >= 19:
58
53
  ble_int_arr = to_int_array(to_hex_string(data))
59
54
  button_indicator = ble_int_arr[8]
60
- logger.info(f"Buttom code pressed: ${button_indicator}")
61
55
  ret = (
62
56
  WatchButton.LOWER_LEFT
63
57
  if (button_indicator == 0 or button_indicator == 1)
@@ -14,14 +14,12 @@ class DstForWorldCitiesIO:
14
14
 
15
15
  @staticmethod
16
16
  async def request(connection, city_number: int):
17
- logger.info(f"DstForWorldCitiesIO request")
18
17
  DstForWorldCitiesIO.connection = connection
19
18
  key = "1e0{}".format(city_number)
20
19
  await connection.request(key)
21
20
 
22
- loop = asyncio.get_running_loop()
23
- DstForWorldCitiesIO.result = loop.create_future()
24
- return DstForWorldCitiesIO.result
21
+ DstForWorldCitiesIO.result = CancelableResult()
22
+ return DstForWorldCitiesIO.result.get_result()
25
23
 
26
24
  @staticmethod
27
25
  async def send_to_watch(connection):
@@ -29,5 +27,4 @@ class DstForWorldCitiesIO:
29
27
 
30
28
  @staticmethod
31
29
  def on_received(data):
32
- logger.info(f"DstForWorldCitiesIO onReceived")
33
30
  DstForWorldCitiesIO.result.set_result(data)
@@ -20,14 +20,13 @@ class DstWatchStateIO:
20
20
 
21
21
  @staticmethod
22
22
  async def request(connection, state: DtsState):
23
- logger.info(f"DstWatchStateIO request")
24
23
  DstWatchStateIO.connection = connection
25
24
  key = f"1d0{state.value}"
26
25
  await connection.request(key)
27
26
 
28
- loop = asyncio.get_running_loop()
29
- DstWatchStateIO.result = loop.create_future()
30
- return DstWatchStateIO.result
27
+ DstWatchStateIO.result = CancelableResult()
28
+ return DstWatchStateIO.result.get_result()
29
+
31
30
 
32
31
  @staticmethod
33
32
  async def send_to_watch(connection):
@@ -35,5 +34,4 @@ class DstWatchStateIO:
35
34
 
36
35
  @staticmethod
37
36
  def on_received(data):
38
- logger.info(f"DstWatchStateIO onReceived")
39
37
  DstWatchStateIO.result.set_result(data)
@@ -41,20 +41,16 @@ class EventsIO:
41
41
 
42
42
  @staticmethod
43
43
  async def request(connection, event_number):
44
- logger.info(f"EventsIO request")
45
44
  EventsIO.connection = connection
46
45
 
47
46
  await connection.request("30{}".format(event_number)) # reminder title
48
47
  await connection.request("31{}".format(event_number)) # reminder time
49
48
 
50
- loop = asyncio.get_running_loop()
51
- EventsIO.result = loop.create_future()
52
- return EventsIO.result
49
+ EventsIO.result = CancelableResult()
50
+ return EventsIO.result.get_result()
53
51
 
54
52
  @staticmethod
55
53
  async def send_to_watch_set(message):
56
- logger.info(f"EventsIO sendToWatchSet: {message}")
57
-
58
54
  def reminder_title_from_json(reminder_json):
59
55
  title_str = reminder_json.get("title")
60
56
  return to_byte_array(title_str, 18)
@@ -342,7 +338,6 @@ class EventsIO:
342
338
 
343
339
  reminder_json = json.loads(reminder_time_to_json(data[2:]))
344
340
  reminder_json.update(EventsIO.title)
345
- logger.info(reminder_json)
346
341
  EventsIO.result.set_result(reminder_json)
347
342
 
348
343
  @staticmethod
@@ -16,25 +16,20 @@ class SettingsIO:
16
16
 
17
17
  @staticmethod
18
18
  async def request(connection):
19
- logger.info(f"TimerIO request")
20
19
  SettingsIO.connection = connection
21
20
  await connection.request("13")
22
21
 
23
- loop = asyncio.get_running_loop()
24
- SettingsIO.result = loop.create_future()
25
- return SettingsIO.result
22
+ SettingsIO.result = CancelableResult()
23
+ return SettingsIO.result.get_result()
26
24
 
27
25
  @staticmethod
28
26
  def send_to_watch(message):
29
- logger.info(f"SettingsIO sendToWatch: {message}")
30
27
  SettingsIO.connection.write(
31
28
  0x000C, bytearray([CHARACTERISTICS["CASIO_SETTING_FOR_BASIC"]])
32
29
  )
33
30
 
34
31
  @staticmethod
35
32
  async def send_to_watch_set(message):
36
- logger.info(f"SettingsIO sendToWatchSet: {message}")
37
-
38
33
  def encode(settings):
39
34
  mask_24_hours = 0b00000001
40
35
  MASK_BUTTON_TONE_OFF = 0b00000010
@@ -20,27 +20,23 @@ class TimeAdjustmentIO:
20
20
 
21
21
  @staticmethod
22
22
  async def request(connection):
23
- logger.info(f"TimerIO request")
24
23
  TimeAdjustmentIO.connection = connection
25
24
  await connection.request("11")
26
25
 
27
- loop = asyncio.get_running_loop()
28
- TimeAdjustmentIO.result = loop.create_future()
29
- return TimeAdjustmentIO.result
26
+ TimeAdjustmentIO.result = CancelableResult()
27
+ return TimeAdjustmentIO.result.get_result()
28
+
30
29
 
31
30
  @staticmethod
32
31
  def send_to_watch(message):
33
- logger.info(f"TimeAdjustmentIO sendToWatch: {message}")
34
32
  TimeAdjustmentIO.connection.write(
35
33
  0x000C, bytearray([CHARACTERISTICS["TIME_ADJUSTMENT"]])
36
34
  )
37
35
 
38
36
  @staticmethod
39
37
  async def send_to_watch_set(message):
40
- logger.info(f"TimeAdjustmentIO sendToWatchSet: {message}")
41
38
 
42
39
  if TimeAdjustmentIO.original_value == None:
43
- logging.error("Error: Must call get before set")
44
40
  return ErrorIO.request("Error: Must call get before set")
45
41
 
46
42
  time_adjustment = json.loads(message).get("timeAdjustment") == "True"
@@ -61,7 +57,6 @@ class TimeAdjustmentIO:
61
57
 
62
58
  @staticmethod
63
59
  def on_received(message):
64
- logger.info(f"TimeAdjustmentIO onReceived: {message}")
65
60
  TimeAdjustmentIO.original_value = to_hex_string(
66
61
  message
67
62
  ) # save original message
@@ -3,17 +3,16 @@ import datetime
3
3
  import json
4
4
  import time
5
5
  from typing import Any
6
- from gshock_api.cancelable_result import CancelableResult
7
6
  from gshock_api.logger import logger
8
7
 
9
8
  from gshock_api.utils import to_compact_string, to_hex_string
10
9
  from gshock_api.casio_constants import CasioConstants
10
+ import bleak
11
11
 
12
12
  CHARACTERISTICS = CasioConstants.CHARACTERISTICS
13
13
 
14
14
 
15
15
  class TimeIO:
16
- result: CancelableResult = None
17
16
  connection = None
18
17
 
19
18
  @staticmethod
@@ -32,14 +31,19 @@ class TimeIO:
32
31
  @staticmethod
33
32
  async def send_to_watch_set(message):
34
33
  date_time_ms = int(json.loads(message).get("value"))
35
- logger.info("date_time_ms: {}".format(date_time_ms))
36
34
  date_time = datetime.datetime.fromtimestamp(date_time_ms / 1000.0)
37
35
  time_data = TimeEncoder.prepare_current_time(date_time)
38
36
  time_command = to_hex_string(
39
37
  bytearray([CHARACTERISTICS["CASIO_CURRENT_TIME"]]) + time_data
40
38
  )
41
- await TimeIO.connection.write(0xE, to_compact_string(time_command))
42
-
39
+ try:
40
+ await TimeIO.connection.write(0xE, to_compact_string(time_command))
41
+ except (Exception) as e:
42
+ # Ignore this exception if the LOWER-RIGHT button is pressed.
43
+ # In this case, the connection will be closed before the call completes with a response, and we get an EOFError.
44
+ # The call actually works, though.
45
+
46
+ logger.info(f"Error {e} ignored due to timeout limitation")
43
47
 
44
48
  class TimeEncoder:
45
49
  def prepare_current_time(date: datetime.datetime):
@@ -16,13 +16,12 @@ class TimerIO:
16
16
 
17
17
  @staticmethod
18
18
  async def request(connection):
19
- logger.info(f"TimerIO request")
20
19
  TimerIO.connection = connection
21
20
  await connection.request("18")
22
21
 
23
- loop = asyncio.get_running_loop()
24
- TimerIO.result = loop.create_future()
25
- return TimerIO.result
22
+ TimerIO.result = CancelableResult()
23
+ return TimerIO.result.get_result()
24
+
26
25
 
27
26
  @staticmethod
28
27
  async def send_to_watch(connection):
@@ -30,8 +29,6 @@ class TimerIO:
30
29
 
31
30
  @staticmethod
32
31
  async def send_to_watch_set(data):
33
- logger.info(f"TimerIO sendToWatchSet: {data}")
34
-
35
32
  def encode(seconds_str):
36
33
  in_seconds = int(seconds_str)
37
34
  hours = in_seconds // 3600
@@ -53,8 +50,6 @@ class TimerIO:
53
50
 
54
51
  @staticmethod
55
52
  def on_received(data):
56
- logger.info(f"TimerIO onReceived")
57
-
58
53
  def decode_value(data: str) -> str:
59
54
  timer_int_array = data
60
55
 
@@ -19,13 +19,11 @@ class WatchConditionIO:
19
19
 
20
20
  @staticmethod
21
21
  async def request(connection):
22
- logger.info(f"WatchConditionIO request")
23
22
  WatchConditionIO.connection = connection
24
23
  await connection.request("28")
25
24
 
26
- loop = asyncio.get_running_loop()
27
- WatchConditionIO.result = loop.create_future()
28
- return WatchConditionIO.result
25
+ WatchConditionIO.result = CancelableResult()
26
+ return WatchConditionIO.result.get_result()
29
27
 
30
28
  @staticmethod
31
29
  async def send_to_watch(connection):
@@ -33,16 +31,11 @@ class WatchConditionIO:
33
31
 
34
32
  @staticmethod
35
33
  def on_received(data):
36
- logger.info(f"WatchConditionIO onReceived")
37
-
38
34
  def decode_value(data: str) -> WatchConditionIO.WatchConditionValue:
39
35
  int_arr = list(map(int, data))
40
36
  bytes_data = bytes(int_arr[1:])
41
37
 
42
38
  if len(bytes_data) >= 2:
43
- # Battery level between 15 and 20 for B2100 and between 12 and 19 for B5600. Scale accordingly to %
44
- logger.info(f"battery level row value: {int(bytes_data[0])}")
45
-
46
39
  battery_level_lower_limit = watch_info.batteryLevelLowerLimit
47
40
  battery_level_upper_limit = watch_info.batteryLevelUpperLimit
48
41
 
@@ -15,9 +15,8 @@ class WatchNameIO:
15
15
  WatchNameIO.connection = connection
16
16
  await connection.request("23")
17
17
 
18
- loop = asyncio.get_running_loop()
19
- WatchNameIO.result = loop.create_future()
20
- return WatchNameIO.result
18
+ WatchNameIO.result = CancelableResult()
19
+ return WatchNameIO.result.get_result()
21
20
 
22
21
  @staticmethod
23
22
  def on_received(data):
@@ -13,15 +13,13 @@ class WorldCitiesIO:
13
13
 
14
14
  @staticmethod
15
15
  async def request(connection, cityNumber: int):
16
- logger.info(f"DstWatchStateIO request")
17
16
  WorldCitiesIO.connection = connection
18
17
  key = "1f0{}".format(cityNumber)
19
18
 
20
19
  await connection.request(key)
21
20
 
22
- loop = asyncio.get_running_loop()
23
- WorldCitiesIO.result = loop.create_future()
24
- return WorldCitiesIO.result
21
+ WorldCitiesIO.result = CancelableResult()
22
+ return WorldCitiesIO.result.get_result()
25
23
 
26
24
  @staticmethod
27
25
  async def send_to_watch(connection):
@@ -29,5 +27,4 @@ class WorldCitiesIO:
29
27
 
30
28
  @staticmethod
31
29
  def on_received(data):
32
- logger.info(f"WorldCitiesIO onReceived")
33
30
  WorldCitiesIO.result.set_result(data)
@@ -72,7 +72,6 @@ class MessageDispatcher:
72
72
  if key not in MessageDispatcher.data_received_messages:
73
73
  logger.info(f"Unknown key: {key}")
74
74
  else:
75
- logger.info(f"Found key: {MessageDispatcher.data_received_messages[key]}")
76
75
  MessageDispatcher.data_received_messages[key](data)
77
76
 
78
77
  # Usage example
@@ -11,7 +11,6 @@ class Scanner:
11
11
 
12
12
  async def scan(self, device_address=None) -> BLEDevice:
13
13
  scanner = BleakScanner()
14
- logger.info("Scanning for devices...")
15
14
 
16
15
  if device_address is None:
17
16
  while True:
@@ -19,7 +18,6 @@ class Scanner:
19
18
  lambda d, ad: d.name and d.name.lower().startswith("casio"),
20
19
  timeout=5 * 60.0,
21
20
  )
22
- logger.info(f"device: {device}")
23
21
  if device is None:
24
22
  continue
25
23
 
@@ -202,8 +202,6 @@ class WatchInfo:
202
202
  if len(parts) > 1:
203
203
  self.shortName = parts[1]
204
204
 
205
- logger.info(f"============> self.shortName: ${self.shortName}")
206
-
207
205
  # *** Order matters. Start with the longest shortName first. ***
208
206
  if self.shortName.startswith("MSG"):
209
207
  self.model = WATCH_MODEL.MSG
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gshock_api
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: Pythgon API for GShock Watches using BLE
5
5
  Home-page: https://github.com/pyscaffold/pyscaffold/
6
6
  Author: Ivo Zivkov
@@ -11,6 +11,7 @@ src/gshock_api/casio_constants.py
11
11
  src/gshock_api/configurator.py
12
12
  src/gshock_api/connection.py
13
13
  src/gshock_api/event.py
14
+ src/gshock_api/exceptions.py
14
15
  src/gshock_api/gshock_api.py
15
16
  src/gshock_api/logger.py
16
17
  src/gshock_api/mailsener.py
@@ -1,38 +0,0 @@
1
- import asyncio
2
- from typing import Any
3
-
4
- class CancelableResult:
5
- def __init__(self, timeout: float = 5.0):
6
- self._timeout = timeout
7
- self._future: asyncio.Future[Any] = asyncio.Future()
8
-
9
- async def get_result(self) -> Any:
10
- try:
11
- return await asyncio.wait_for(self._future, timeout=self._timeout)
12
- except asyncio.TimeoutError:
13
- if not self._future.done():
14
- self._future.set_result('')
15
- return await self._future
16
-
17
- def set_result(self, result: Any) -> None:
18
- if not self._future.done():
19
- self._future.set_result(result)
20
-
21
- # Example usage
22
- async def main():
23
- cancelable_result = CancelableResult(timeout=5)
24
-
25
- # Simulate some async work that might or might not set a result
26
- async def some_async_work():
27
- await asyncio.sleep(3) # Change this to 6 to test the timeout
28
- cancelable_result.set_result('Result after async work')
29
-
30
- await asyncio.gather(some_async_work(), asyncio.sleep(6))
31
-
32
- final_result = await cancelable_result.get_result()
33
- print(f'Final result: "{final_result}"')
34
-
35
- # Run the main coroutine
36
- # asyncio.run(main())
37
-
38
- cancelable_result = CancelableResult()
File without changes
File without changes
File without changes