-
-
Notifications
You must be signed in to change notification settings - Fork 38.1k
Adds folder sensor #12208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds folder sensor #12208
Changes from 2 commits
ffd634f
f9707ce
adbbabc
16c078b
5ee5e0d
929b532
2c8bfc0
54739fb
5c8a792
c4cef26
07462e7
51bc020
6cb0695
e3615f8
117be0d
8c0c0a2
ff5872c
8fd2a71
6676eff
1974a7f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| """ | ||
| Sensor for monitoring the contents of a folder. | ||
|
|
||
| For more details about this platform, please refer to the documentation at | ||
| https://home-assistant.io/components/sensor.folder/ | ||
| """ | ||
| from datetime import datetime as dt | ||
| from datetime import timedelta | ||
| import glob | ||
| import logging | ||
| import os | ||
| import voluptuous as vol | ||
|
|
||
| from homeassistant.helpers.entity import Entity | ||
| from homeassistant.helpers.template import DATE_STR_FORMAT | ||
| import homeassistant.helpers.config_validation as cv | ||
| from homeassistant.components.sensor import PLATFORM_SCHEMA | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| CONF_FOLDER_PATHS = 'folder' | ||
| CONF_FILTER = 'filter' | ||
| DEFAULT_FILTER = '*' | ||
|
|
||
| SCAN_INTERVAL = timedelta(seconds=10) | ||
|
|
||
| PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ | ||
| vol.Required(CONF_FOLDER_PATHS): cv.isdir, | ||
| vol.Optional(CONF_FILTER, default=DEFAULT_FILTER): cv.string, | ||
| }) | ||
|
|
||
|
|
||
| def setup_platform(hass, config, add_devices, discovery_info=None): | ||
| """Set up the folder sensor.""" | ||
| folder = Folder(config.get(CONF_FOLDER_PATHS), config.get(CONF_FILTER)) | ||
| add_devices([folder], True) | ||
|
|
||
|
|
||
| class Folder(Entity): | ||
| """Representation of a folder.""" | ||
|
|
||
| ICON = 'mdi:folder' | ||
|
|
||
| def __init__(self, folder_path, filter_term): | ||
| """Initialize the data object.""" | ||
| folder_path = os.path.join(folder_path, '') # If no trailing / add it | ||
| self._folder_path = folder_path # Need to check its a valid path | ||
| self._filter_term = filter_term | ||
| self._sorted_files_list = [] | ||
| self._number_of_files = None | ||
| self._recent_modified_file = '' | ||
| self._last_updated = '' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Init as |
||
| self._name = folder_path.split("/")[-2] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You must not use Windows
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As in, this will not work on Windows? OK will try something else
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use https://docs.python.org/3/library/os.path.html#os.path.split or Pathlib
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
| self._unit_of_measurement = '' | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not an allowed unit of measurement. |
||
| self.update() | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this. It's already called during entity addition. |
||
|
|
||
| def update(self): | ||
| """Update the sensor.""" | ||
| self._sorted_files_list = self.get_sorted_files_list( | ||
| self._folder_path, self._filter_term) | ||
|
|
||
| self._recent_modified_file = self._sorted_files_list[-1] | ||
|
|
||
| self._last_updated = self.get_last_updated( | ||
| self._recent_modified_file) | ||
| return | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this unnecessary return statement. |
||
|
|
||
| def get_sorted_files_list(self, folder_path, filter_term): | ||
| """Rerturn the sorted list of files in a directory, applying filter. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo.... |
||
| List entired sorted by modified time, with most recent first.""" | ||
| query = folder_path + filter_term | ||
| files_list = glob.glob(query) | ||
| sorted_files_list = sorted(files_list, key=os.path.getmtime) | ||
| return sorted_files_list | ||
|
|
||
| def get_last_updated(self, recent_modified_file): | ||
| """Rerturn the datetime a file was last modified.""" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same...typo |
||
| modified_time = os.path.getmtime(recent_modified_file) | ||
| modified_time_datetime = dt.fromtimestamp(modified_time) | ||
| return modified_time_datetime.strftime(DATE_STR_FORMAT) | ||
|
|
||
| @property | ||
| def name(self): | ||
| """Return the name of the sensor.""" | ||
| return self._name | ||
|
|
||
| @property | ||
| def state(self): | ||
| """Return the state of the sensor.""" | ||
| return self._last_updated | ||
|
|
||
| @property | ||
| def icon(self): | ||
| """Icon to use in the frontend, if any.""" | ||
| return self.ICON | ||
|
|
||
| @property | ||
| def device_state_attributes(self): | ||
| """Return other details about the sensor state.""" | ||
| attrs = {} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please construct the whole dict directly. attr = {
'folder': self._folder_path,
...
} |
||
| attrs['folder'] = self._folder_path | ||
| attrs['filter'] = self._filter_term | ||
| attrs['modified_file'] = self._recent_modified_file.split('/')[-1] | ||
| attrs['number_of_files'] = len(self._sorted_files_list) | ||
| attrs['files'] = [f.split('/')[-1] for f in self._sorted_files_list] | ||
| return attrs | ||
|
|
||
| @property | ||
| def unit_of_measurement(self): | ||
| """Return the unit of measurement of this entity, if any.""" | ||
| return self._unit_of_measurement | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All paths have to be whitelisted by checking it with
hass.config.is_allowed_path(path)