Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Reddit."""
2 
3 from __future__ import annotations
4 
5 from datetime import timedelta
6 import logging
7 
8 import praw
9 import voluptuous as vol
10 
12  PLATFORM_SCHEMA as SENSOR_PLATFORM_SCHEMA,
13  SensorEntity,
14 )
15 from homeassistant.const import (
16  ATTR_ID,
17  CONF_CLIENT_ID,
18  CONF_CLIENT_SECRET,
19  CONF_MAXIMUM,
20  CONF_PASSWORD,
21  CONF_USERNAME,
22 )
23 from homeassistant.core import HomeAssistant
25 from homeassistant.helpers.entity_platform import AddEntitiesCallback
26 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
27 
28 _LOGGER = logging.getLogger(__name__)
29 
30 CONF_SORT_BY = "sort_by"
31 CONF_SUBREDDITS = "subreddits"
32 
33 ATTR_BODY = "body"
34 ATTR_COMMENTS_NUMBER = "comms_num"
35 ATTR_CREATED = "created"
36 ATTR_POSTS = "posts"
37 ATTR_SUBREDDIT = "subreddit"
38 ATTR_SCORE = "score"
39 ATTR_TITLE = "title"
40 ATTR_URL = "url"
41 
42 DEFAULT_NAME = "Reddit"
43 
44 DOMAIN = "reddit"
45 
46 LIST_TYPES = ["top", "controversial", "hot", "new"]
47 
48 SCAN_INTERVAL = timedelta(seconds=300)
49 
50 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
51  {
52  vol.Required(CONF_CLIENT_ID): cv.string,
53  vol.Required(CONF_CLIENT_SECRET): cv.string,
54  vol.Required(CONF_USERNAME): cv.string,
55  vol.Required(CONF_PASSWORD): cv.string,
56  vol.Required(CONF_SUBREDDITS): vol.All(cv.ensure_list, [cv.string]),
57  vol.Optional(CONF_SORT_BY, default="hot"): vol.All(
58  cv.string, vol.In(LIST_TYPES)
59  ),
60  vol.Optional(CONF_MAXIMUM, default=10): cv.positive_int,
61  }
62 )
63 
64 
66  hass: HomeAssistant,
67  config: ConfigType,
68  add_entities: AddEntitiesCallback,
69  discovery_info: DiscoveryInfoType | None = None,
70 ) -> None:
71  """Set up the Reddit sensor platform."""
72  subreddits = config[CONF_SUBREDDITS]
73  user_agent = f"{config[CONF_USERNAME]}_home_assistant_sensor"
74  limit = config[CONF_MAXIMUM]
75  sort_by = config[CONF_SORT_BY]
76 
77  try:
78  reddit = praw.Reddit(
79  client_id=config[CONF_CLIENT_ID],
80  client_secret=config[CONF_CLIENT_SECRET],
81  username=config[CONF_USERNAME],
82  password=config[CONF_PASSWORD],
83  user_agent=user_agent,
84  )
85 
86  _LOGGER.debug("Connected to praw")
87 
88  except praw.exceptions.PRAWException as err:
89  _LOGGER.error("Reddit error %s", err)
90  return
91 
92  sensors = [
93  RedditSensor(reddit, subreddit, limit, sort_by) for subreddit in subreddits
94  ]
95  add_entities(sensors, True)
96 
97 
99  """Representation of a Reddit sensor."""
100 
101  def __init__(self, reddit, subreddit: str, limit: int, sort_by: str) -> None:
102  """Initialize the Reddit sensor."""
103  self._reddit_reddit = reddit
104  self._subreddit_subreddit = subreddit
105  self._limit_limit = limit
106  self._sort_by_sort_by = sort_by
107 
108  self._subreddit_data_subreddit_data: list = []
109 
110  @property
111  def name(self):
112  """Return the name of the sensor."""
113  return f"reddit_{self._subreddit}"
114 
115  @property
116  def native_value(self):
117  """Return the state of the sensor."""
118  return len(self._subreddit_data_subreddit_data)
119 
120  @property
122  """Return the state attributes."""
123  return {
124  ATTR_SUBREDDIT: self._subreddit_subreddit,
125  ATTR_POSTS: self._subreddit_data_subreddit_data,
126  CONF_SORT_BY: self._sort_by_sort_by,
127  }
128 
129  @property
130  def icon(self):
131  """Return the icon to use in the frontend."""
132  return "mdi:reddit"
133 
134  def update(self) -> None:
135  """Update data from Reddit API."""
136  self._subreddit_data_subreddit_data = []
137 
138  try:
139  subreddit = self._reddit_reddit.subreddit(self._subreddit_subreddit)
140  if hasattr(subreddit, self._sort_by_sort_by):
141  method_to_call = getattr(subreddit, self._sort_by_sort_by)
142 
143  for submission in method_to_call(limit=self._limit_limit):
144  self._subreddit_data_subreddit_data.append(
145  {
146  ATTR_ID: submission.id,
147  ATTR_URL: submission.url,
148  ATTR_TITLE: submission.title,
149  ATTR_SCORE: submission.score,
150  ATTR_COMMENTS_NUMBER: submission.num_comments,
151  ATTR_CREATED: submission.created,
152  ATTR_BODY: submission.selftext,
153  }
154  )
155 
156  except praw.exceptions.PRAWException as err:
157  _LOGGER.error("Reddit error %s", err)
None __init__(self, reddit, str subreddit, int limit, str sort_by)
Definition: sensor.py:101
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:70