Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Sensor for retrieving latest GitLab CI job information."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 
8 from gitlab import Gitlab, GitlabAuthenticationError, GitlabGetError
9 import voluptuous as vol
10 
12  PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
13  SensorEntity,
14 )
15 from homeassistant.const import CONF_NAME, CONF_SCAN_INTERVAL, CONF_TOKEN, CONF_URL
16 from homeassistant.core import HomeAssistant
18 from homeassistant.helpers.entity_platform import AddEntitiesCallback
19 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
20 from homeassistant.util import Throttle
21 
22 _LOGGER = logging.getLogger(__name__)
23 
24 ATTR_BUILD_BRANCH = "build branch"
25 ATTR_BUILD_COMMIT_DATE = "commit date"
26 ATTR_BUILD_COMMIT_ID = "commit id"
27 ATTR_BUILD_DURATION = "build_duration"
28 ATTR_BUILD_FINISHED = "build_finished"
29 ATTR_BUILD_ID = "build id"
30 ATTR_BUILD_STARTED = "build_started"
31 ATTR_BUILD_STATUS = "build_status"
32 ATTRIBUTION = "Information provided by https://gitlab.com/"
33 
34 CONF_GITLAB_ID = "gitlab_id"
35 
36 DEFAULT_NAME = "GitLab CI Status"
37 DEFAULT_URL = "https://gitlab.com"
38 
39 ICON_HAPPY = "mdi:emoticon-happy"
40 ICON_OTHER = "mdi:git"
41 ICON_SAD = "mdi:emoticon-sad"
42 
43 SCAN_INTERVAL = timedelta(seconds=300)
44 
45 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
46  {
47  vol.Required(CONF_GITLAB_ID): cv.string,
48  vol.Required(CONF_TOKEN): cv.string,
49  vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
50  vol.Optional(CONF_URL, default=DEFAULT_URL): cv.string,
51  }
52 )
53 
54 
56  hass: HomeAssistant,
57  config: ConfigType,
58  add_entities: AddEntitiesCallback,
59  discovery_info: DiscoveryInfoType | None = None,
60 ) -> None:
61  """Set up the GitLab sensor platform."""
62  _name = config.get(CONF_NAME, DEFAULT_NAME)
63  _interval = config.get(CONF_SCAN_INTERVAL, SCAN_INTERVAL)
64  _url = config.get(CONF_URL)
65 
66  _gitlab_data = GitLabData(
67  priv_token=config[CONF_TOKEN],
68  gitlab_id=config[CONF_GITLAB_ID],
69  interval=_interval,
70  url=_url,
71  )
72 
73  add_entities([GitLabSensor(_gitlab_data, _name)], True)
74 
75 
77  """Representation of a GitLab sensor."""
78 
79  _attr_attribution = ATTRIBUTION
80 
81  def __init__(self, gitlab_data: GitLabData, name: str) -> None:
82  """Initialize the GitLab sensor."""
83  self._attr_available_attr_available = False
84  self._gitlab_data_gitlab_data = gitlab_data
85  self._attr_name_attr_name = name
86 
87  @property
88  def icon(self) -> str:
89  """Return the icon to use in the frontend."""
90  if self.native_valuenative_valuenative_value == "success":
91  return ICON_HAPPY
92  if self.native_valuenative_valuenative_value == "failed":
93  return ICON_SAD
94  return ICON_OTHER
95 
96  def update(self) -> None:
97  """Collect updated data from GitLab API."""
98  self._gitlab_data_gitlab_data.update()
99 
100  self._attr_native_value_attr_native_value = self._gitlab_data_gitlab_data.status
101  self._attr_extra_state_attributes_attr_extra_state_attributes = {
102  ATTR_BUILD_STATUS: self._gitlab_data_gitlab_data.status,
103  ATTR_BUILD_STARTED: self._gitlab_data_gitlab_data.started_at,
104  ATTR_BUILD_FINISHED: self._gitlab_data_gitlab_data.finished_at,
105  ATTR_BUILD_DURATION: self._gitlab_data_gitlab_data.duration,
106  ATTR_BUILD_COMMIT_ID: self._gitlab_data_gitlab_data.commit_id,
107  ATTR_BUILD_COMMIT_DATE: self._gitlab_data_gitlab_data.commit_date,
108  ATTR_BUILD_ID: self._gitlab_data_gitlab_data.build_id,
109  ATTR_BUILD_BRANCH: self._gitlab_data_gitlab_data.branch,
110  }
111  self._attr_available_attr_available = self._gitlab_data_gitlab_data.available
112 
113 
115  """GitLab Data object."""
116 
117  def __init__(self, gitlab_id, priv_token, interval, url):
118  """Fetch data from GitLab API for most recent CI job."""
119 
120  self._gitlab_id_gitlab_id = gitlab_id
121  self._gitlab_gitlab = Gitlab(url, private_token=priv_token, per_page=1)
122  self._gitlab_gitlab.auth()
123  self.updateupdate = Throttle(interval)(self._update_update)
124 
125  self.availableavailable = False
126  self.statusstatus = None
127  self.started_atstarted_at = None
128  self.finished_atfinished_at = None
129  self.durationduration = None
130  self.commit_idcommit_id = None
131  self.commit_datecommit_date = None
132  self.build_idbuild_id = None
133  self.branchbranch = None
134 
135  def _update(self) -> None:
136  try:
137  _projects = self._gitlab_gitlab.projects.get(self._gitlab_id_gitlab_id)
138  _last_pipeline = _projects.pipelines.list(page=1)[0]
139  _last_job = _last_pipeline.jobs.list(page=1)[0]
140  self.statusstatus = _last_pipeline.attributes.get("status")
141  self.started_atstarted_at = _last_job.attributes.get("started_at")
142  self.finished_atfinished_at = _last_job.attributes.get("finished_at")
143  self.durationduration = _last_job.attributes.get("duration")
144  _commit = _last_job.attributes.get("commit")
145  self.commit_idcommit_id = _commit.get("id")
146  self.commit_datecommit_date = _commit.get("committed_date")
147  self.build_idbuild_id = _last_job.attributes.get("id")
148  self.branchbranch = _last_job.attributes.get("ref")
149  self.availableavailable = True
150  except GitlabAuthenticationError as erra:
151  _LOGGER.error("Authentication Error: %s", erra)
152  self.availableavailable = False
153  except GitlabGetError as errg:
154  _LOGGER.error("Project Not Found: %s", errg)
155  self.availableavailable = False
def __init__(self, gitlab_id, priv_token, interval, url)
Definition: sensor.py:117
None __init__(self, GitLabData gitlab_data, str name)
Definition: sensor.py:81
StateType|date|datetime|Decimal native_value(self)
Definition: __init__.py:460
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: sensor.py:60
def add_entities(account, async_add_entities, tracked)
Definition: sensor.py:40