carconnectivity-plugin-database 0.1__py3-none-any.whl → 0.1a16__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.

Potentially problematic release.


This version of carconnectivity-plugin-database might be problematic. Click here for more details.

@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
4
4
  import threading
5
5
 
6
6
  import logging
7
- from datetime import timedelta, datetime, timezone
7
+ from datetime import timedelta
8
8
 
9
9
  from sqlalchemy.exc import DatabaseError
10
10
 
@@ -27,9 +27,8 @@ if TYPE_CHECKING:
27
27
  from sqlalchemy.orm import scoped_session
28
28
  from sqlalchemy.orm.session import Session
29
29
 
30
- from carconnectivity.attributes import EnumAttribute, SpeedAttribute, PowerAttribute, FloatAttribute
30
+ from carconnectivity.attributes import EnumAttribute, SpeedAttribute, PowerAttribute
31
31
 
32
- from carconnectivity_plugins.database.plugin import Plugin
33
32
  from carconnectivity_plugins.database.model.vehicle import Vehicle
34
33
  from carconnectivity.drive import ElectricDrive
35
34
 
@@ -38,16 +37,13 @@ LOG: logging.Logger = logging.getLogger("carconnectivity.plugins.database.agents
38
37
 
39
38
  class ChargingAgent(BaseAgent):
40
39
 
41
- def __init__(self, database_plugin: Plugin, session_factory: scoped_session[Session], vehicle: Vehicle,
42
- carconnectivity_vehicle: ElectricVehicle) -> None:
43
- if vehicle is None or carconnectivity_vehicle is None:
40
+ def __init__(self, session_factory: scoped_session[Session], vehicle: Vehicle) -> None:
41
+ if vehicle is None or vehicle.carconnectivity_vehicle is None:
44
42
  raise ValueError("Vehicle or its carconnectivity_vehicle attribute is None")
45
- if not isinstance(carconnectivity_vehicle, ElectricVehicle):
43
+ if not isinstance(vehicle.carconnectivity_vehicle, ElectricVehicle):
46
44
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is not an ElectricVehicle")
47
- self.database_plugin: Plugin = database_plugin
48
45
  self.session_factory: scoped_session[Session] = session_factory
49
46
  self.vehicle: Vehicle = vehicle
50
- self.carconnectivity_vehicle: ElectricVehicle = carconnectivity_vehicle
51
47
 
52
48
  with self.session_factory() as session:
53
49
  self.last_charging_session: Optional[ChargingSession] = session.query(ChargingSession).filter(ChargingSession.vehicle == vehicle) \
@@ -56,22 +52,24 @@ class ChargingAgent(BaseAgent):
56
52
  ChargingSession.plug_connected_date.desc().nulls_first()).first()
57
53
 
58
54
  self.last_charging_session_lock: threading.RLock = threading.RLock()
59
- self.carconnectivity_last_charging_state: Optional[Charging.ChargingState] = self.carconnectivity_vehicle.charging.state.value
60
- self.carconnectivity_last_connector_state: Optional[ChargingConnector.ChargingConnectorConnectionState] = self.carconnectivity_vehicle.charging\
55
+ self.carconnectivity_last_charging_state: Optional[Charging.ChargingState] = vehicle.carconnectivity_vehicle.charging.state.value
56
+ self.carconnectivity_last_connector_state: Optional[ChargingConnector.ChargingConnectorConnectionState] = vehicle.carconnectivity_vehicle.charging\
61
57
  .connector.connection_state.value
62
- self.carconnectivity_last_connector_lock_state: Optional[ChargingConnector.ChargingConnectorLockState] = self.carconnectivity_vehicle.charging\
58
+ self.carconnectivity_last_connector_lock_state: Optional[ChargingConnector.ChargingConnectorLockState] = vehicle.carconnectivity_vehicle.charging\
63
59
  .connector.lock_state.value
64
60
  if self.last_charging_session is not None and not self.last_charging_session.is_closed():
65
- if self.carconnectivity_vehicle.charging.state.value in (Charging.ChargingState.CHARGING, Charging.ChargingState.CONSERVATION) \
66
- or (self.carconnectivity_vehicle.charging.connector.connection_state.enabled
67
- and self.carconnectivity_vehicle.charging.connector.connection_state.value ==
61
+ if vehicle.carconnectivity_vehicle.charging.state.value in (Charging.ChargingState.CHARGING, Charging.ChargingState.CONSERVATION) \
62
+ or (vehicle.carconnectivity_vehicle.charging.connector.connection_state.enabled
63
+ and vehicle.carconnectivity_vehicle.charging.connector.connection_state.value ==
68
64
  ChargingConnector.ChargingConnectorConnectionState.CONNECTED) \
69
- or (self.carconnectivity_vehicle.charging.connector.lock_state.enabled
70
- and self.carconnectivity_vehicle.charging.connector.lock_state.value == ChargingConnector.ChargingConnectorLockState.LOCKED):
65
+ or (vehicle.carconnectivity_vehicle.charging.connector.lock_state.enabled
66
+ and vehicle.carconnectivity_vehicle.charging.connector.lock_state.value == ChargingConnector.ChargingConnectorLockState.LOCKED):
71
67
  LOG.info("Last charging session for vehicle %s is still open during startup, will continue this session", vehicle.vin)
72
68
  else:
73
69
  LOG.info("Last charging session for vehicle %s is still open during startup, but we are not charging, ignoring it", vehicle.vin)
74
70
  self.last_charging_session = None
71
+ else:
72
+ self.last_charging_session = None
75
73
 
76
74
  self.last_charging_state: Optional[ChargingState] = session.query(ChargingState).filter(ChargingState.vehicle == vehicle)\
77
75
  .order_by(ChargingState.first_date.desc()).first()
@@ -85,36 +83,30 @@ class ChargingAgent(BaseAgent):
85
83
  .order_by(ChargingPower.first_date.desc()).first()
86
84
  self.last_charging_power_lock: threading.RLock = threading.RLock()
87
85
 
88
- self.carconnectivity_vehicle.charging.connector.connection_state.add_observer(self.__on_connector_state_change, Observable.ObserverEvent.UPDATED)
89
- if self.carconnectivity_vehicle.charging.connector.connection_state.enabled:
90
- self.__on_connector_state_change(self.carconnectivity_vehicle.charging.connector.connection_state, Observable.ObserverEvent.UPDATED)
86
+ vehicle.carconnectivity_vehicle.charging.connector.connection_state.add_observer(self.__on_connector_state_change, Observable.ObserverEvent.UPDATED)
87
+ if vehicle.carconnectivity_vehicle.charging.connector.connection_state.enabled:
88
+ self.__on_connector_state_change(vehicle.carconnectivity_vehicle.charging.connector.connection_state, Observable.ObserverEvent.UPDATED)
91
89
 
92
- self.carconnectivity_vehicle.charging.connector.lock_state.add_observer(self.__on_connector_lock_state_change, Observable.ObserverEvent.UPDATED)
93
- if self.carconnectivity_vehicle.charging.connector.lock_state.enabled:
94
- self.__on_connector_lock_state_change(self.carconnectivity_vehicle.charging.connector.lock_state, Observable.ObserverEvent.UPDATED)
90
+ vehicle.carconnectivity_vehicle.charging.connector.lock_state.add_observer(self.__on_connector_lock_state_change, Observable.ObserverEvent.UPDATED)
91
+ if vehicle.carconnectivity_vehicle.charging.connector.lock_state.enabled:
92
+ self.__on_connector_lock_state_change(vehicle.carconnectivity_vehicle.charging.connector.lock_state, Observable.ObserverEvent.UPDATED)
95
93
 
96
- self.carconnectivity_vehicle.charging.state.add_observer(self.__on_charging_state_change, Observable.ObserverEvent.UPDATED)
97
- if self.carconnectivity_vehicle.charging.state.enabled:
98
- self.__on_charging_state_change(self.carconnectivity_vehicle.charging.state, Observable.ObserverEvent.UPDATED)
94
+ vehicle.carconnectivity_vehicle.charging.state.add_observer(self.__on_charging_state_change, Observable.ObserverEvent.UPDATED)
95
+ if vehicle.carconnectivity_vehicle.charging.state.enabled:
96
+ self.__on_charging_state_change(vehicle.carconnectivity_vehicle.charging.state, Observable.ObserverEvent.UPDATED)
99
97
 
100
- self.carconnectivity_vehicle.charging.rate.add_observer(self.__on_charging_rate_change, Observable.ObserverEvent.UPDATED)
101
- if self.carconnectivity_vehicle.charging.rate.enabled:
102
- self.__on_charging_rate_change(self.carconnectivity_vehicle.charging.rate, Observable.ObserverEvent.UPDATED)
98
+ vehicle.carconnectivity_vehicle.charging.rate.add_observer(self.__on_charging_rate_change, Observable.ObserverEvent.UPDATED)
99
+ if vehicle.carconnectivity_vehicle.charging.rate.enabled:
100
+ self.__on_charging_rate_change(vehicle.carconnectivity_vehicle.charging.rate, Observable.ObserverEvent.UPDATED)
103
101
 
104
- self.carconnectivity_vehicle.charging.power.add_observer(self.__on_charging_power_change, Observable.ObserverEvent.UPDATED)
105
- if self.carconnectivity_vehicle.charging.power.enabled:
106
- self.__on_charging_power_change(self.carconnectivity_vehicle.charging.power, Observable.ObserverEvent.UPDATED)
107
-
108
- self.carconnectivity_vehicle.charging.type.add_observer(self._on_charging_type_change, Observable.ObserverEvent.VALUE_CHANGED)
109
-
110
- electric_drive: Optional[ElectricDrive] = self.carconnectivity_vehicle.get_electric_drive()
111
- if electric_drive is not None:
112
- electric_drive.level.add_observer(self._on_battery_level_change, Observable.ObserverEvent.VALUE_CHANGED)
102
+ vehicle.carconnectivity_vehicle.charging.power.add_observer(self.__on_charging_power_change, Observable.ObserverEvent.UPDATED)
103
+ if vehicle.carconnectivity_vehicle.charging.power.enabled:
104
+ self.__on_charging_power_change(vehicle.carconnectivity_vehicle.charging.power, Observable.ObserverEvent.UPDATED)
113
105
  self.session_factory.remove()
114
106
 
115
107
  def __on_charging_state_change(self, element: EnumAttribute[Charging.ChargingState], flags: Observable.ObserverEvent) -> None:
116
108
  del flags
117
- if self.carconnectivity_vehicle is None:
109
+ if self.vehicle.carconnectivity_vehicle is None:
118
110
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is None")
119
111
 
120
112
  if element.enabled:
@@ -123,9 +115,8 @@ class ChargingAgent(BaseAgent):
123
115
  if self.last_charging_state is not None:
124
116
  self.last_charging_state = session.merge(self.last_charging_state)
125
117
  session.refresh(self.last_charging_state)
126
- if element.last_updated is not None \
127
- and (self.last_charging_state is None or (self.last_charging_state.state != element.value
128
- and element.last_updated > self.last_charging_state.last_date)):
118
+ if (self.last_charging_state is None or self.last_charging_state.state != element.value) \
119
+ and element.last_updated is not None:
129
120
  new_charging_state: ChargingState = ChargingState(vin=self.vehicle.vin, first_date=element.last_updated,
130
121
  last_date=element.last_updated, state=element.value)
131
122
  try:
@@ -136,7 +127,6 @@ class ChargingAgent(BaseAgent):
136
127
  except DatabaseError as err:
137
128
  session.rollback()
138
129
  LOG.error('DatabaseError while adding charging state for vehicle %s to database: %s', self.vehicle.vin, err)
139
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
140
130
 
141
131
  elif self.last_charging_state is not None and self.last_charging_state.state == element.value and element.last_updated is not None:
142
132
  if self.last_charging_state.last_date is None or element.last_updated > self.last_charging_state.last_date:
@@ -147,7 +137,6 @@ class ChargingAgent(BaseAgent):
147
137
  except DatabaseError as err:
148
138
  session.rollback()
149
139
  LOG.error('DatabaseError while updating charging state for vehicle %s in database: %s', self.vehicle.vin, err)
150
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
151
140
 
152
141
  with self.last_charging_session_lock:
153
142
  if self.last_charging_session is not None:
@@ -172,12 +161,10 @@ class ChargingAgent(BaseAgent):
172
161
  try:
173
162
  self.last_charging_session.session_end_date = None
174
163
  self.last_charging_session.end_level = None
175
- self._update_session_charging_type(session, self.last_charging_session)
176
164
  session.commit()
177
165
  except DatabaseError as err:
178
166
  session.rollback()
179
167
  LOG.error('DatabaseError while updating charging session for vehicle %s in database: %s', self.vehicle.vin, err)
180
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
181
168
  else:
182
169
  LOG.info("Starting new charging session for vehicle %s", self.vehicle.vin)
183
170
  new_session: ChargingSession = ChargingSession(vin=self.vehicle.vin, session_start_date=element.last_changed)
@@ -192,7 +179,6 @@ class ChargingAgent(BaseAgent):
192
179
  except DatabaseError as err:
193
180
  session.rollback()
194
181
  LOG.error('DatabaseError while adding charging session for vehicle %s to database: %s', self.vehicle.vin, err)
195
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
196
182
  else:
197
183
  if self.last_charging_session.was_started():
198
184
  LOG.debug("Continuing existing charging session for vehicle %s", self.vehicle.vin)
@@ -207,10 +193,9 @@ class ChargingAgent(BaseAgent):
207
193
  except DatabaseError as err:
208
194
  session.rollback()
209
195
  LOG.error('DatabaseError while starting charging session for vehicle %s in database: %s', self.vehicle.vin, err)
210
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
211
196
  # Update startlevel at beginning of charging
212
- if self.last_charging_session is not None and isinstance(self.carconnectivity_vehicle, ElectricVehicle):
213
- electric_drive: Optional[ElectricDrive] = self.carconnectivity_vehicle.get_electric_drive()
197
+ if self.last_charging_session is not None and isinstance(self.vehicle.carconnectivity_vehicle, ElectricVehicle):
198
+ electric_drive: Optional[ElectricDrive] = self.vehicle.carconnectivity_vehicle.get_electric_drive()
214
199
  if electric_drive is not None and electric_drive.level.enabled and electric_drive.level.value is not None:
215
200
  try:
216
201
  self.last_charging_session.start_level = electric_drive.level.value
@@ -218,7 +203,6 @@ class ChargingAgent(BaseAgent):
218
203
  except DatabaseError as err:
219
204
  session.rollback()
220
205
  LOG.error('DatabaseError while setting start level for vehicle %s in database: %s', self.vehicle.vin, err)
221
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
222
206
  elif element.value not in (Charging.ChargingState.CHARGING, Charging.ChargingState.CONSERVATION) \
223
207
  and self.carconnectivity_last_charging_state in (Charging.ChargingState.CHARGING, Charging.ChargingState.CONSERVATION):
224
208
  if self.last_charging_session is not None and not self.last_charging_session.was_ended():
@@ -229,9 +213,8 @@ class ChargingAgent(BaseAgent):
229
213
  except DatabaseError as err:
230
214
  session.rollback()
231
215
  LOG.error('DatabaseError while ending charging session for vehicle %s in database: %s', self.vehicle.vin, err)
232
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
233
- if isinstance(self.carconnectivity_vehicle, ElectricVehicle):
234
- electric_drive: Optional[ElectricDrive] = self.carconnectivity_vehicle.get_electric_drive()
216
+ if isinstance(self.vehicle.carconnectivity_vehicle, ElectricVehicle):
217
+ electric_drive: Optional[ElectricDrive] = self.vehicle.carconnectivity_vehicle.get_electric_drive()
235
218
  if electric_drive is not None and electric_drive.level.enabled and electric_drive.level.value is not None:
236
219
  try:
237
220
  self.last_charging_session.end_level = electric_drive.level.value
@@ -239,13 +222,12 @@ class ChargingAgent(BaseAgent):
239
222
  except DatabaseError as err:
240
223
  session.rollback()
241
224
  LOG.error('DatabaseError while setting start level for vehicle %s in database: %s', self.vehicle.vin, err)
242
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
243
225
  self.carconnectivity_last_charging_state = element.value
244
226
  self.session_factory.remove()
245
227
 
246
228
  def __on_charging_rate_change(self, element: SpeedAttribute, flags: Observable.ObserverEvent) -> None:
247
229
  del flags
248
- if self.carconnectivity_vehicle is None:
230
+ if self.vehicle.carconnectivity_vehicle is None:
249
231
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is None")
250
232
  if element.enabled:
251
233
  with self.last_charging_rate_lock:
@@ -253,9 +235,8 @@ class ChargingAgent(BaseAgent):
253
235
  if self.last_charging_rate is not None:
254
236
  self.last_charging_rate = session.merge(self.last_charging_rate)
255
237
  session.refresh(self.last_charging_rate)
256
- if element.last_updated is not None \
257
- and (self.last_charging_rate is None or (self.last_charging_rate.rate != element.value
258
- and element.last_updated > self.last_charging_rate.last_date)):
238
+ if (self.last_charging_rate is None or self.last_charging_rate.rate != element.value) \
239
+ and element.last_updated is not None:
259
240
  new_charging_rate: ChargingRate = ChargingRate(vin=self.vehicle.vin, first_date=element.last_updated,
260
241
  last_date=element.last_updated, rate=element.value)
261
242
  try:
@@ -266,7 +247,6 @@ class ChargingAgent(BaseAgent):
266
247
  except DatabaseError as err:
267
248
  session.rollback()
268
249
  LOG.error('DatabaseError while adding charging rate for vehicle %s to database: %s', self.vehicle.vin, err)
269
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
270
250
  elif self.last_charging_rate is not None and self.last_charging_rate.rate == element.value and element.last_updated is not None:
271
251
  if self.last_charging_rate.last_date is None or element.last_updated > self.last_charging_rate.last_date:
272
252
  try:
@@ -276,12 +256,11 @@ class ChargingAgent(BaseAgent):
276
256
  except DatabaseError as err:
277
257
  session.rollback()
278
258
  LOG.error('DatabaseError while updating charging rate for vehicle %s in database: %s', self.vehicle.vin, err)
279
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
280
259
  self.session_factory.remove()
281
260
 
282
261
  def __on_charging_power_change(self, element: PowerAttribute, flags: Observable.ObserverEvent) -> None:
283
262
  del flags
284
- if self.carconnectivity_vehicle is None:
263
+ if self.vehicle.carconnectivity_vehicle is None:
285
264
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is None")
286
265
  if element.enabled:
287
266
  with self.last_charging_power_lock:
@@ -289,9 +268,8 @@ class ChargingAgent(BaseAgent):
289
268
  if self.last_charging_power is not None:
290
269
  self.last_charging_power = session.merge(self.last_charging_power)
291
270
  session.refresh(self.last_charging_power)
292
- if element.last_updated is not None \
293
- and (self.last_charging_power is None or (self.last_charging_power.power != element.value
294
- and element.last_updated > self.last_charging_power.last_date)):
271
+ if (self.last_charging_power is None or self.last_charging_power.power != element.value) \
272
+ and element.last_updated is not None:
295
273
  new_charging_power: ChargingPower = ChargingPower(vin=self.vehicle.vin, first_date=element.last_updated,
296
274
  last_date=element.last_updated, power=element.value)
297
275
  try:
@@ -302,7 +280,6 @@ class ChargingAgent(BaseAgent):
302
280
  except DatabaseError as err:
303
281
  session.rollback()
304
282
  LOG.error('DatabaseError while adding charging power for vehicle %s to database: %s', self.vehicle.vin, err)
305
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
306
283
  elif self.last_charging_power is not None and self.last_charging_power.power == element.value and element.last_updated is not None:
307
284
  if self.last_charging_power.last_date is None or element.last_updated > self.last_charging_power.last_date:
308
285
  try:
@@ -311,12 +288,11 @@ class ChargingAgent(BaseAgent):
311
288
  except DatabaseError as err:
312
289
  session.rollback()
313
290
  LOG.error('DatabaseError while updating charging power for vehicle %s in database: %s', self.vehicle.vin, err)
314
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
315
291
  self.session_factory.remove()
316
292
 
317
293
  def __on_connector_state_change(self, element: EnumAttribute[ChargingConnector.ChargingConnectorConnectionState], flags: Observable.ObserverEvent) -> None:
318
294
  del flags
319
- if self.carconnectivity_vehicle is None:
295
+ if self.vehicle.carconnectivity_vehicle is None:
320
296
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is None")
321
297
 
322
298
  with self.session_factory() as session:
@@ -326,7 +302,6 @@ class ChargingAgent(BaseAgent):
326
302
  session.refresh(self.last_charging_session)
327
303
 
328
304
  if element.value == ChargingConnector.ChargingConnectorConnectionState.CONNECTED \
329
- and self.carconnectivity_last_connector_state is not None \
330
305
  and self.carconnectivity_last_connector_state != ChargingConnector.ChargingConnectorConnectionState.CONNECTED:
331
306
  if self.last_charging_session is None or self.last_charging_session.is_closed():
332
307
  LOG.info("Starting new charging session for vehicle %s due to connector connected state", self.vehicle.vin)
@@ -341,7 +316,6 @@ class ChargingAgent(BaseAgent):
341
316
  except DatabaseError as err:
342
317
  session.rollback()
343
318
  LOG.error('DatabaseError while adding charging session for vehicle %s to database: %s', self.vehicle.vin, err)
344
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
345
319
  elif not self.last_charging_session.was_connected():
346
320
  LOG.debug("Continuing existing charging session for vehicle %s, writing connected date", self.vehicle.vin)
347
321
  try:
@@ -352,7 +326,6 @@ class ChargingAgent(BaseAgent):
352
326
  except DatabaseError as err:
353
327
  session.rollback()
354
328
  LOG.error('DatabaseError while starting charging session for vehicle %s in database: %s', self.vehicle.vin, err)
355
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
356
329
  elif element.value != ChargingConnector.ChargingConnectorConnectionState.CONNECTED \
357
330
  and self.carconnectivity_last_connector_state == ChargingConnector.ChargingConnectorConnectionState.CONNECTED:
358
331
  if self.last_charging_session is not None and not self.last_charging_session.was_disconnected():
@@ -363,29 +336,22 @@ class ChargingAgent(BaseAgent):
363
336
  except DatabaseError as err:
364
337
  session.rollback()
365
338
  LOG.error('DatabaseError while ending charging session for vehicle %s in database: %s', self.vehicle.vin, err)
366
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
367
339
  # Create charging session when connected at startup
368
340
  elif element.value == ChargingConnector.ChargingConnectorConnectionState.CONNECTED \
369
341
  and self.carconnectivity_last_connector_state == ChargingConnector.ChargingConnectorConnectionState.CONNECTED:
370
342
  if self.last_charging_session is None or self.last_charging_session.is_closed():
371
- # when the incoming connected state was during the last session, this is a continuation
372
- if self.last_charging_session is None or element.last_changed is not None and element.last_changed > \
373
- (self.last_charging_session.session_end_date
374
- or self.last_charging_session.plug_unlocked_date
375
- or datetime.min.replace(tzinfo=timezone.utc)):
376
- LOG.info("Starting new charging session for vehicle %s due to connector connected state on startup", self.vehicle.vin)
377
- new_session: ChargingSession = ChargingSession(vin=self.vehicle.vin, plug_connected_date=element.last_changed)
378
- try:
379
- session.add(new_session)
380
- self._update_session_odometer(session, new_session)
381
- self._update_session_position(session, new_session)
382
- session.commit()
383
- LOG.debug('Added new charging session for vehicle %s to database', self.vehicle.vin)
384
- self.last_charging_session = new_session
385
- except DatabaseError as err:
386
- session.rollback()
387
- LOG.error('DatabaseError while adding charging session for vehicle %s to database: %s', self.vehicle.vin, err)
388
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
343
+ LOG.info("Starting new charging session for vehicle %s due to connector connected state", self.vehicle.vin)
344
+ new_session: ChargingSession = ChargingSession(vin=self.vehicle.vin, plug_connected_date=element.last_changed)
345
+ try:
346
+ session.add(new_session)
347
+ self._update_session_odometer(session, new_session)
348
+ self._update_session_position(session, new_session)
349
+ session.commit()
350
+ LOG.debug('Added new charging session for vehicle %s to database', self.vehicle.vin)
351
+ self.last_charging_session = new_session
352
+ except DatabaseError as err:
353
+ session.rollback()
354
+ LOG.error('DatabaseError while adding charging session for vehicle %s to database: %s', self.vehicle.vin, err)
389
355
  elif self.last_charging_session is not None and not self.last_charging_session.was_connected():
390
356
  try:
391
357
  self.last_charging_session.plug_connected_date = element.last_changed
@@ -394,13 +360,12 @@ class ChargingAgent(BaseAgent):
394
360
  except DatabaseError as err:
395
361
  session.rollback()
396
362
  LOG.error('DatabaseError while changing charging session for vehicle %s to database: %s', self.vehicle.vin, err)
397
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
398
363
  self.carconnectivity_last_connector_state = element.value
399
364
  self.session_factory.remove()
400
365
 
401
366
  def __on_connector_lock_state_change(self, element: EnumAttribute[ChargingConnector.ChargingConnectorLockState], flags: Observable.ObserverEvent) -> None:
402
367
  del flags
403
- if self.carconnectivity_vehicle is None:
368
+ if self.vehicle.carconnectivity_vehicle is None:
404
369
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is None")
405
370
 
406
371
  with self.session_factory() as session:
@@ -410,36 +375,20 @@ class ChargingAgent(BaseAgent):
410
375
  session.refresh(self.last_charging_session)
411
376
 
412
377
  if element.value == ChargingConnector.ChargingConnectorLockState.LOCKED \
413
- and self.carconnectivity_last_connector_lock_state is not None \
414
378
  and self.carconnectivity_last_connector_lock_state != ChargingConnector.ChargingConnectorLockState.LOCKED:
415
379
  if self.last_charging_session is None or self.last_charging_session.is_closed():
416
- # In case this was an interrupted charging session (interrupt no longer than 24hours), continue by erasing end time
417
- if self.last_charging_session is not None and not self.last_charging_session.was_disconnected() \
418
- and (self.last_charging_session.plug_unlocked_date is None
419
- or self.last_charging_session.plug_unlocked_date > ((element.last_changed or datetime.now(timezone.utc))
420
- - timedelta(hours=24))):
421
- LOG.debug("found a closed charging session that was not disconneced. This could be an interrupted session we want to continue")
422
- try:
423
- self.last_charging_session.plug_unlocked_date = None
424
- session.commit()
425
- except DatabaseError as err:
426
- session.rollback()
427
- LOG.error('DatabaseError while changing charging session for vehicle %s to database: %s', self.vehicle.vin, err)
428
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
429
- else:
430
- LOG.info("Starting new charging session for vehicle %s due to connector locked state", self.vehicle.vin)
431
- new_session: ChargingSession = ChargingSession(vin=self.vehicle.vin, plug_locked_date=element.last_changed)
432
- try:
433
- session.add(new_session)
434
- self._update_session_odometer(session, new_session)
435
- self._update_session_position(session, new_session)
436
- session.commit()
437
- LOG.debug('Added new charging session for vehicle %s to database', self.vehicle.vin)
438
- self.last_charging_session = new_session
439
- except DatabaseError as err:
440
- session.rollback()
441
- LOG.error('DatabaseError while adding charging session for vehicle %s to database: %s', self.vehicle.vin, err)
442
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
380
+ LOG.info("Starting new charging session for vehicle %s due to connector locked state", self.vehicle.vin)
381
+ new_session: ChargingSession = ChargingSession(vin=self.vehicle.vin, plug_locked_date=element.last_changed)
382
+ try:
383
+ session.add(new_session)
384
+ self._update_session_odometer(session, new_session)
385
+ self._update_session_position(session, new_session)
386
+ session.commit()
387
+ LOG.debug('Added new charging session for vehicle %s to database', self.vehicle.vin)
388
+ self.last_charging_session = new_session
389
+ except DatabaseError as err:
390
+ session.rollback()
391
+ LOG.error('DatabaseError while adding charging session for vehicle %s to database: %s', self.vehicle.vin, err)
443
392
  elif not self.last_charging_session.was_locked():
444
393
  LOG.debug("Continuing existing charging session for vehicle %s, writing locked date", self.vehicle.vin)
445
394
  try:
@@ -450,7 +399,6 @@ class ChargingAgent(BaseAgent):
450
399
  except DatabaseError as err:
451
400
  session.rollback()
452
401
  LOG.error('DatabaseError while starting charging session for vehicle %s in database: %s', self.vehicle.vin, err)
453
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
454
402
  elif element.value != ChargingConnector.ChargingConnectorLockState.LOCKED \
455
403
  and self.carconnectivity_last_connector_lock_state == ChargingConnector.ChargingConnectorLockState.LOCKED:
456
404
  if self.last_charging_session is not None and not self.last_charging_session.was_unlocked():
@@ -461,26 +409,11 @@ class ChargingAgent(BaseAgent):
461
409
  except DatabaseError as err:
462
410
  session.rollback()
463
411
  LOG.error('DatabaseError while ending charging session for vehicle %s in database: %s', self.vehicle.vin, err)
464
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
465
412
  # Create charging session when locked at startup
466
413
  elif element.value == ChargingConnector.ChargingConnectorLockState.LOCKED \
467
414
  and self.carconnectivity_last_connector_lock_state == ChargingConnector.ChargingConnectorLockState.LOCKED:
468
415
  if self.last_charging_session is None or self.last_charging_session.is_closed():
469
- # In case this was an interrupted charging session (interrupt no longer than 24hours), continue by erasing end time
470
- if self.last_charging_session is not None and not self.last_charging_session.was_disconnected() \
471
- and (self.last_charging_session.plug_unlocked_date is None
472
- or self.last_charging_session.plug_unlocked_date > ((element.last_changed or datetime.now(timezone.utc))
473
- - timedelta(hours=24))):
474
- LOG.debug("found a closed charging session that was not disconneced. This could be an interrupted session we want to continue")
475
- try:
476
- self.last_charging_session.plug_unlocked_date = None
477
- session.commit()
478
- except DatabaseError as err:
479
- session.rollback()
480
- LOG.error('DatabaseError while changing charging session for vehicle %s to database: %s', self.vehicle.vin, err)
481
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
482
- else:
483
- LOG.info("Starting new charging session for vehicle %s due to connector locked state on startup", self.vehicle.vin)
416
+ LOG.info("Starting new charging session for vehicle %s due to connector locked state", self.vehicle.vin)
484
417
  new_session: ChargingSession = ChargingSession(vin=self.vehicle.vin, plug_locked_date=element.last_changed)
485
418
  try:
486
419
  session.add(new_session)
@@ -492,7 +425,6 @@ class ChargingAgent(BaseAgent):
492
425
  except DatabaseError as err:
493
426
  session.rollback()
494
427
  LOG.error('DatabaseError while adding charging session for vehicle %s to database: %s', self.vehicle.vin, err)
495
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
496
428
  elif self.last_charging_session is not None and not self.last_charging_session.was_locked():
497
429
  try:
498
430
  self.last_charging_session.plug_locked_date = element.last_changed
@@ -501,110 +433,62 @@ class ChargingAgent(BaseAgent):
501
433
  except DatabaseError as err:
502
434
  session.rollback()
503
435
  LOG.error('DatabaseError while changing charging session for vehicle %s to database: %s', self.vehicle.vin, err)
504
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
505
436
  self.carconnectivity_last_connector_lock_state = element.value
506
437
  self.session_factory.remove()
507
438
 
508
439
  def _update_session_odometer(self, session: Session, charging_session: ChargingSession) -> None:
509
- if self.carconnectivity_vehicle is None:
440
+ if self.vehicle.carconnectivity_vehicle is None:
510
441
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is None")
511
- if self.carconnectivity_vehicle.odometer.enabled:
442
+ if self.vehicle.carconnectivity_vehicle.odometer.enabled:
512
443
  if charging_session.session_odometer is None:
513
444
  try:
514
- charging_session.session_odometer = self.carconnectivity_vehicle.odometer.value
445
+ charging_session.session_odometer = self.vehicle.carconnectivity_vehicle.odometer.value
515
446
  except DatabaseError as err:
516
447
  session.rollback()
517
448
  LOG.error('DatabaseError while updating odometer for charging session of vehicle %s in database: %s', self.vehicle.vin, err)
518
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
519
449
 
520
450
  def _update_session_charging_type(self, session: Session, charging_session: ChargingSession) -> None:
521
- if self.carconnectivity_vehicle is None:
451
+ if self.vehicle.carconnectivity_vehicle is None:
522
452
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is None")
523
- if isinstance(self.carconnectivity_vehicle, ElectricVehicle) and self.carconnectivity_vehicle.charging.type.enabled \
524
- and self.carconnectivity_vehicle.charging.type.value is not None:
453
+ if isinstance(self.vehicle.carconnectivity_vehicle, ElectricVehicle) and self.vehicle.carconnectivity_vehicle.charging.type.enabled \
454
+ and self.vehicle.carconnectivity_vehicle.charging.type.value is not None:
525
455
  if charging_session.charging_type is None:
526
456
  try:
527
- charging_session.charging_type = self.carconnectivity_vehicle.charging.type.value
457
+ charging_session.charging_type = self.vehicle.carconnectivity_vehicle.charging.type.value
528
458
  except DatabaseError as err:
529
459
  session.rollback()
530
460
  LOG.error('DatabaseError while updating charging type for charging session of vehicle %s in database: %s', self.vehicle.vin, err)
531
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
532
461
 
533
462
  def _update_session_position(self, session: Session, charging_session: ChargingSession) -> None:
534
- if self.carconnectivity_vehicle is None:
463
+ if self.vehicle.carconnectivity_vehicle is None:
535
464
  raise ValueError("Vehicle's carconnectivity_vehicle attribute is None")
536
- if self.carconnectivity_vehicle.position.enabled and self.carconnectivity_vehicle.position.latitude.enabled \
537
- and self.carconnectivity_vehicle.position.longitude.enabled \
538
- and self.carconnectivity_vehicle.position.latitude.value is not None \
539
- and self.carconnectivity_vehicle.position.longitude.value is not None:
465
+ if self.vehicle.carconnectivity_vehicle.position.enabled and self.vehicle.carconnectivity_vehicle.position.latitude.enabled \
466
+ and self.vehicle.carconnectivity_vehicle.position.longitude.enabled \
467
+ and self.vehicle.carconnectivity_vehicle.position.latitude.value is not None \
468
+ and self.vehicle.carconnectivity_vehicle.position.longitude.value is not None:
540
469
  if charging_session.session_position_latitude is None and charging_session.session_position_longitude is None:
541
470
  try:
542
- charging_session.session_position_latitude = self.carconnectivity_vehicle.position.latitude.value
543
- charging_session.session_position_longitude = self.carconnectivity_vehicle.position.longitude.value
471
+ charging_session.session_position_latitude = self.vehicle.carconnectivity_vehicle.position.latitude.value
472
+ charging_session.session_position_longitude = self.vehicle.carconnectivity_vehicle.position.longitude.value
544
473
  except DatabaseError as err:
545
474
  session.rollback()
546
475
  LOG.error('DatabaseError while updating position for charging session of vehicle %s in database: %s', self.vehicle.vin, err)
547
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
548
- if charging_session.location is None and self.carconnectivity_vehicle.position.location.enabled:
549
- location: Location = Location.from_carconnectivity_location(location=self.carconnectivity_vehicle.position.location)
476
+ if charging_session.location is None and self.vehicle.carconnectivity_vehicle.position.location.enabled:
477
+ location: Location = Location.from_carconnectivity_location(location=self.vehicle.carconnectivity_vehicle.position.location)
550
478
  try:
551
479
  location = session.merge(location)
552
480
  charging_session.location = location
553
481
  except DatabaseError as err:
554
482
  session.rollback()
555
483
  LOG.error('DatabaseError while merging location for charging session of vehicle %s in database: %s', self.vehicle.vin, err)
556
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
557
484
  if charging_session.charging_station is None \
558
- and isinstance(self.carconnectivity_vehicle, ElectricVehicle) and self.carconnectivity_vehicle.charging is not None \
559
- and self.carconnectivity_vehicle.charging.enabled and self.carconnectivity_vehicle.charging.charging_station.enabled:
485
+ and isinstance(self.vehicle.carconnectivity_vehicle, ElectricVehicle) and self.vehicle.carconnectivity_vehicle.charging is not None \
486
+ and self.vehicle.carconnectivity_vehicle.charging.enabled and self.vehicle.carconnectivity_vehicle.charging.charging_station.enabled:
560
487
  charging_station: ChargingStation = ChargingStation.from_carconnectivity_charging_station(
561
- charging_station=self.carconnectivity_vehicle.charging.charging_station)
488
+ charging_station=self.vehicle.carconnectivity_vehicle.charging.charging_station)
562
489
  try:
563
490
  charging_station = session.merge(charging_station)
564
491
  charging_session.charging_station = charging_station
565
492
  except DatabaseError as err:
566
493
  session.rollback()
567
494
  LOG.error('DatabaseError while merging charging station for charging session of vehicle %s in database: %s', self.vehicle.vin, err)
568
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
569
-
570
- def _on_charging_type_change(self, element: EnumAttribute[Charging.ChargingType], flags: Observable.ObserverEvent) -> None:
571
- del flags
572
- if element.enabled:
573
- with self.session_factory() as session:
574
- with self.last_charging_session_lock:
575
- if self.last_charging_session is not None:
576
- self.last_charging_session = session.merge(self.last_charging_session)
577
- session.refresh(self.last_charging_session)
578
- if self.last_charging_session is not None and not self.last_charging_session.is_closed() \
579
- and element.value in [Charging.ChargingType.AC, Charging.ChargingType.DC]:
580
- try:
581
- self.last_charging_session.charging_type = element.value
582
- session.commit()
583
- except DatabaseError as err:
584
- session.rollback()
585
- LOG.error('DatabaseError while updating type of charging session for vehicle %s in database: %s', self.vehicle.vin, err)
586
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
587
- self.session_factory.remove()
588
-
589
- def _on_battery_level_change(self, element: FloatAttribute, flags: Observable.ObserverEvent) -> None:
590
- del flags
591
- if element.enabled and element.value is not None:
592
- # We try to see if there was a late battery level update for a finished session
593
- with self.session_factory() as session:
594
- with self.last_charging_session_lock:
595
- if self.last_charging_session is not None:
596
- self.last_charging_session = session.merge(self.last_charging_session)
597
- session.refresh(self.last_charging_session)
598
- if self.last_charging_session is not None and self.last_charging_session.session_end_date is not None:
599
- if element.last_updated is not None and (element.last_updated <= (self.last_charging_session.session_end_date + timedelta(minutes=1))):
600
- # Only update if we have no end level yet or the new level is higher than the previous one (this happens with late level updates)
601
- if self.last_charging_session.end_level is None or self.last_charging_session.end_level < element.value:
602
- try:
603
- self.last_charging_session.end_level = element.value
604
- session.commit()
605
- except DatabaseError as err:
606
- session.rollback()
607
- LOG.error('DatabaseError while updating battery level of charging session for vehicle %s in database: %s',
608
- self.vehicle.vin, err)
609
- self.database_plugin.healthy._set_value(value=False) # pylint: disable=protected-access
610
- self.session_factory.remove()