IS-Matrix-Forge 1.0.0.dev1__py3-none-any.whl

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 (123) hide show
  1. is_matrix_forge/__init__.py +8 -0
  2. is_matrix_forge/assets/__init__.py +8 -0
  3. is_matrix_forge/assets/audio/__init__.py +36 -0
  4. is_matrix_forge/assets/audio/files/__init__.py +53 -0
  5. is_matrix_forge/assets/audio/files/plugged.wav +0 -0
  6. is_matrix_forge/assets/audio/files/unplugged.wav +0 -0
  7. is_matrix_forge/assets/char_map.json +2150 -0
  8. is_matrix_forge/assets/font_map.py +119 -0
  9. is_matrix_forge/common/__init__.py +0 -0
  10. is_matrix_forge/common/decorators/__init__.py +152 -0
  11. is_matrix_forge/common/dirs.py +20 -0
  12. is_matrix_forge/common/helpers/__init__.py +132 -0
  13. is_matrix_forge/common/helpers/github_api.py +67 -0
  14. is_matrix_forge/designer_gui/__init__.py +8 -0
  15. is_matrix_forge/designer_gui/main_window/__init__.py +252 -0
  16. is_matrix_forge/designer_gui/main_window/layout.py +117 -0
  17. is_matrix_forge/dev_tools/__init__.py +8 -0
  18. is_matrix_forge/dev_tools/debug.py +82 -0
  19. is_matrix_forge/dev_tools/presets.py +47 -0
  20. is_matrix_forge/inputmodule/__init__.py +164 -0
  21. is_matrix_forge/inputmodule/b1display.py +160 -0
  22. is_matrix_forge/inputmodule/c1minimal.py +35 -0
  23. is_matrix_forge/inputmodule/font.py +2166 -0
  24. is_matrix_forge/inputmodule/helpers/__init__.py +16 -0
  25. is_matrix_forge/inputmodule/ledmatrix.py +516 -0
  26. is_matrix_forge/led_matrix/Scripts/__init__.py +4 -0
  27. is_matrix_forge/led_matrix/Scripts/battery_monitor.py +152 -0
  28. is_matrix_forge/led_matrix/Scripts/install_presets/__init__.py +2 -0
  29. is_matrix_forge/led_matrix/Scripts/install_presets/arguments.py +84 -0
  30. is_matrix_forge/led_matrix/Scripts/install_presets/main.py +192 -0
  31. is_matrix_forge/led_matrix/__init__.py +7 -0
  32. is_matrix_forge/led_matrix/commands/__init__.py +84 -0
  33. is_matrix_forge/led_matrix/commands/map.py +46 -0
  34. is_matrix_forge/led_matrix/constants.py +82 -0
  35. is_matrix_forge/led_matrix/controller/__init__.py +26 -0
  36. is_matrix_forge/led_matrix/controller/controller.py +635 -0
  37. is_matrix_forge/led_matrix/controller/helpers/__init__.py +7 -0
  38. is_matrix_forge/led_matrix/controller/helpers/threading.py +41 -0
  39. is_matrix_forge/led_matrix/controller/multiton.py +32 -0
  40. is_matrix_forge/led_matrix/controller/threaded.py +72 -0
  41. is_matrix_forge/led_matrix/display/__init__.py +13 -0
  42. is_matrix_forge/led_matrix/display/animations/__init__.py +29 -0
  43. is_matrix_forge/led_matrix/display/animations/animation.py +593 -0
  44. is_matrix_forge/led_matrix/display/animations/effects/__init__.py +17 -0
  45. is_matrix_forge/led_matrix/display/animations/errors.py +23 -0
  46. is_matrix_forge/led_matrix/display/animations/font/__init__.py +17 -0
  47. is_matrix_forge/led_matrix/display/animations/font/font.py +4 -0
  48. is_matrix_forge/led_matrix/display/animations/font/map_builder.py +123 -0
  49. is_matrix_forge/led_matrix/display/animations/frame/__init__.py +47 -0
  50. is_matrix_forge/led_matrix/display/animations/frame/base.py +245 -0
  51. is_matrix_forge/led_matrix/display/animations/frame/helpers.py +67 -0
  52. is_matrix_forge/led_matrix/display/animations/keep_awake.py +1 -0
  53. is_matrix_forge/led_matrix/display/animations/plugged.py +0 -0
  54. is_matrix_forge/led_matrix/display/animations/text_scroller.py +104 -0
  55. is_matrix_forge/led_matrix/display/effects/__init__.py +17 -0
  56. is_matrix_forge/led_matrix/display/effects/breather.py +206 -0
  57. is_matrix_forge/led_matrix/display/effects/fade.py +0 -0
  58. is_matrix_forge/led_matrix/display/effects/scroller/__init__.py +92 -0
  59. is_matrix_forge/led_matrix/display/effects/scroller/base.py +76 -0
  60. is_matrix_forge/led_matrix/display/effects/scroller/helpers.py +62 -0
  61. is_matrix_forge/led_matrix/display/grid/__init__.py +9 -0
  62. is_matrix_forge/led_matrix/display/grid/grid.py +208 -0
  63. is_matrix_forge/led_matrix/display/grid/helpers.py +130 -0
  64. is_matrix_forge/led_matrix/display/grid/presets/__init__.py +64 -0
  65. is_matrix_forge/led_matrix/display/grid/presets/manifest.py +172 -0
  66. is_matrix_forge/led_matrix/display/helpers/__init__.py +110 -0
  67. is_matrix_forge/led_matrix/display/helpers/columns.py +33 -0
  68. is_matrix_forge/led_matrix/display/media.py +199 -0
  69. is_matrix_forge/led_matrix/display/patterns/__init__.py +59 -0
  70. is_matrix_forge/led_matrix/display/patterns/built_in/__init__.py +91 -0
  71. is_matrix_forge/led_matrix/display/patterns/built_in/commands.py +3 -0
  72. is_matrix_forge/led_matrix/display/patterns/built_in/constants.py +29 -0
  73. is_matrix_forge/led_matrix/display/patterns/built_in/stencils.py +70 -0
  74. is_matrix_forge/led_matrix/display/patterns/utils.py +2 -0
  75. is_matrix_forge/led_matrix/display/text/__init__.py +66 -0
  76. is_matrix_forge/led_matrix/display/text/scroller.py +136 -0
  77. is_matrix_forge/led_matrix/errors/__init__.py +4 -0
  78. is_matrix_forge/led_matrix/errors/base.py +14 -0
  79. is_matrix_forge/led_matrix/errors/grid.py +37 -0
  80. is_matrix_forge/led_matrix/errors/matrix.py +68 -0
  81. is_matrix_forge/led_matrix/errors/misc.py +36 -0
  82. is_matrix_forge/led_matrix/fonts.py +20 -0
  83. is_matrix_forge/led_matrix/hardware.py +172 -0
  84. is_matrix_forge/led_matrix/helpers/__init__.py +165 -0
  85. is_matrix_forge/led_matrix/helpers/core/__init__.py +17 -0
  86. is_matrix_forge/led_matrix/helpers/core/lazy_mod_load.py +84 -0
  87. is_matrix_forge/led_matrix/helpers/device.py +118 -0
  88. is_matrix_forge/led_matrix/helpers/status_handler.py +14 -0
  89. is_matrix_forge/led_matrix/helpers/stream/__init__.py +70 -0
  90. is_matrix_forge/led_matrix/helpers/stream/errors.py +17 -0
  91. is_matrix_forge/led_matrix/led_matrix.py +25 -0
  92. is_matrix_forge/led_matrix/status.py +8 -0
  93. is_matrix_forge/led_matrix/tools/__init__.py +8 -0
  94. is_matrix_forge/led_matrix/tools/identify.py +27 -0
  95. is_matrix_forge/led_matrix/utils/__init__.py +41 -0
  96. is_matrix_forge/log_engine.py +25 -0
  97. is_matrix_forge/monitor/__init__.py +68 -0
  98. is_matrix_forge/monitor/errors.py +35 -0
  99. is_matrix_forge/monitor/events.py +78 -0
  100. is_matrix_forge/monitor/gui/__init__.py +0 -0
  101. is_matrix_forge/monitor/gui/errors.py +35 -0
  102. is_matrix_forge/monitor/gui/event/__init__.py +8 -0
  103. is_matrix_forge/monitor/gui/event/collection.py +153 -0
  104. is_matrix_forge/monitor/gui/event/errors.py +58 -0
  105. is_matrix_forge/monitor/gui/event/event.py +226 -0
  106. is_matrix_forge/monitor/gui/layout/__init__.py +8 -0
  107. is_matrix_forge/monitor/gui/layout/base.py +147 -0
  108. is_matrix_forge/monitor/gui/metaclasses/__init__.py +20 -0
  109. is_matrix_forge/monitor/gui/windows/__init__.py +0 -0
  110. is_matrix_forge/monitor/gui/windows/base.py +325 -0
  111. is_matrix_forge/monitor/gui/windows/main/__init__.py +77 -0
  112. is_matrix_forge/monitor/gui/windows/main/layout.py +21 -0
  113. is_matrix_forge/monitor/helpers.py +55 -0
  114. is_matrix_forge/monitor/monitor.py +431 -0
  115. is_matrix_forge/notify/__init__.py +0 -0
  116. is_matrix_forge/notify/sounds/__init__.py +6 -0
  117. is_matrix_forge/notify/sounds/base.py +106 -0
  118. is_matrix_forge/progress.py +99 -0
  119. is_matrix_forge-1.0.0.dev1.dist-info/LICENSE.md +19 -0
  120. is_matrix_forge-1.0.0.dev1.dist-info/METADATA +190 -0
  121. is_matrix_forge-1.0.0.dev1.dist-info/RECORD +123 -0
  122. is_matrix_forge-1.0.0.dev1.dist-info/WHEEL +4 -0
  123. is_matrix_forge-1.0.0.dev1.dist-info/entry_points.txt +5 -0
@@ -0,0 +1,118 @@
1
+ """
2
+ Device helper functions for LED matrix hardware.
3
+
4
+ This module provides utility functions for working with LED matrix devices,
5
+ including functions to convert between different device location formats.
6
+ """
7
+ from serial import Serial, SerialException
8
+ from serial.tools import list_ports
9
+ from is_matrix_forge.log_engine import ROOT_LOGGER
10
+
11
+
12
+ MOD_LOGGER = ROOT_LOGGER.get_child('led_matrix.helpers.device')
13
+
14
+
15
+ def serial_loc_to_physical(dev):
16
+ """
17
+ Convert the serial location of a device to its physical location.
18
+
19
+ Parameters:
20
+ dev (ListPortInfo):
21
+ The device to convert.
22
+
23
+ Returns:
24
+ str:
25
+ The physical location of the device.
26
+ """
27
+ return dev.device
28
+
29
+
30
+ def device_available(device):
31
+ """
32
+ Check if a device is available.
33
+
34
+ Parameters:
35
+ device:
36
+ The device to check.
37
+
38
+ Returns:
39
+ bool:
40
+ True if the device is available, False otherwise.
41
+
42
+ """
43
+ log = MOD_LOGGER.get_child('device_available')
44
+ log.debug(f'Checking if device is available: {device}...')
45
+
46
+ if not check_device(device):
47
+ log.warning(f'Device {device} failed check, thus not available.')
48
+ return False
49
+ else:
50
+ log.debug(f'Device {device} is available.')
51
+ return True
52
+
53
+
54
+ def check_device(device):
55
+
56
+ from serial.tools.list_ports_common import ListPortInfo
57
+
58
+ log = MOD_LOGGER.get_child('check_device')
59
+ log.debug(f'Checking device: {device}...')
60
+
61
+ if not isinstance(device, ListPortInfo):
62
+ emsg = f'device must be of type `ListPortInfo`, not {type(device)}'
63
+ log.error(emsg)
64
+ raise TypeError(emsg)
65
+
66
+ # Both the vendor and product ID must match to be supported
67
+ if device.vid != EXPECTED_VID or device.pid != EXPECTED_PID:
68
+ log.warning(
69
+ f'Given device is not supported. (VID: {device.vid}, PID: {device.pid})'
70
+ )
71
+ return False
72
+
73
+ return bool(test_connection(device.device))
74
+
75
+
76
+ def get_devices():
77
+ log = MOD_LOGGER.get_child('get_devices')
78
+
79
+ log.debug('Getting devices...')
80
+
81
+ ports = list_ports.comports()
82
+
83
+ log.debug(f'Found {len(ports)} devices.')
84
+ log.debug('Filtering and returning devices...')
85
+ return [
86
+ port for port in ports if port.vid == 0x32AC and port.pid == 0x20
87
+ ]
88
+
89
+
90
+ def test_connection(port_name):
91
+ """
92
+ Test the connection to a given port.
93
+
94
+ Parameters:
95
+ port_name (str):
96
+ The name of the port to test the: connection to.
97
+
98
+ Returns:
99
+
100
+ """
101
+ log = MOD_LOGGER.get_child('test_connection')
102
+ log.debug(f'Testing connection to {port_name}...')
103
+
104
+ try:
105
+ with Serial(port_name, 115200) as s:
106
+ s.write(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
107
+ s.flush()
108
+ log.debug('Connection test successful.')
109
+ return True
110
+ except SerialException:
111
+ log.debug('Connection test failed.')
112
+ return False
113
+
114
+
115
+ DEVICES = get_devices()
116
+
117
+ if len(DEVICES) == 0:
118
+ MOD_LOGGER.warning('No devices found. Please connect a device and try again.')
@@ -0,0 +1,14 @@
1
+ # led_matrix_lib/status_handler.py
2
+
3
+
4
+ _status = None
5
+
6
+
7
+ def set_status(new_status):
8
+
9
+ global _status
10
+ _status = new_status
11
+
12
+
13
+ def get_status():
14
+ return _status
@@ -0,0 +1,70 @@
1
+ import cv2
2
+ from serial import Serial, SerialException
3
+
4
+ from is_matrix_forge.led_matrix.constants import *
5
+ from is_matrix_forge.led_matrix.helpers.status_handler import get_status
6
+ from is_matrix_forge.led_matrix import send_col
7
+
8
+ from .errors import *
9
+ from ...errors.matrix import MatrixConnectionError, MatrixInUseError
10
+
11
+
12
+ def play_stream(dev, capture, mode: str) -> None:
13
+ """
14
+ Core routine for piping frames to the LED matrix via serial.
15
+
16
+ Parameters:
17
+ dev (`serial.tools.list_ports_common.ListPortInfo`):
18
+ The serial port descriptor returned by `serial.tools.list_ports`.
19
+
20
+ capture (`cv2.VideoCapture`):
21
+ An already-opened OpenCV capture object.
22
+
23
+ mode ({'camera', 'video'}):
24
+ Identifies the status flag and grayscale conversion table entry.
25
+
26
+ Returns:
27
+ None
28
+
29
+ Raises:
30
+ RuntimeError:
31
+ If the serial port is not open.
32
+ """
33
+ try:
34
+ with Serial(dev.device, DEFAULT_BAUDRATE) as s:
35
+
36
+ ok, first_frame = capture.read()
37
+
38
+ if not ok:
39
+ raise StreamSourceUnreadableError()
40
+ except SerialException as e:
41
+ raise MatrixInUseError from e
42
+
43
+ # ── Calculate scaling and crop once based on the first frame ───────
44
+ scale_y = HEIGHT / first_frame.shape[0]
45
+ scaled_w = int(round(first_frame.shape[1] * scale_y))
46
+ start_x = max(0, int(round(scaled_w / 2 - WIDTH / 2)))
47
+ end_x = min(scaled_w, start_x + WIDTH)
48
+ dim = (HEIGHT, scaled_w)
49
+
50
+ # ── Main pump loop ────────────────────────────────────────────────
51
+ while get_status() == mode:
52
+ ok, frame = capture.read()
53
+ if not ok:
54
+ break
55
+
56
+ gray = cv2.cvtColor(frame, __GRAYSCALE_CVT[mode])
57
+ resized = cv2.resize(gray, dim)
58
+ cropped = resized[0:HEIGHT, start_x:end_x]
59
+
60
+ # Stream one column at a time
61
+ for x in range(cropped.shape[1]):
62
+ send_col(
63
+ dev,
64
+ s,
65
+ x,
66
+ [cropped[y, x] for y in range(HEIGHT)]
67
+ )
68
+ commit_cols(dev, s)
69
+
70
+ capture.release()
@@ -0,0 +1,17 @@
1
+ from inspyre_toolbox.exceptional import CustomRootException
2
+
3
+
4
+ class MatrixStreamError(CustomRootException):
5
+ default_message= 'An error occurred while streaming to the LED matrix!'
6
+
7
+ def __init__(self, message=None):
8
+ if message is None:
9
+ message = self.default_message
10
+ else:
11
+ message = f'{self.default_message}\n\n Additional Info:\n{" " * 4}{message}'
12
+ super().__init__(message)
13
+
14
+
15
+ class StreamSourceUnreadableError(MatrixStreamError):
16
+ def __init__(self):
17
+ super().__init__('The source is not readable.')
@@ -0,0 +1,25 @@
1
+ """
2
+ LED Matrix Module.
3
+
4
+ This module provides a high-level interface for interacting with LED matrix devices.
5
+ It combines functionality from various modules to provide a simple API for controlling
6
+ LED matrices, displaying patterns, animations, and battery status.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ # Standard library
12
+ from pathlib import Path
13
+ from typing import Optional, Union, List
14
+
15
+ # Third-party
16
+ from serial.tools.list_ports_common import ListPortInfo
17
+
18
+ # Inspyre-Softworks
19
+ from is_matrix_forge.led_matrix.display.grid import Grid, generate_blank_grid
20
+ from is_matrix_forge.led_matrix.display.animations import goodbye_animation
21
+ from is_matrix_forge.led_matrix.helpers.device import get_devices
22
+ from is_matrix_forge.common.helpers import percentage_to_value
23
+
24
+
25
+
@@ -0,0 +1,8 @@
1
+ """
2
+ Author: Taylor B. tayjaybabee@gmail.com
3
+ Date: 2025-05-09 23:20:37
4
+ LastEditors: Taylor B. tayjaybabee@gmail.com
5
+ LastEditTime: 2025-05-09 23:24:58
6
+ FilePath: is_matrix_forge/led_matrix/status.py
7
+ Description: 这是默认设置,可以在设置》工具》File Description中进行配置
8
+ """
@@ -0,0 +1,8 @@
1
+ """
2
+ Author: Taylor B. tayjaybabee@gmail.com
3
+ Date: 2025-05-12 22:17:04
4
+ LastEditors: Taylor B. tayjaybabee@gmail.com
5
+ LastEditTime: 2025-05-12 22:17:28
6
+ FilePath: is_matrix_forge/led_matrix/tools/__init__.py
7
+ Description: 这是默认设置,可以在设置》工具》File Description中进行配置
8
+ """
@@ -0,0 +1,27 @@
1
+ from is_matrix_forge.led_matrix import LEDMatrixController
2
+ from is_matrix_forge.led_matrix.helpers.device import DEVICES
3
+ from threading import Thread
4
+
5
+
6
+ threads = []
7
+
8
+
9
+ def identify_devices(devices=None):
10
+ global threads
11
+
12
+ if devices is None:
13
+ devices = DEVICES
14
+
15
+ controllers = []
16
+
17
+ for device in devices:
18
+ controllers.append(LEDMatrixController(device, 100))
19
+
20
+ for controller in controllers:
21
+ t = Thread(target=controller.identify)
22
+ threads.append(t)
23
+ t.start()
24
+
25
+
26
+ if __name__ == "__main__":
27
+ identify_devices()
@@ -0,0 +1,41 @@
1
+ """
2
+
3
+
4
+ Author:
5
+ Inspyre Softworks
6
+
7
+ Project:
8
+ led-matrix-battery
9
+
10
+ File:
11
+ is_matrix_forge/led_matrix/utils/__init__.py
12
+
13
+
14
+ Description:
15
+
16
+
17
+ """
18
+ import serial
19
+
20
+ from is_matrix_forge.led_matrix import RESPONSE_SIZE, disconnect_dev, FWK_MAGIC
21
+
22
+
23
+ def send_command_raw(dev, command, with_response=False):
24
+ """Send a command to the device.
25
+ Opens new serial connection every time"""
26
+ # print(f"Sending command: {command}")
27
+ try:
28
+ with serial.Serial(dev.device, 115200) as s:
29
+ s.write(command)
30
+
31
+ if with_response:
32
+ res = s.read(RESPONSE_SIZE)
33
+ # print(f"Received: {res}")
34
+ return res
35
+ except (IOError, OSError) as _ex:
36
+ disconnect_dev(dev.device)
37
+ # print("Error: ", ex)
38
+
39
+
40
+ def send_command(dev, command, parameters=[], with_response=False):
41
+ return send_command_raw(dev, FWK_MAGIC + [command] + parameters, with_response)
@@ -0,0 +1,25 @@
1
+ from inspy_logger import InspyLogger, Loggable
2
+ from inspy_logger.constants import LEVEL_MAP
3
+
4
+
5
+ LOG_LEVELS = [level for level in LEVEL_MAP.keys()]
6
+
7
+ del LEVEL_MAP
8
+
9
+ PROGNAME = 'LEDMatrixBattery'
10
+ AUTHOR = 'Inspyre-Softworks'
11
+
12
+ INSPY_LOG_LEVEL = 'INFO'
13
+
14
+ ROOT_LOGGER = InspyLogger(PROGNAME, console_level='info', no_file_logging=True)
15
+
16
+
17
+ __all__ = [
18
+ 'AUTHOR',
19
+ 'INSPY_LOG_LEVEL',
20
+ 'Loggable',
21
+ 'LOG_LEVELS',
22
+ 'PROGNAME',
23
+ 'ROOT_LOGGER',
24
+ ]
25
+
@@ -0,0 +1,68 @@
1
+ """
2
+ File: monitor.py
3
+ Author: Inspyre-Softworks
4
+ Description:
5
+ This file contains the PowerMonitor class, which is used to monitor the battery level of the system.
6
+ """
7
+ # Standard library imports
8
+ from pathlib import Path
9
+ from threading import Thread
10
+ from typing import Union, Optional
11
+
12
+ # Third-party imports
13
+ from serial.tools.list_ports_common import ListPortInfo
14
+
15
+ # Inspyre-Softworks imports
16
+ from easy_exit_calls import ExitCallHandler
17
+
18
+ # Package imports
19
+ from .errors import *
20
+ from .helpers import get_plugged_status
21
+ from is_matrix_forge.log_engine import ROOT_LOGGER as PARENT_LOGGER
22
+ from is_matrix_forge.notify.sounds import PLUGGED_NOTIFY, UNPLUGGED_NOTIFY
23
+
24
+
25
+ DEFAULT_PLUGGED_SOUND = PLUGGED_NOTIFY
26
+ DEFAULT_UNPLUGGED_SOUND = UNPLUGGED_NOTIFY
27
+
28
+ ECH = ExitCallHandler()
29
+
30
+ MOD_LOGGER = PARENT_LOGGER.get_child('monitor')
31
+
32
+
33
+ def run_power_monitor(
34
+ device: ListPortInfo,
35
+ battery_check_interval: int = 5,
36
+ plugged_alert: Optional[Union[str, Path]] = DEFAULT_PLUGGED_SOUND,
37
+ unplugged_alert: Optional[Union[str, Path]] = DEFAULT_UNPLUGGED_SOUND,
38
+ ):
39
+ """
40
+ Run the power monitor.
41
+
42
+ Parameters:
43
+ device (ListPortInfo):
44
+ The LED matrix on which to display the battery level.
45
+
46
+ battery_check_interval (Optional[Union[int, float, str]]):
47
+ The interval (in seconds) at which to check the battery level.
48
+
49
+ plugged_alert (Optional[Union[str, Path]]):
50
+ The filepath to the sound to play when the device is plugged into power.
51
+
52
+ unplugged_alert (Optional[Union[str, Path]]):
53
+ The filepath to the sound to play when the device is unplugged from power.
54
+
55
+ """
56
+ monitor = PowerMonitor(
57
+ device,
58
+ battery_check_interval=battery_check_interval,
59
+ plugged_alert=plugged_alert,
60
+ unplugged_alert=unplugged_alert
61
+ )
62
+
63
+ try:
64
+ monitor.start()
65
+ except KeyboardInterrupt:
66
+ monitor.stop(without_salutation=True)
67
+
68
+ return monitor
@@ -0,0 +1,35 @@
1
+ from inspyre_toolbox.exceptional import CustomRootException
2
+
3
+
4
+ class PowerMonitorError(CustomRootException):
5
+ """
6
+ Base class for all PowerMonitor errors.
7
+
8
+ Class Attributes:
9
+ default_message (str): Read-Only. The default message for the error.
10
+ """
11
+ default_message = 'An error occurred while monitoring the battery!'
12
+
13
+
14
+ class PowerMonitorNotRunningError(PowerMonitorError):
15
+ """
16
+ Raised when a method is called on a PowerMonitor instance that is not running, but should be to perform the action.
17
+ """
18
+ def __init__(self, message = None):
19
+ msg = 'The PowerMonitor is not running, can not perform action on a non-running instance!'
20
+ if message is not None:
21
+ msg += f'\n\nAdditional information from caller: {message}'
22
+
23
+ super().__init__(msg)
24
+
25
+
26
+ class BatteryStateUnknownError(PowerMonitorError):
27
+ """
28
+ Raised when the state of the battery cannot be determined.
29
+ """
30
+ def __init__(self, message = None):
31
+ msg = 'The state of the battery cannot be determined!'
32
+ if message is not None:
33
+ msg += f'\n\nAdditional information from caller: {message}'
34
+
35
+ super().__init__(msg)
@@ -0,0 +1,78 @@
1
+ from is_matrix_forge.log_engine import ROOT_LOGGER
2
+ from is_matrix_forge.monitor.monitor import PowerMonitor
3
+ from is_matrix_forge.monitor.helpers import get_battery_percentage
4
+
5
+ MOD_LOGGER = ROOT_LOGGER.get_child('monitor.events')
6
+
7
+
8
+ def event_to_bool(event: str) -> bool:
9
+ """
10
+ Converts an event to a boolean.
11
+
12
+ Parameters:
13
+ event:
14
+ The string representation of the event to convert.
15
+
16
+ Returns:
17
+ bool:
18
+ The converted boolean value.
19
+
20
+ Raises:
21
+ ValueError:
22
+ If the event is not a valid boolean value.
23
+
24
+ Examples:
25
+ >>> event_to_bool('true')
26
+ True
27
+ >>> event_to_bool('false')
28
+ False
29
+ >>> event_to_bool('invalid')
30
+ Traceback (most recent call last):
31
+ ...
32
+ ValueError: invalid is not a valid boolean value.
33
+ """
34
+ event = event.lower().strip()
35
+
36
+ if event in ['on', 'true', 'plugged']:
37
+ return True
38
+ elif event in ['off', 'false', 'unplugged']:
39
+ return False
40
+ else:
41
+ raise ValueError(f'{event} is not a valid boolean value.')
42
+
43
+
44
+ def __handle_device_plugged_in(power_monitor):
45
+ pm = power_monitor
46
+ if pm.plugged_in and not pm.controller.is_animating and (not pm.last_state or pm.last_state is None):
47
+ pm.notify('plugged')
48
+ pm.controller.clear()
49
+ pm._last_state = True
50
+
51
+
52
+ def __handle_device_unplugged(power_monitor):
53
+ pm = power_monitor
54
+ if pm.unplugged and not pm.controller.is_animating and (pm.last_state or pm.last_state is None):
55
+ pm.notify('unplugged')
56
+ pm.controller.clear()
57
+ pm._last_state = False
58
+
59
+ pm.controller.draw_percentage(get_battery_percentage())
60
+
61
+
62
+ def handle_event(event: str, power_monitor: PowerMonitor):
63
+ log = MOD_LOGGER.get_child('handle_event')
64
+ log.debug(f'Handling {event}...')
65
+
66
+ #if not isinstance(power_monitor, PowerMonitor):
67
+ # raise TypeError(f'{power_monitor} is not a PowerMonitor instance.')
68
+ #else:
69
+ # log.debug(f'{power_monitor} is a PowerMonitor instance.')
70
+
71
+ event = event_to_bool(event)
72
+
73
+ pm = power_monitor
74
+
75
+ if event:
76
+ __handle_device_plugged_in(pm)
77
+ else:
78
+ __handle_device_unplugged(pm)
File without changes
@@ -0,0 +1,35 @@
1
+ from inspyre_toolbox.exceptional import CustomRootException
2
+
3
+
4
+ class PowerMonitorGUIError(CustomRootException):
5
+ """
6
+ Base class for all PowerMonitor GUI errors.
7
+
8
+ Class Attributes:
9
+ default_message (str): Read-Only. The default message for the error.
10
+ """
11
+ default_message = 'An error occurred with the PowerMonitor GUI!'
12
+
13
+
14
+ class MalformedWindowError(PowerMonitorGUIError):
15
+ """
16
+ Raised when a window is malformed or not properly initialized.
17
+
18
+ Class Attributes:
19
+ default_message (str): Read-Only. The default message for the error.
20
+ """
21
+ default_message = 'Window is malformed or not properly initialized!'
22
+
23
+ def __init__(self, message: str = None, **kwargs) -> None:
24
+ """
25
+ Initializes the MalformedWindowError.
26
+
27
+ Parameters:
28
+ message (Optional[str]):
29
+ The error message to be displayed. If None, uses the default message.
30
+ """
31
+ if message is not None:
32
+ self.default_message = f"{self.default_message}\n\n Additional information from caller:\n {message}"
33
+
34
+ super().__init__(message=self.default_message, **kwargs)
35
+
@@ -0,0 +1,8 @@
1
+ from .event import Event
2
+ from .collection import EventCollection
3
+
4
+
5
+ __all__ = [
6
+ 'Event',
7
+ 'EventCollection'
8
+ ]