Skip to content

Commit

Permalink
Add Teams Presence Sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
RogerSelwyn committed Feb 11, 2022
1 parent 5734711 commit a92a0a6
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 37 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Under "Api Permissions" click Add a permission and add the following delegated p
* Mail.Send - *Send mail as a user*
* Mail.Send.Shared - *Send mail on behalf of others*
* Users.Read - *Sign in and read user profile*
*
* Presence.Read - *Read user's presence information* (Required for Teams Presence Sensor)
## Adding to Home Assistant

### Using Home Assistant Community Store (HACS)
Expand Down Expand Up @@ -71,6 +71,8 @@ o365:
has_attachment: True
max_items: 2
is_unread: True
status_sensors:
- name: "User Teams Status"
```
## notify.o365_email service data
Expand Down Expand Up @@ -125,6 +127,11 @@ Key | Type | Required | Description
`subject_contains` | `string` | `False` | Only get emails where the subject contains this string (Mutually exclusive with `subject_is`)
`subject_is` | `string` | `False` | Only get emails where the subject equals exactly this string (Mutually exclusive with `subject_contains`)

### status_sensors
Key | Type | Required | Description
-- | -- | -- | --
`name` | `string` | `True` | The name of the sensor.

## Calendar configuration
This component has changed to now using an external o365_calendars.yaml file, this is done to align this component more with the official Google Calendar Event integration.
### example o365_calendar.yaml:
Expand Down
30 changes: 9 additions & 21 deletions custom_components/o365/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,14 @@
from homeassistant.helpers.network import get_url
from O365 import Account, FileSystemTokenBackend

from .const import (
AUTH_CALLBACK_NAME,
AUTH_CALLBACK_PATH,
AUTH_CALLBACK_PATH_ALT,
CONF_ALT_CONFIG,
CONF_CALENDARS,
CONF_CLIENT_ID,
CONF_CLIENT_SECRET,
CONF_EMAIL_SENSORS,
CONF_QUERY_SENSORS,
CONF_TRACK_NEW,
CONFIG_SCHEMA,
CONFIGURATOR_DESCRIPTION,
CONFIGURATOR_LINK_NAME,
CONFIGURATOR_SUBMIT_CAPTION,
DEFAULT_CACHE_PATH,
DEFAULT_NAME,
DOMAIN,
SCOPE,
TOKEN_FILENAME,
)
from .const import (AUTH_CALLBACK_NAME, AUTH_CALLBACK_PATH,
AUTH_CALLBACK_PATH_ALT, CONF_ALT_CONFIG, CONF_CALENDARS,
CONF_CLIENT_ID, CONF_CLIENT_SECRET, CONF_EMAIL_SENSORS,
CONF_STATUS_SENSORS, CONF_QUERY_SENSORS, CONF_TRACK_NEW,
CONFIG_SCHEMA, CONFIGURATOR_DESCRIPTION,
CONFIGURATOR_LINK_NAME, CONFIGURATOR_SUBMIT_CAPTION,
DEFAULT_CACHE_PATH, DEFAULT_NAME, DOMAIN, SCOPE,
TOKEN_FILENAME)
from .utils import build_config_file_path, validate_permissions

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -92,6 +79,7 @@ def do_setup(hass, config, account):
"account": account,
CONF_EMAIL_SENSORS: config.get(CONF_EMAIL_SENSORS, []),
CONF_QUERY_SENSORS: config.get(CONF_QUERY_SENSORS, []),
CONF_STATUS_SENSORS: config.get(CONF_STATUS_SENSORS, []),
CONF_TRACK_NEW: config.get(CONF_TRACK_NEW, True),
}
hass.async_create_task(
Expand Down
8 changes: 4 additions & 4 deletions custom_components/o365/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ def extra_state_attributes(self):
"offset_reached": self._offset_reached,
"data": self._data_attribute,
}
else:
return {
"data": self._data_attribute,
}

return {
"data": self._data_attribute,
}

@property
def event(self):
Expand Down
15 changes: 9 additions & 6 deletions custom_components/o365/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,8 @@

import homeassistant.helpers.config_validation as cv
import voluptuous as vol
from homeassistant.components.notify import (
ATTR_DATA,
ATTR_MESSAGE,
ATTR_TARGET,
ATTR_TITLE,
)
from homeassistant.components.notify import (ATTR_DATA, ATTR_MESSAGE,
ATTR_TARGET, ATTR_TITLE)
from homeassistant.config import get_default_config_dir
from homeassistant.const import CONF_NAME
from O365.calendar import AttendeeType # pylint: disable=no-name-in-module
Expand Down Expand Up @@ -76,6 +72,7 @@ class EventResponse(Enum):
CONF_MAIL_FOLDER = "folder"
CONF_MAIL_FROM = "from"
CONF_MAX_ITEMS = "max_items"
CONF_STATUS_SENSORS = "status_sensors"
CONF_QUERY_SENSORS = "query_sensors"
CONF_SUBJECT_CONTAINS = "subject_contains"
CONF_SUBJECT_IS = "subject_is"
Expand Down Expand Up @@ -130,6 +127,11 @@ class EventResponse(Enum):
vol.Optional(CONF_IS_UNREAD): bool,
}
)
STATUS_SENSOR = vol.Schema(
{
vol.Required(CONF_NAME): cv.string,
}
)
QUERY_SENSOR = vol.Schema(
{
vol.Required(CONF_NAME): cv.string,
Expand All @@ -154,6 +156,7 @@ class EventResponse(Enum):
vol.Optional(CONF_CALENDARS, default=[]): [CALENDAR_SCHEMA],
vol.Optional(CONF_EMAIL_SENSORS): [EMAIL_SENSOR],
vol.Optional(CONF_QUERY_SENSORS): [QUERY_SENSOR],
vol.Optional(CONF_STATUS_SENSORS): [STATUS_SENSOR],
},
)
},
Expand Down
43 changes: 38 additions & 5 deletions custom_components/o365/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
from .const import (CONF_EMAIL_SENSORS, CONF_HAS_ATTACHMENT, CONF_IMPORTANCE,
CONF_IS_UNREAD, CONF_MAIL_FOLDER, CONF_MAIL_FROM,
CONF_MAX_ITEMS, CONF_NAME, CONF_QUERY_SENSORS,
CONF_SUBJECT_CONTAINS, CONF_SUBJECT_IS, DOMAIN)
CONF_STATUS_SENSORS, CONF_SUBJECT_CONTAINS,
CONF_SUBJECT_IS, DOMAIN)
from .utils import get_email_attributes

_LOGGER = logging.getLogger(__name__)
Expand All @@ -28,6 +29,7 @@ def setup_platform(

_unread_sensors(hass, account, add_devices)
_query_sensors(hass, account, add_devices)
_status_sensors(hass, account, add_devices)

return True

Expand All @@ -48,6 +50,13 @@ def _query_sensors(hass, account, add_devices):
add_devices([sensor], True)


def _status_sensors(hass, account, add_devices):
status_sensors = hass.data[DOMAIN].get(CONF_STATUS_SENSORS, [])
for conf in status_sensors:
teams_status_sensor = O365TeamsStatusSensor(account, conf)
add_devices([teams_status_sensor], True)


def _get_mail_folder(account, conf, sensor_type):
"""Get the configured folder."""
mailbox = account.mailbox()
Expand All @@ -73,7 +82,7 @@ def _get_mail_folder(account, conf, sensor_type):
return mail_folder


class O365Sensor:
class O365MailSensor:
"""O365 generic Sensor class."""

def __init__(self, conf, mail_folder):
Expand Down Expand Up @@ -114,7 +123,7 @@ def update(self):
self._attributes = {"data": attrs}


class O365QuerySensor(O365Sensor, Entity):
class O365QuerySensor(O365MailSensor, Entity):
"""O365 Query sensor processing."""

def __init__(self, conf, mail_folder):
Expand Down Expand Up @@ -164,8 +173,8 @@ def _add_to_query(self, qtype, attribute_name, attribute_value, check_value=True
self.query.chain("and").on_attribute(attribute_name).equals(attribute_value)


class O365InboxSensor(O365Sensor, Entity):
"""O365 Inboox processing."""
class O365InboxSensor(O365MailSensor, Entity):
"""O365 Inbox processing."""

def __init__(self, conf, mail_folder):
"""Initialise the O365 Inbox."""
Expand All @@ -177,3 +186,27 @@ def __init__(self, conf, mail_folder):
if self.is_unread is not None:
self.query = self.mail_folder.new_query()
self.query.chain("and").on_attribute("IsRead").equals(not self.is_unread)


class O365TeamsStatusSensor(Entity):
"""O365 Teams sensor processing."""

def __init__(self, account, conf):
"""Initialise the Teams Sensor."""
self.teams = account.teams()
self._name = conf.get(CONF_NAME)
self._state = None

@property
def name(self):
"""Sensor name."""
return self._name

@property
def state(self):
"""Sensor state."""
return self._state

def update(self):
"""Update state."""
self._state = self.teams.get_my_presence().activity

0 comments on commit a92a0a6

Please sign in to comment.