Skip to content

Commit

Permalink
feat: Add set user preferred status service
Browse files Browse the repository at this point in the history
  • Loading branch information
RogerSelwyn committed Mar 1, 2024
1 parent ab55429 commit 481caad
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 6 deletions.
31 changes: 31 additions & 0 deletions custom_components/o365/classes/teamssensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from homeassistant.const import ATTR_NAME, CONF_EMAIL
from homeassistant.exceptions import ServiceValidationError

from O365.teams import PreferredActivity, PreferredAvailability

from ..const import (
ATTR_ACTIVITY,
ATTR_AVAILABILITY,
Expand All @@ -23,6 +25,7 @@
DOMAIN,
EVENT_HA_EVENT,
EVENT_SEND_CHAT_MESSAGE,
EVENT_UPDATE_USER_PREFERRED_STATUS,
EVENT_UPDATE_USER_STATUS,
PERM_CHAT_READWRITE,
PERM_MINIMUM_CHAT_WRITE,
Expand Down Expand Up @@ -91,6 +94,34 @@ def update_user_status(self, availability, activity, expiration_duration=None):
)
return False

def update_user_preferred_status(self, availability, expiration_duration=None):
"""Update the users teams status."""
if self._email:
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="not_possible",
translation_placeholders={
CONF_EMAIL: self._email,
},
)

if not self._validate_status_permissions():
return False

activity = (
availability
if availability != PreferredAvailability.OFFLINE
else PreferredActivity.OFFWORK
)
status = self.teams.set_my_user_preferred_presence(
availability, activity, expiration_duration
)
self._raise_event(
EVENT_UPDATE_USER_PREFERRED_STATUS,
{ATTR_AVAILABILITY: status.availability, ATTR_ACTIVITY: status.activity},
)
return False

def _raise_event(self, event_type, status):
self.hass.bus.fire(
f"{DOMAIN}_{event_type}",
Expand Down
1 change: 1 addition & 0 deletions custom_components/o365/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ class EventResponse(Enum):
EVENT_RESPOND_CALENDAR_EVENT = "respond_calendar_event"
EVENT_SEND_CHAT_MESSAGE = "send_chat_message"
EVENT_UPDATE_USER_STATUS = "update_user_status"
EVENT_UPDATE_USER_PREFERRED_STATUS = "update_user_preferred_status"

LEGACY_ACCOUNT_NAME = "converted"
O365_STORAGE = "o365_storage"
Expand Down
3 changes: 2 additions & 1 deletion custom_components/o365/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"auto_reply_enable": "mdi:microsoft-outlook",
"auto_reply_disable": "mdi:microsoft-outlook",
"send_chat_message": "mdi:microsoft-teams",
"update_user_status": "mdi:microsoft-teams"
"update_user_status": "mdi:microsoft-teams",
"update_user_preferred_status": "mdi:microsoft-teams"
},
"entity": {
"sensor": {
Expand Down
2 changes: 1 addition & 1 deletion custom_components/o365/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/RogerSelwyn/O365-HomeAssistant/issues",
"requirements": [
"O365==2.0.33",
"O365==2.0.34",
"BeautifulSoup4>=4.10.0"
],
"version": "v4.7.0b1"
Expand Down
9 changes: 7 additions & 2 deletions custom_components/o365/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
ATTR_TITLE,
)
from homeassistant.const import CONF_EMAIL, CONF_ENABLED, CONF_NAME

from O365.calendar import ( # pylint: disable=no-name-in-module
AttendeeType,
EventSensitivity,
Expand All @@ -17,7 +18,7 @@
from O365.mailbox import ( # pylint: disable=no-name-in-module, import-error
ExternalAudience,
)
from O365.teams import Activity, Availability
from O365.teams import Activity, Availability, PreferredAvailability
from O365.utils import ImportanceLevel # pylint: disable=no-name-in-module

from .const import (
Expand Down Expand Up @@ -252,13 +253,17 @@
vol.Required(ATTR_EVENT_ID): cv.string,
}


STATUS_SERVICE_UPDATE_USER_STATUS_SCHEMA = {
vol.Required(ATTR_AVAILABILITY): vol.Coerce(Availability),
vol.Required(ATTR_ACTIVITY): vol.Coerce(Activity),
vol.Optional(ATTR_EXPIRATIONDURATION): cv.string,
}

STATUS_SERVICE_UPDATE_USER_PERERRED_STATUS_SCHEMA = {
vol.Required(ATTR_AVAILABILITY): vol.Coerce(PreferredAvailability),
vol.Optional(ATTR_EXPIRATIONDURATION): cv.string,
}

TODO_SERVICE_NEW_SCHEMA = {
vol.Required(ATTR_SUBJECT): cv.string,
vol.Optional(ATTR_DESCRIPTION): cv.string,
Expand Down
6 changes: 6 additions & 0 deletions custom_components/o365/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
AUTO_REPLY_SERVICE_DISABLE_SCHEMA,
AUTO_REPLY_SERVICE_ENABLE_SCHEMA,
CHAT_SERVICE_SEND_MESSAGE_SCHEMA,
STATUS_SERVICE_UPDATE_USER_PERERRED_STATUS_SCHEMA,
STATUS_SERVICE_UPDATE_USER_STATUS_SCHEMA,
)

Expand Down Expand Up @@ -140,6 +141,11 @@ async def _async_setup_status_services(config, perms):
STATUS_SERVICE_UPDATE_USER_STATUS_SCHEMA,
"update_user_status",
)
platform.async_register_entity_service(
"update_user_preferred_status",
STATUS_SERVICE_UPDATE_USER_PERERRED_STATUS_SCHEMA,
"update_user_preferred_status",
)


async def _async_setup_chat_services(config, perms):
Expand Down
39 changes: 39 additions & 0 deletions custom_components/o365/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -519,3 +519,42 @@ update_user_status:
required: false
selector:
text:

update_user_preferred_status:
name: Update user preferred Teams status
description: "Update the user's preferred Teams status"
target:
device:
integration: o365
entity:
integration: o365
domain: sensor
fields:
availability:
name: Availability
description: "The base presence information"
example: Busy
required: true
selector:
select:
mode: dropdown
options:
- label: "Available"
value: "Available"
- label: "Busy"
value: "Busy"
- label: "Do Not Disturb"
value: "DoNotDisturb"
- label: "Be Right Back"
value: "BeRightBack"
- label: "Away"
value: "Away"
- label: "Offline"
value: "Offline"
expiration_duration:
name: Expiration Duration
description: "The expiration of the app presence session. The value is represented in ISO 8601 format for durations"
example: PT1H
required: false
selector:
text:
14 changes: 12 additions & 2 deletions docs/services.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ These services must be targeted at a `status` sensor. They can only target the l
### o365.update_user_status
Update Teams status for the logged in client. This will not override a status that is set via the MS Teams client. Allowable pairings of availability and activity are show in the [MS Graph Documentation](https://learn.microsoft.com/en-us/graph/api/presence-setpresence?view=graph-rest-1.0&tabs=http#request-body). The expiration/duration field is also documented on the same page. It defaults to 5 minutes.

#### Example update status service call
#### Example update user status service call

```yaml
service: o365.update_user_status
Expand All @@ -168,6 +168,16 @@ data:
target:
entity_id: sensor.roger_teams_status
```
### o365.update_user_preferred_status
Update Teams preferred status for the logged-in user. This is equivalent to setting status within the Teams client. Allowable pairings of availability and activity are show in the [MS Graph Documentation](https://learn.microsoft.com/en-us/graph/api/presence-setuserpreferredpresence?view=graph-rest-1.0&tabs=http#request-body). The expiration/duration field is also documented on the same page. If not provided, a default expiration will be applied: DoNotDisturb or Busy - Expiration in 1 day; All others - Expiration in 7 days

#### Example update user preferred status service call

https://learn.microsoft.com/en-us/graph/api/presence-setpresence?view=graph-rest-1.0&tabs=http#request-body
```yaml
service: o365.update_user_preferred_status
data:
availability: Offline
expiration_duration: PT1H
target:
entity_id: sensor.roger_teams_status
```

0 comments on commit 481caad

Please sign in to comment.