@@ -84,6 +84,28 @@ async def check_relay_availability(self, fountain_id: int) -> bool:
8484 return False
8585 return True
8686
87+ async def _request_ble_api (
88+ self ,
89+ endpoint : PetkitEndpoint ,
90+ fountain : "WaterFountain" ,
91+ extra_data : dict | None = None ,
92+ ):
93+ """API Bluetooth request method"""
94+ data = {
95+ "bleId" : fountain .id ,
96+ "type" : fountain .device_nfo .type , # type: ignore[union-attr]
97+ "mac" : fountain .mac ,
98+ }
99+ if extra_data :
100+ data .update (extra_data )
101+
102+ return await self .client .req .request (
103+ method = HTTPMethod .POST ,
104+ url = endpoint ,
105+ data = data ,
106+ headers = await self .client .get_session_id (),
107+ )
108+
87109 async def open_ble_connection (self , fountain_id : int ) -> bool :
88110 """Open a BLE connection to the given fountain_id.
89111 :param fountain_id: The ID of the fountain to open the BLE connection for.
@@ -94,51 +116,44 @@ async def open_ble_connection(self, fountain_id: int) -> bool:
94116 if water_fountain .ble_connection_state == BluetoothState .CONNECTED :
95117 _LOGGER .debug ("BLE connection already established (id %s)" , fountain_id )
96118 return True
97- # ToDo : BluetoothState.CONNECTING must be managed
98- water_fountain .ble_connection_state = BluetoothState .NOT_CONNECTED
99- if not await self .check_relay_availability (fountain_id ):
100- _LOGGER .debug ("BLE relay not available (id: %s)." , fountain_id )
101- return False
102- response = await self .client .req .request (
103- method = HTTPMethod .POST ,
104- url = PetkitEndpoint .BLE_CONNECT ,
105- data = {
106- "bleId" : fountain_id ,
107- "type" : water_fountain .device_nfo .type , # type: ignore[union-attr]
108- "mac" : water_fountain .mac ,
109- },
110- headers = await self .client .get_session_id (),
111- )
112- if response != {"state" : 1 }:
113- _LOGGER .debug ("Unable to open a BLE connection (id %s)" , fountain_id )
114- return False
119+
120+ if water_fountain .ble_connection_state == BluetoothState .CONNECTING :
121+ _LOGGER .debug ("BLE connection already in progress (id %s)." , fountain_id )
122+ else :
123+ if not await self .check_relay_availability (fountain_id ):
124+ _LOGGER .debug ("BLE relay not available (id: %s)." , fountain_id )
125+ water_fountain .ble_connection_state = BluetoothState .NOT_CONNECTED
126+ return False
127+
128+ response = await self ._request_ble_api (
129+ PetkitEndpoint .BLE_CONNECT , water_fountain
130+ )
131+ if response != {"state" : 1 }:
132+ _LOGGER .debug ("Unable to open a BLE connection (id %s)" , fountain_id )
133+ water_fountain .ble_connection_state = BluetoothState .NOT_CONNECTED
134+ return False
135+
136+ water_fountain .ble_connection_state = BluetoothState .CONNECTING
137+
115138 for attempt in range (BLE_CONNECT_ATTEMPT ):
116139 _LOGGER .debug (
117- "BLE connection... %s/ %s (id %s)" ,
140+ "BLE connection... attempt: %s (id %s)" ,
118141 attempt ,
119- BLE_CONNECT_ATTEMPT ,
120142 fountain_id ,
121143 )
122- response = await self .client .req .request (
123- method = HTTPMethod .POST ,
124- url = PetkitEndpoint .BLE_POLL ,
125- data = {
126- "bleId" : fountain_id ,
127- "type" : water_fountain .device_nfo .type , # type: ignore[union-attr]
128- "mac" : water_fountain .mac ,
129- },
130- headers = await self .client .get_session_id (),
144+ response = await self ._request_ble_api (
145+ PetkitEndpoint .BLE_POLL , water_fountain
131146 )
132- if response == 0 :
147+ if response == BluetoothState . CONNECTING :
133148 # Wait for 4 seconds before polling again, connection is still in progress
134149 await asyncio .sleep (4 )
135- elif response == - 1 :
150+ elif response == BluetoothState . ERROR :
136151 _LOGGER .debug ("Failed to establish BLE connection (id %s)" , fountain_id )
137152 water_fountain .last_ble_poll = datetime .now ().strftime (
138153 "%Y-%m-%dT%H:%M:%S.%f"
139154 )
140155 return False
141- elif response == 1 :
156+ elif response == BluetoothState . CONNECTED :
142157 _LOGGER .debug (
143158 "BLE connection established successfully (id %s)" , fountain_id
144159 )
@@ -164,20 +179,14 @@ async def close_ble_connection(self, fountain_id: int) -> None:
164179
165180 if water_fountain .ble_connection_state != BluetoothState .CONNECTED :
166181 _LOGGER .debug (
167- "BLE connection not established. Cannot close (id %s)" , fountain_id
182+ "BLE connection not established. Cannot close (id %s) State is=%s" ,
183+ fountain_id ,
184+ water_fountain .ble_connection_state ,
168185 )
169186 return
170187
171- await self .client .req .request (
172- method = HTTPMethod .POST ,
173- url = PetkitEndpoint .BLE_CANCEL ,
174- data = {
175- "bleId" : fountain_id ,
176- "type" : water_fountain .device_nfo .type , # type: ignore[union-attr]
177- "mac" : water_fountain .mac ,
178- },
179- headers = await self .client .get_session_id (),
180- )
188+ await self ._request_ble_api (PetkitEndpoint .BLE_CANCEL , water_fountain )
189+ water_fountain .ble_connection_state = BluetoothState .NOT_CONNECTED
181190 _LOGGER .debug ("BLE connection closed successfully (id %s)" , fountain_id )
182191
183192 async def get_ble_cmd_data (
@@ -229,17 +238,10 @@ async def send_ble_command(self, fountain_id: int, command: FountainAction) -> b
229238 cmd_code , cmd_data = await self .get_ble_cmd_data (
230239 list (command_data ), water_fountain .ble_counter
231240 )
232- response = await self .client .req .request (
233- method = HTTPMethod .POST ,
234- url = PetkitEndpoint .BLE_CONTROL_DEVICE ,
235- data = {
236- "bleId" : water_fountain .id ,
237- "cmd" : cmd_code ,
238- "data" : cmd_data ,
239- "mac" : water_fountain .mac ,
240- "type" : water_fountain .device_nfo .type , # type: ignore[union-attr]
241- },
242- headers = await self .client .get_session_id (),
241+ response = await self ._request_ble_api (
242+ PetkitEndpoint .BLE_CONTROL_DEVICE ,
243+ water_fountain ,
244+ extra_data = {"cmd" : cmd_code , "data" : cmd_data },
243245 )
244246 if response != 1 :
245247 _LOGGER .error ("Failed to send BLE command (id %s)" , fountain_id )
0 commit comments