Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Show the amount of records in a user's Discogs collection."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 import random
8 
9 import discogs_client
10 import voluptuous as vol
11 
13  PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
14  SensorEntity,
15  SensorEntityDescription,
16 )
17 from homeassistant.const import CONF_MONITORED_CONDITIONS, CONF_NAME, CONF_TOKEN
18 from homeassistant.core import HomeAssistant
19 from homeassistant.helpers.aiohttp_client import SERVER_SOFTWARE
21 from homeassistant.helpers.entity_platform import AddEntitiesCallback
22 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
23 
24 _LOGGER = logging.getLogger(__name__)
25 
26 ATTR_IDENTITY = "identity"
27 
28 DEFAULT_NAME = "Discogs"
29 
30 ICON_RECORD = "mdi:album"
31 ICON_PLAYER = "mdi:record-player"
32 UNIT_RECORDS = "records"
33 
34 SCAN_INTERVAL = timedelta(minutes=10)
35 
36 SENSOR_COLLECTION_TYPE = "collection"
37 SENSOR_WANTLIST_TYPE = "wantlist"
38 SENSOR_RANDOM_RECORD_TYPE = "random_record"
39 
40 SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
42  key=SENSOR_COLLECTION_TYPE,
43  name="Collection",
44  icon=ICON_RECORD,
45  native_unit_of_measurement=UNIT_RECORDS,
46  ),
48  key=SENSOR_WANTLIST_TYPE,
49  name="Wantlist",
50  icon=ICON_RECORD,
51  native_unit_of_measurement=UNIT_RECORDS,
52  ),
54  key=SENSOR_RANDOM_RECORD_TYPE,
55  name="Random Record",
56  icon=ICON_PLAYER,
57  ),
58 )
59 SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES]
60 
61 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
62  {
63  vol.Required(CONF_TOKEN): cv.string,
64  vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
65  vol.Optional(CONF_MONITORED_CONDITIONS, default=SENSOR_KEYS): vol.All(
66  cv.ensure_list, [vol.In(SENSOR_KEYS)]
67  ),
68  }
69 )
70 
71 
73  hass: HomeAssistant,
74  config: ConfigType,
75  add_entities: AddEntitiesCallback,
76  discovery_info: DiscoveryInfoType | None = None,
77 ) -> None:
78  """Set up the Discogs sensor."""
79  token = config[CONF_TOKEN]
80  name = config[CONF_NAME]
81 
82  try:
83  _discogs_client = discogs_client.Client(SERVER_SOFTWARE, user_token=token)
84 
85  discogs_data = {
86  "user": _discogs_client.identity().name,
87  "folders": _discogs_client.identity().collection_folders,
88  "collection_count": _discogs_client.identity().num_collection,
89  "wantlist_count": _discogs_client.identity().num_wantlist,
90  }
91  except discogs_client.exceptions.HTTPError:
92  _LOGGER.error("API token is not valid")
93  return
94 
95  monitored_conditions = config[CONF_MONITORED_CONDITIONS]
96  entities = [
97  DiscogsSensor(discogs_data, name, description)
98  for description in SENSOR_TYPES
99  if description.key in monitored_conditions
100  ]
101 
102  add_entities(entities, True)
103 
104 
106  """Create a new Discogs sensor for a specific type."""
107 
108  _attr_attribution = "Data provided by Discogs"
109 
110  def __init__(
111  self, discogs_data, name, description: SensorEntityDescription
112  ) -> None:
113  """Initialize the Discogs sensor."""
114  self.entity_descriptionentity_description = description
115  self._discogs_data_discogs_data = discogs_data
116  self._attrs_attrs: dict = {}
117 
118  self._attr_name_attr_name = f"{name} {description.name}"
119 
120  @property
122  """Return the device state attributes of the sensor."""
123  if self._attr_native_value_attr_native_value is None or self._attrs_attrs is None:
124  return None
125 
126  if (
127  self.entity_descriptionentity_description.key == SENSOR_RANDOM_RECORD_TYPE
128  and self._attr_native_value_attr_native_value is not None
129  ):
130  return {
131  "cat_no": self._attrs_attrs["labels"][0]["catno"],
132  "cover_image": self._attrs_attrs["cover_image"],
133  "format": (
134  f"{self._attrs['formats'][0]['name']} ({self._attrs['formats'][0]['descriptions'][0]})"
135  ),
136  "label": self._attrs_attrs["labels"][0]["name"],
137  "released": self._attrs_attrs["year"],
138  ATTR_IDENTITY: self._discogs_data_discogs_data["user"],
139  }
140 
141  return {
142  ATTR_IDENTITY: self._discogs_data_discogs_data["user"],
143  }
144 
145  def get_random_record(self):
146  """Get a random record suggestion from the user's collection."""
147  # Index 0 in the folders is the 'All' folder
148  collection = self._discogs_data_discogs_data["folders"][0]
149  if collection.count > 0:
150  random_index = random.randrange(collection.count)
151  random_record = collection.releases[random_index].release
152 
153  self._attrs_attrs = random_record.data
154  return (
155  f"{random_record.data['artists'][0]['name']} -"
156  f" {random_record.data['title']}"
157  )
158 
159  return None
160 
161  def update(self) -> None:
162  """Set state to the amount of records in user's collection."""
163  if self.entity_descriptionentity_description.key == SENSOR_COLLECTION_TYPE:
164  self._attr_native_value_attr_native_value = self._discogs_data_discogs_data["collection_count"]
165  elif self.entity_descriptionentity_description.key == SENSOR_WANTLIST_TYPE:
166  self._attr_native_value_attr_native_value = self._discogs_data_discogs_data["wantlist_count"]
167  else:
168  self._attr_native_value_attr_native_value = self.get_random_recordget_random_record()
None __init__(self, discogs_data, name, SensorEntityDescription description)
Definition: sensor.py:112
None setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: sensor.py:77
def add_entities(account, async_add_entities, tracked)
Definition: sensor.py:40