Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Component providing HA sensor support for Travis CI framework."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 
8 from travispy import TravisPy
9 from travispy.errors import TravisError
10 import voluptuous as vol
11 
12 from homeassistant.components import persistent_notification
14  PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
15  SensorEntity,
16  SensorEntityDescription,
17 )
18 from homeassistant.const import (
19  CONF_API_KEY,
20  CONF_MONITORED_CONDITIONS,
21  CONF_SCAN_INTERVAL,
22  UnitOfTime,
23 )
24 from homeassistant.core import HomeAssistant
26 from homeassistant.helpers.entity_platform import AddEntitiesCallback
27 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
28 
29 _LOGGER = logging.getLogger(__name__)
30 
31 CONF_BRANCH = "branch"
32 CONF_REPOSITORY = "repository"
33 
34 DEFAULT_BRANCH_NAME = "master"
35 
36 SCAN_INTERVAL = timedelta(seconds=30)
37 
38 SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
40  key="last_build_id",
41  name="Last Build ID",
42  icon="mdi:card-account-details",
43  ),
45  key="last_build_duration",
46  name="Last Build Duration",
47  native_unit_of_measurement=UnitOfTime.SECONDS,
48  icon="mdi:timelapse",
49  ),
51  key="last_build_finished_at",
52  name="Last Build Finished At",
53  icon="mdi:timetable",
54  ),
56  key="last_build_started_at",
57  name="Last Build Started At",
58  icon="mdi:timetable",
59  ),
61  key="last_build_state",
62  name="Last Build State",
63  icon="mdi:github",
64  ),
66  key="state",
67  name="State",
68  icon="mdi:github",
69  ),
70 )
71 
72 SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES]
73 
74 NOTIFICATION_ID = "travisci"
75 NOTIFICATION_TITLE = "Travis CI Sensor Setup"
76 
77 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
78  {
79  vol.Required(CONF_API_KEY): cv.string,
80  vol.Required(CONF_MONITORED_CONDITIONS, default=SENSOR_KEYS): vol.All(
81  cv.ensure_list, [vol.In(SENSOR_KEYS)]
82  ),
83  vol.Required(CONF_BRANCH, default=DEFAULT_BRANCH_NAME): cv.string,
84  vol.Optional(CONF_REPOSITORY, default=[]): vol.All(cv.ensure_list, [cv.string]),
85  vol.Optional(CONF_SCAN_INTERVAL, default=SCAN_INTERVAL): cv.time_period,
86  }
87 )
88 
89 
91  hass: HomeAssistant,
92  config: ConfigType,
93  add_entities: AddEntitiesCallback,
94  discovery_info: DiscoveryInfoType | None = None,
95 ) -> None:
96  """Set up the Travis CI sensor."""
97 
98  token = config[CONF_API_KEY]
99  repositories = config[CONF_REPOSITORY]
100  branch = config[CONF_BRANCH]
101 
102  try:
103  travis = TravisPy.github_auth(token)
104  user = travis.user()
105 
106  except TravisError as ex:
107  _LOGGER.error("Unable to connect to Travis CI service: %s", str(ex))
108  persistent_notification.create(
109  hass,
110  f"Error: {ex}<br />You will need to restart hass after fixing.",
111  title=NOTIFICATION_TITLE,
112  notification_id=NOTIFICATION_ID,
113  )
114  return
115 
116  # non specific repository selected, then show all associated
117  if not repositories:
118  all_repos = travis.repos(member=user.login)
119  repositories = [repo.slug for repo in all_repos]
120 
121  entities = []
122  monitored_conditions = config[CONF_MONITORED_CONDITIONS]
123  for repo in repositories:
124  if "/" not in repo:
125  repo = f"{user.login}/{repo}"
126 
127  entities.extend(
128  [
129  TravisCISensor(travis, repo, user, branch, description)
130  for description in SENSOR_TYPES
131  if description.key in monitored_conditions
132  ]
133  )
134 
135  add_entities(entities, True)
136 
137 
139  """Representation of a Travis CI sensor."""
140 
141  _attr_attribution = "Information provided by https://travis-ci.org/"
142 
143  def __init__(
144  self, data, repo_name, user, branch, description: SensorEntityDescription
145  ) -> None:
146  """Initialize the sensor."""
147  self.entity_descriptionentity_description = description
148  self._build_build = None
149  self._data_data = data
150  self._repo_name_repo_name = repo_name
151  self._user_user = user
152  self._branch_branch = branch
153 
154  self._attr_name_attr_name = f"{repo_name} {description.name}"
155 
156  @property
158  """Return the state attributes."""
159  attrs = {}
160 
161  if self._build_build and self._attr_native_value_attr_native_value is not None:
162  if self._user_user and self.entity_descriptionentity_description.key == "state":
163  attrs["Owner Name"] = self._user_user.name
164  attrs["Owner Email"] = self._user_user.email
165  else:
166  attrs["Committer Name"] = self._build_build.commit.committer_name
167  attrs["Committer Email"] = self._build_build.commit.committer_email
168  attrs["Commit Branch"] = self._build_build.commit.branch
169  attrs["Committed Date"] = self._build_build.commit.committed_at
170  attrs["Commit SHA"] = self._build_build.commit.sha
171 
172  return attrs
173 
174  def update(self) -> None:
175  """Get the latest data and updates the states."""
176  _LOGGER.debug("Updating sensor %s", self.namename)
177 
178  repo = self._data_data.repo(self._repo_name_repo_name)
179  self._build_build = self._data_data.build(repo.last_build_id)
180 
181  if self._build_build:
182  if (sensor_type := self.entity_descriptionentity_description.key) == "state":
183  branch_stats = self._data_data.branch(self._branch_branch, self._repo_name_repo_name)
184  self._attr_native_value_attr_native_value = branch_stats.state
185 
186  else:
187  param = sensor_type.replace("last_build_", "")
188  self._attr_native_value_attr_native_value = getattr(self._build_build, param)
None __init__(self, data, repo_name, user, branch, SensorEntityDescription description)
Definition: sensor.py:145
str|UndefinedType|None name(self)
Definition: entity.py:738
def add_entities(account, async_add_entities, tracked)
Definition: sensor.py:40
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: sensor.py:95