TISControlProtocol 1.0.68__tar.gz → 1.0.70__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 (73) hide show
  1. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/PKG-INFO +1 -1
  2. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/pyproject.toml +1 -1
  3. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/api.py +28 -9
  4. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/__init__.py +2 -0
  5. tiscontrolprotocol-1.0.70/src/TISControlProtocol/apis/toggle_connection_endpoint.py +52 -0
  6. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/display.py +51 -24
  7. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/.gitignore +0 -0
  8. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/.vscode/c_cpp_properties.json +0 -0
  9. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/.vscode/launch.json +0 -0
  10. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/.vscode/settings.json +0 -0
  11. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/.vscode/tasks.json +0 -0
  12. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/LICENSE +0 -0
  13. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/MANIFEST.in +0 -0
  14. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/README.md +0 -0
  15. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/dev/pump_version.py +0 -0
  16. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/BytesHelper.py +0 -0
  17. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/__init__.py +0 -0
  18. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/AckCoordinator.py +0 -0
  19. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketDispatcher.py +0 -0
  20. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketExtractor.py +0 -0
  21. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/AnalogFeedbackHandler.py +0 -0
  22. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/AutoBinaryFeedbackHandler.py +0 -0
  23. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/BinaryFeedbackHandler.py +0 -0
  24. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/ClimateBinaryFeedbackHandler.py +0 -0
  25. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/ClimateControlFeedbackHandler.py +0 -0
  26. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/ControlResponseHandler.py +0 -0
  27. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/DiscoveryFeedbackHandler.py +0 -0
  28. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/EnergyFeedbackHandler.py +0 -0
  29. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/FloorBinaryFeedbackHandler.py +0 -0
  30. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/HealthFeedbackHandler.py +0 -0
  31. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/LunaTempFeedbackHandler.py +0 -0
  32. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/RealTimeFeedbackHandler.py +0 -0
  33. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/SearchResponseHandler.py +0 -0
  34. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/SecurityFeedbackHandler.py +0 -0
  35. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/UpdateResponseHandler.py +0 -0
  36. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/UpdateSecurityHandler.py +0 -0
  37. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/WeatherFeedbackHandler.py +0 -0
  38. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketHandlers/__init__.py +0 -0
  39. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketProtocol.py +0 -0
  40. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketReceiver.py +0 -0
  41. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/PacketSender.py +0 -0
  42. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/ProtocolHandler.py +0 -0
  43. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/UpdateCoordinator.py +0 -0
  44. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/Protocols/udp/__init__.py +0 -0
  45. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/__init__.py +0 -0
  46. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/bill_config_endpoint.py +0 -0
  47. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/change_password_endpoint.py +0 -0
  48. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/get_bill_config_endpoint.py +0 -0
  49. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/get_key_endpoint.py +0 -0
  50. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/password_dashboard.py +0 -0
  51. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/password_form_endpoint.py +0 -0
  52. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/passwords_endpoint.py +0 -0
  53. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/restart_endpoint.py +0 -0
  54. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/scan_devices_endpoint.py +0 -0
  55. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/shared.py +0 -0
  56. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/submit_password.py +0 -0
  57. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/tis_endpoint.py +0 -0
  58. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/apis/update_endpoint.py +0 -0
  59. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/crc.py +0 -0
  60. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/logo.png +0 -0
  61. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/package-lock.json +0 -0
  62. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/package.json +0 -0
  63. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/postcss.config.mjs +0 -0
  64. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/public/__init__.py +0 -0
  65. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/public/dashboard.css +0 -0
  66. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/public/password_dashboard_loader.js +0 -0
  67. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/shared.py +0 -0
  68. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/views/__init__.py +0 -0
  69. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/views/password_dashboard/index.html +0 -0
  70. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/views/password_dashboard/styles.css +0 -0
  71. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/views/password_form/index.html +0 -0
  72. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/src/TISControlProtocol/views/password_form/styles.css +0 -0
  73. {tiscontrolprotocol-1.0.68 → tiscontrolprotocol-1.0.70}/tests/test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: TISControlProtocol
3
- Version: 1.0.68
3
+ Version: 1.0.70
4
4
  Summary: A library for TIS Control Protocol
5
5
  Project-URL: Homepage, https://github.com/TISControlHass
6
6
  Project-URL: Issues, https://github.com/TISControlHass/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "TISControlProtocol"
7
- version = "1.0.68"
7
+ version = "1.0.70"
8
8
  description = "A library for TIS Control Protocol"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -19,6 +19,7 @@ from TISControlProtocol.shared import get_real_mac
19
19
  from .apis import (
20
20
  BillConfigEndpoint,
21
21
  ChangeSecurityPassEndpoint,
22
+ ToggleConnectionEndpoint,
22
23
  GetBillConfigEndpoint,
23
24
  GetKeyEndpoint,
24
25
  PasswordsEndpoint,
@@ -47,8 +48,10 @@ class TISApi:
47
48
  """Initialize the API class."""
48
49
  self.host = host
49
50
  self.port = port
51
+ self.loop = None
50
52
  self.protocol = None
51
53
  self.transport = None
54
+ self.sock = None
52
55
  self.hass = hass
53
56
  self.config_entries = {}
54
57
  self.bill_configs = {}
@@ -60,20 +63,35 @@ class TISApi:
60
63
  self.cms_url = "https://cms-tis.com"
61
64
  self._cms_task_unsub = None
62
65
 
66
+ async def setup(self):
67
+ """Setup the TIS API."""
68
+ try:
69
+ await self.connect()
70
+ await self._initialize_hass_data()
71
+ await self._register_http_views()
72
+ self.hass.async_add_executor_job(self.run_display)
73
+ except Exception as e:
74
+ logging.error("Error during setup: %s", e)
75
+
63
76
  async def connect(self):
64
77
  """Connect to the TIS API."""
65
78
  self.loop = self.hass.loop
66
79
  self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
80
+
67
81
  try:
68
82
  await self._setup_udp_protocol()
69
- await self._initialize_hass_data()
70
- await self._register_http_views()
71
- self.hass.async_add_executor_job(self.run_display)
72
- # self._register_services()
73
- # self._schedule_cms_data_task()
74
- except Exception as e:
75
- logging.error("Error during connection setup: %s", e)
76
- raise ConnectionError
83
+ except Exception:
84
+ self.sock.close()
85
+ raise
86
+
87
+ async def disconnect(self):
88
+ """Disconnect from the TIS API."""
89
+ if self.transport:
90
+ self.transport.close()
91
+ self.transport = None
92
+ if hasattr(self, "sock") and self.sock:
93
+ self.sock.close()
94
+ self.sock = None
77
95
 
78
96
  async def _setup_udp_protocol(self):
79
97
  """Setup the UDP protocol."""
@@ -107,6 +125,7 @@ class TISApi:
107
125
  self.hass.http.register_view(BillConfigEndpoint(self))
108
126
  self.hass.http.register_view(GetBillConfigEndpoint(self))
109
127
  self.hass.http.register_view(PasswordsEndpoint(self))
128
+ self.hass.http.register_view(ToggleConnectionEndpoint(self))
110
129
  except Exception as e:
111
130
  logging.error("Error registering views %s", e)
112
131
  raise ConnectionError
@@ -209,7 +228,7 @@ class TISApi:
209
228
 
210
229
  if self.display is None:
211
230
  self.display = TISDisplay(self.display_logo, self.version)
212
-
231
+
213
232
  self.display.run_display()
214
233
 
215
234
  async def parse_device_manager_request(self, data: dict) -> None:
@@ -16,6 +16,7 @@ from .password_form_endpoint import PasswordFormEndpoint
16
16
  from .submit_password import SubmitPasswordEndpoint
17
17
  from .password_dashboard import PasswordDashboardEndpoint
18
18
  from .passwords_endpoint import PasswordsEndpoint
19
+ from .toggle_connection_endpoint import ToggleConnectionEndpoint
19
20
 
20
21
 
21
22
  __all__ = [
@@ -29,6 +30,7 @@ __all__ = [
29
30
  "GetBillConfigEndpoint",
30
31
  "SubmitPasswordEndpoint",
31
32
  "PasswordsEndpoint",
33
+ "ToggleConnectionEndpoint",
32
34
  ]
33
35
 
34
36
 
@@ -0,0 +1,52 @@
1
+ from homeassistant.components.http import HomeAssistantView
2
+ from aiohttp import web
3
+ from TISControlProtocol.shared import get_real_mac
4
+ import logging
5
+
6
+
7
+ class ToggleConnectionEndpoint(HomeAssistantView):
8
+ """Connect or Disconnect the TIS API"""
9
+
10
+ url = "/api/toggle-connection"
11
+ name = "api:toggle-connection"
12
+ requires_auth = False
13
+
14
+ def __init__(self, tis_api):
15
+ self.tis_api = tis_api
16
+
17
+ async def post(self, request):
18
+ mac_address = request.query.get("mac_address")
19
+
20
+ if mac_address is None:
21
+ logging.info("Required parameters not found in query, parsing request body")
22
+ try:
23
+ data = await request.json()
24
+ mac_address = data.get("mac_address")
25
+ except Exception:
26
+ pass
27
+
28
+ mac = await get_real_mac("end0")
29
+
30
+ if mac_address is None:
31
+ return web.json_response(
32
+ {"error": "required parameters are missing"}, status=400
33
+ )
34
+ elif mac_address != mac:
35
+ return web.json_response({"error": "Unauthorized"}, status=403)
36
+
37
+ if self.tis_api.transport:
38
+ logging.info("Disconnecting from TIS API")
39
+ try:
40
+ await self.tis_api.disconnect()
41
+ return web.json_response({"message": "Disconnected"}, status=200)
42
+ except Exception as e:
43
+ logging.error(f"Error disconnecting: {e}")
44
+ return web.json_response({"error": "Failed to disconnect"}, status=500)
45
+ else:
46
+ logging.info("Connecting to TIS API")
47
+ try:
48
+ await self.tis_api.connect()
49
+ return web.json_response({"message": "Connected"}, status=200)
50
+ except Exception as e:
51
+ logging.error(f"Error connecting: {e}")
52
+ return web.json_response({"error": "Failed to connect"}, status=500)
@@ -17,6 +17,7 @@ except (ImportError, RuntimeError) as e:
17
17
  "Failed to load display dependencies. Display will be disabled. Error: %s", e
18
18
  )
19
19
 
20
+
20
21
  class TISDisplay:
21
22
  def __init__(self, display_logo: str, version: str):
22
23
  self.display_logo = display_logo
@@ -39,11 +40,11 @@ class TISDisplay:
39
40
  logging.error(f"Error setting pin {pin} to {value}: {e}")
40
41
 
41
42
  def send_command(self, cmd):
42
- self._set_pin(23, 0) # Command mode (0)
43
+ self._set_pin(23, 0) # Command mode (0)
43
44
  os.write(self.spi_fd, bytes([cmd]))
44
45
 
45
46
  def send_data(self, data):
46
- self._set_pin(23, 1) # Data mode (1)
47
+ self._set_pin(23, 1) # Data mode (1)
47
48
  if isinstance(data, int):
48
49
  os.write(self.spi_fd, bytes([data]))
49
50
  else:
@@ -59,30 +60,30 @@ class TISDisplay:
59
60
  time.sleep(0.1)
60
61
 
61
62
  # ST7789 Initialization Sequence
62
- self.send_command(0x01) # SWRESET
63
+ self.send_command(0x01) # SWRESET
63
64
  time.sleep(0.15)
64
- self.send_command(0x11) # Sleep out
65
+ self.send_command(0x11) # Sleep out
65
66
  time.sleep(0.15)
66
67
 
67
- self.send_command(0x3A) # Color mode 16-bit
68
- self.send_data(0x55) # 0x55 for RGB565
68
+ self.send_command(0x3A) # Color mode 16-bit
69
+ self.send_data(0x55) # 0x55 for RGB565
69
70
 
70
- self.send_command(0x36) # Memory Access Control (MADCTL)
71
- self.send_data(0x00) # Normal rotation
71
+ self.send_command(0x36) # Memory Access Control (MADCTL)
72
+ self.send_data(0x00) # Normal rotation
72
73
 
73
- self.send_command(0x21) # INVON
74
- self.send_command(0x13) # NORON
74
+ self.send_command(0x21) # INVON
75
+ self.send_command(0x13) # NORON
75
76
  time.sleep(0.01)
76
- self.send_command(0x29) # Display on
77
+ self.send_command(0x29) # Display on
77
78
  time.sleep(0.1)
78
79
 
79
80
  def set_window(self, x1, y1, x2, y2):
80
- self.send_command(0x2A) # Column Address Set
81
+ self.send_command(0x2A) # Column Address Set
81
82
  self.send_data(bytearray([x1 >> 8, x1 & 0xFF, x2 >> 8, x2 & 0xFF]))
82
83
 
83
- self.send_command(0x2B) # Row Address Set
84
+ self.send_command(0x2B) # Row Address Set
84
85
  self.send_data(bytearray([y1 >> 8, y1 & 0xFF, y2 >> 8, y2 & 0xFF]))
85
- self.send_command(0x2C) # RAMWR
86
+ self.send_command(0x2C) # RAMWR
86
87
 
87
88
  def set_display_image(self):
88
89
  if self.display_logo:
@@ -94,27 +95,43 @@ class TISDisplay:
94
95
  font = ImageFont.load_default(size=28)
95
96
  except TypeError:
96
97
  font = ImageFont.load_default()
97
-
98
+
98
99
  x, y = 78, 235
99
100
  draw.text((x, y), version_text, font=font, fill=(255, 255, 255))
100
- img = img.rotate(-90, expand=True)
101
+ img = img.rotate(180, expand=True)
101
102
 
102
103
  if img.size != (240, 320):
103
104
  img = img.resize((240, 320))
104
105
 
105
106
  r, g, b = img.split()
106
- r_data = list(r.getdata()) if not hasattr(r, "get_flattened_data") else r.get_flattened_data()
107
- g_data = list(g.getdata()) if not hasattr(g, "get_flattened_data") else g.get_flattened_data()
108
- b_data = list(b.getdata()) if not hasattr(b, "get_flattened_data") else b.get_flattened_data()
107
+ r_data = (
108
+ list(r.getdata())
109
+ if not hasattr(r, "get_flattened_data")
110
+ else r.get_flattened_data()
111
+ )
112
+ g_data = (
113
+ list(g.getdata())
114
+ if not hasattr(g, "get_flattened_data")
115
+ else g.get_flattened_data()
116
+ )
117
+ b_data = (
118
+ list(b.getdata())
119
+ if not hasattr(b, "get_flattened_data")
120
+ else b.get_flattened_data()
121
+ )
109
122
 
110
123
  rgb565 = bytearray(img.width * img.height * 2)
111
124
  for i in range(len(r_data)):
112
- pixel = (((r_data[i] & 0xF8) << 8) | ((g_data[i] & 0xFC) << 3) | (b_data[i] >> 3))
125
+ pixel = (
126
+ ((r_data[i] & 0xF8) << 8)
127
+ | ((g_data[i] & 0xFC) << 3)
128
+ | (b_data[i] >> 3)
129
+ )
113
130
  rgb565[i * 2] = pixel >> 8
114
131
  rgb565[i * 2 + 1] = pixel & 0xFF
115
132
 
116
133
  self.set_window(0, 0, img.width - 1, img.height - 1)
117
- self._set_pin(23, 1) # Data mode
134
+ self._set_pin(23, 1) # Data mode
118
135
 
119
136
  mv = memoryview(rgb565)
120
137
  chunk_size = 4096
@@ -129,7 +146,9 @@ class TISDisplay:
129
146
  SPI_IOC_WR_MODE = 0x40016B01
130
147
  SPI_IOC_WR_MAX_SPEED_HZ = 0x40046B04
131
148
  fcntl.ioctl(self.spi_fd, SPI_IOC_WR_MODE, struct.pack("B", 0))
132
- fcntl.ioctl(self.spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, struct.pack("I", 10000000))
149
+ fcntl.ioctl(
150
+ self.spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, struct.pack("I", 10000000)
151
+ )
133
152
 
134
153
  # Initialize GPIOs via gpiod dynamically
135
154
  self.chip_path = None
@@ -151,12 +170,20 @@ class TISDisplay:
151
170
  self.req_dc = gpiod.request_lines(
152
171
  self.chip_path,
153
172
  consumer="display_dc",
154
- config={23: gpiod.LineSettings(direction=Direction.OUTPUT, output_value=Value.INACTIVE)}
173
+ config={
174
+ 23: gpiod.LineSettings(
175
+ direction=Direction.OUTPUT, output_value=Value.INACTIVE
176
+ )
177
+ },
155
178
  )
156
179
  self.req_rst = gpiod.request_lines(
157
180
  self.chip_path,
158
181
  consumer="display_rst",
159
- config={25: gpiod.LineSettings(direction=Direction.OUTPUT, output_value=Value.INACTIVE)}
182
+ config={
183
+ 25: gpiod.LineSettings(
184
+ direction=Direction.OUTPUT, output_value=Value.INACTIVE
185
+ )
186
+ },
160
187
  )
161
188
 
162
189
  try: