pycupra 0.0.10__py3-none-any.whl → 0.0.12__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.
pycupra/__version__.py CHANGED
@@ -3,4 +3,4 @@ pycupra - A Python 3 library for interacting with the My Cupra/My Seat portal.
3
3
 
4
4
  For more details and documentation, visit the github page at https://github.com/WulfgarW/pycupra
5
5
  """
6
- __version__ = "0.0.10"
6
+ __version__ = "0.0.12"
pycupra/connection.py CHANGED
@@ -612,7 +612,7 @@ class Connection:
612
612
  # A new day has begun. Store _sessionRequestCounter in history and reset timestamp and counter
613
613
  self._sessionRequestCounterHistory[self._sessionRequestTimestamp.strftime('%Y-%m-%d')]=self._sessionRequestCounter
614
614
  _LOGGER.info(f'History of the number of API calls:')
615
- for key, value in self._sessionRequestCounterHistory.items:
615
+ for key, value in self._sessionRequestCounterHistory.items():
616
616
  _LOGGER.info(f' Date: {key}: {value} API calls')
617
617
 
618
618
  self._sessionRequestTimestamp= datetime.now(tz=None)
pycupra/dashboard.py CHANGED
@@ -1284,6 +1284,11 @@ def create_instruments():
1284
1284
  name="Energy flow",
1285
1285
  device_class="power"
1286
1286
  ),
1287
+ BinarySensor(
1288
+ attr="charging_state",
1289
+ name="Charging state",
1290
+ device_class="power"
1291
+ ),
1287
1292
  BinarySensor(
1288
1293
  attr="parking_light",
1289
1294
  name="Parking light",
pycupra/vehicle.py CHANGED
@@ -471,7 +471,7 @@ class Vehicle:
471
471
  raise SeatInvalidRequestException('Departure timers are not supported.')
472
472
 
473
473
  async def set_timer_schedule(self, id, schedule={}):
474
- """ Set departure schedules. """
474
+ """ Set departure timer schedule. """
475
475
  data = {}
476
476
  # Validate required user inputs
477
477
  supported = "is_departure" + str(id) + "_supported"
@@ -518,7 +518,7 @@ class Vehicle:
518
518
  if not 16 <= int(schedule.get("targetTemp", None)) <= 30:
519
519
  raise SeatInvalidRequestException('Target temp must be integer value from 16 to 30')
520
520
  else:
521
- data['temp'] = schedule.get('targetTemp')
521
+ data['temp'] = int(schedule.get('targetTemp'))
522
522
  raise SeatInvalidRequestException('Target temp (yet) not supported.')
523
523
 
524
524
  # Validate charge target and current
@@ -666,6 +666,98 @@ class Vehicle:
666
666
  self._requests['departuretimer'] = {'status': 'Exception'}
667
667
  raise SeatException('Failed to set departure timer schedule')
668
668
 
669
+ async def set_departure_profile_schedule(self, id, schedule={}):
670
+ """ Set departure profile schedule. """
671
+ data = {}
672
+ # Validate required user inputs
673
+ supported = "is_departure_profile" + str(id) + "_supported"
674
+ if getattr(self, supported) is not True:
675
+ raise SeatConfigException(f'Departure profile id {id} is not supported for this vehicle.')
676
+ else:
677
+ _LOGGER.debug(f'Departure profile id {id} is supported')
678
+ if not schedule:
679
+ raise SeatInvalidRequestException('A schedule must be set.')
680
+ if not isinstance(schedule.get('enabled', ''), bool):
681
+ raise SeatInvalidRequestException('The enabled variable must be set to True or False.')
682
+ if not isinstance(schedule.get('recurring', ''), bool):
683
+ raise SeatInvalidRequestException('The recurring variable must be set to True or False.')
684
+ if not re.match('^[0-9]{2}:[0-9]{2}$', schedule.get('time', '')):
685
+ raise SeatInvalidRequestException('The time for departure must be set in 24h format HH:MM.')
686
+
687
+ # Validate optional inputs
688
+ if schedule.get('recurring', False):
689
+ if not re.match('^[yn]{7}$', schedule.get('days', '')):
690
+ raise SeatInvalidRequestException('For recurring schedules the days variable must be set to y/n mask (mon-sun with only wed enabled): nnynnnn.')
691
+ elif not schedule.get('recurring'):
692
+ if not re.match('^[0-9]{4}-[0-9]{2}-[0-9]{2}$', schedule.get('date', '')):
693
+ raise SeatInvalidRequestException('For single departure profile schedule the date variable must be set to YYYY-mm-dd.')
694
+
695
+ if self._relevantCapabilties.get('departureProfiles', {}).get('active', False):
696
+ # Check if profileIds is set and correct
697
+ if schedule.get('chargingProgramId', False):
698
+ # At the moment, only one charging program id is supported
699
+ chargingProgramId = int(schedule.get('chargingProgramId', False))
700
+ found = False
701
+ for chargingProgram in self.attrs.get('departureProfiles', {}).get('profileIds', []):
702
+ if chargingProgram.get('id',None) == chargingProgramId:
703
+ found = True
704
+ break
705
+ if not found:
706
+ raise SeatInvalidRequestException('The charging program id provided for the departure profile schedule is unknown.')
707
+ else:
708
+ profileIds = []
709
+ profileIds.append(chargingProgramId)
710
+ else:
711
+ raise SeatInvalidRequestException('No charging program id provided for departure profile schedule.')
712
+
713
+ newDepProfileSchedule = {}
714
+ # Prepare data and execute
715
+ newDepProfileSchedule['id'] = id
716
+ # Converting schedule to data map
717
+ if schedule.get("enabled",False):
718
+ newDepProfileSchedule['enabled']=True
719
+ else:
720
+ newDepProfileSchedule['enabled']=False
721
+ if schedule.get("recurring",False):
722
+ newDepProfileSchedule['recurringTimer']= {
723
+ "startTime": schedule.get('time',"00:00"),
724
+ "recurringOn":{""
725
+ "mondays":(schedule.get('days',"nnnnnnn")[0]=='y'),
726
+ "tuesdays":(schedule.get('days',"nnnnnnn")[1]=='y'),
727
+ "wednesdays":(schedule.get('days',"nnnnnnn")[2]=='y'),
728
+ "thursdays":(schedule.get('days',"nnnnnnn")[3]=='y'),
729
+ "fridays":(schedule.get('days',"nnnnnnn")[4]=='y'),
730
+ "saturdays":(schedule.get('days',"nnnnnnn")[5]=='y'),
731
+ "sundays":(schedule.get('days',"nnnnnnn")[6]=='y'),
732
+ }
733
+ }
734
+ else:
735
+ if self._relevantCapabilties.get('departureProfiles', {}).get('supportsSingleTimer', False):
736
+ startDateTime = datetime.fromisoformat(schedule.get('date',"2025-01-01")+'T'+schedule.get('time',"00:00"))
737
+ _LOGGER.info(f'startDateTime={startDateTime.isoformat()}')
738
+ newDepProfileSchedule['singleTimer']= {
739
+ "startDateTimeLocal": startDateTime.isoformat(),
740
+ }
741
+ else:
742
+ raise SeatInvalidRequestException('Vehicle does not support single timer.')
743
+ newDepProfileSchedule["profileIds"]= profileIds
744
+
745
+ # Now we have to substitute the current departure profile schedule with the given id by the new one
746
+ data= deepcopy(self.attrs.get('departureProfiles'))
747
+ if len(data.get('timers', []))<1:
748
+ raise SeatInvalidRequestException(f'No timers found in departure profile: {data}.')
749
+ idFound=False
750
+ for e in range(len(data.get('timers', []))):
751
+ if data['timers'][e].get('id',-1)==id:
752
+ data['timers'][e] = newDepProfileSchedule
753
+ idFound=True
754
+ if idFound:
755
+ return await self._set_departure_profiles(data, action='set')
756
+ raise SeatInvalidRequestException(f'Departure profile id {id} not found in {data.get('timers',[])}.')
757
+ else:
758
+ _LOGGER.info('Departure profiles are not supported.')
759
+ raise SeatInvalidRequestException('Departure profiles are not supported.')
760
+
669
761
  async def set_departure_profile_active(self, id=1, action='off'):
670
762
  """ Activate/deactivate departure profiles. """
671
763
  data = {}
@@ -1552,18 +1644,22 @@ class Vehicle:
1552
1644
  return True
1553
1645
 
1554
1646
  @property
1555
- def energy_flow(self):
1556
- """Return true if energy is flowing through charging port."""
1557
- check = self.attrs.get('charger', {}).get('status', {}).get('chargingStatusData', {}).get('energyFlow', {}).get('content', 'off')
1558
- if check == 'on':
1647
+ #def energy_flow(self):
1648
+ # """Return true if energy is flowing through charging port."""
1649
+ def charging_state(self):
1650
+ """Return true if vehicle is charging."""
1651
+ check = self.attrs.get('charging', {}).get('status', {}).get('state', '')
1652
+ if check == 'charging':
1559
1653
  return True
1560
1654
  else:
1561
1655
  return False
1562
1656
 
1563
1657
  @property
1564
- def is_energy_flow_supported(self):
1565
- """Energy flow supported."""
1566
- if self.attrs.get('charger', {}).get('status', {}).get('chargingStatusData', {}).get('energyFlow', False):
1658
+ #def is_energy_flow_supported(self):
1659
+ # """Energy flow supported."""
1660
+ def is_charging_state_supported(self):
1661
+ """Charging state supported."""
1662
+ if self.attrs.get('charging', {}).get('status', {}).get('state', False):
1567
1663
  return True
1568
1664
 
1569
1665
  # Vehicle location states
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pycupra
3
- Version: 0.0.10
3
+ Version: 0.0.12
4
4
  Summary: A library to read and send vehicle data via Cupra/Seat portal using the same API calls as the MyCupra/MySeat mobile app.
5
5
  Home-page: https://github.com/WulfgarW/pycupra
6
6
  Author: WulfgarW
@@ -0,0 +1,13 @@
1
+ pycupra/__init__.py,sha256=VPzUfKd5mBFD1UERNV61FbGHih5dQPupLgIfYtmIUi4,230
2
+ pycupra/__version__.py,sha256=CeTcAqS8UeO4S1S3J9MNxE_2uChpfnFBNT2cCLe83SM,208
3
+ pycupra/connection.py,sha256=_bTo1sBsUUDEf6Q8-u4H079KT_IN5sW5vlYI26ZB9mc,82423
4
+ pycupra/const.py,sha256=VEYH8TUsJGJwBwloaajwoElYd0qxE7oesvoagvDdE-4,10161
5
+ pycupra/dashboard.py,sha256=4ORHlj-GqDLoz6l0iRMtbGSerSMwOU6NRtn0l8KynZ4,41464
6
+ pycupra/exceptions.py,sha256=Nq_F79GP8wjHf5lpvPy9TbSIrRHAJrFMo0T1N9TcgSQ,2917
7
+ pycupra/utilities.py,sha256=cH4MiIzT2WlHgmnl_E7rR0R5LvCXfDNvirJolct50V8,2563
8
+ pycupra/vehicle.py,sha256=RwEPEZxgOqTqBaraN9xw0G_L5ZpHTGiA5s7uHY4COH0,131949
9
+ pycupra-0.0.12.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
10
+ pycupra-0.0.12.dist-info/METADATA,sha256=FcWVH_rgNOeDHzkyUqxdupB7q92EfS-HB72gKoShSN8,2579
11
+ pycupra-0.0.12.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
12
+ pycupra-0.0.12.dist-info/top_level.txt,sha256=9Lbj_jG4JvpGwt6K3AwhWFc0XieDnuHFOP4x44wSXSQ,8
13
+ pycupra-0.0.12.dist-info/RECORD,,
@@ -1,13 +0,0 @@
1
- pycupra/__init__.py,sha256=VPzUfKd5mBFD1UERNV61FbGHih5dQPupLgIfYtmIUi4,230
2
- pycupra/__version__.py,sha256=LEJHOcWGiX25UGY_gf0yvbwRuMD9VDYQsZZqtPGC7t0,208
3
- pycupra/connection.py,sha256=nmHb196thiv6qnnNV7ktoCdzFNeqGVKK6ajFvCIzw2Y,82421
4
- pycupra/const.py,sha256=VEYH8TUsJGJwBwloaajwoElYd0qxE7oesvoagvDdE-4,10161
5
- pycupra/dashboard.py,sha256=MTvOcxAco6Okk0jJKPeqC-VgvYtKtZb2jm2muUQeu1c,41323
6
- pycupra/exceptions.py,sha256=Nq_F79GP8wjHf5lpvPy9TbSIrRHAJrFMo0T1N9TcgSQ,2917
7
- pycupra/utilities.py,sha256=cH4MiIzT2WlHgmnl_E7rR0R5LvCXfDNvirJolct50V8,2563
8
- pycupra/vehicle.py,sha256=nCHqcWtsbq3OHeAKSIUUqA89IBUbEWnxgD-nn2zjUSI,126311
9
- pycupra-0.0.10.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
10
- pycupra-0.0.10.dist-info/METADATA,sha256=_wfyQamG5sIDTLZJh22SqO6HLpz1ivfqYnJiA7wfvws,2579
11
- pycupra-0.0.10.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
12
- pycupra-0.0.10.dist-info/top_level.txt,sha256=9Lbj_jG4JvpGwt6K3AwhWFc0XieDnuHFOP4x44wSXSQ,8
13
- pycupra-0.0.10.dist-info/RECORD,,