Skip to content
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

Add Sleepiq services #30722

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CODEOWNERS
Validating CODEOWNERS rules …
Expand Up @@ -312,6 +312,7 @@ homeassistant/components/sighthound/* @robmarkcole
homeassistant/components/signal_messenger/* @bbernhard
homeassistant/components/simplisafe/* @bachya
homeassistant/components/sinch/* @bendikrb
homeassistant/components/sleepiq/* @Jay2645
homeassistant/components/sisyphus/* @jkeljo
homeassistant/components/slide/* @ualex73
homeassistant/components/sma/* @kellerza
Expand Down
70 changes: 70 additions & 0 deletions homeassistant/components/sleepiq/__init__.py
Expand Up @@ -19,10 +19,16 @@
SLEEP_NUMBER = "sleep_number"
SENSOR_TYPES = {SLEEP_NUMBER: "SleepNumber", IS_IN_BED: "Is In Bed"}

BED = "bed"
LEFT = "left"
PRESET_FAVORITE = 0
RIGHT = "right"
SIDE = "side"
SIDES = [LEFT, RIGHT]

SERVICE_SET_SLEEP_NUMBER = "set_sleep_number"
SERVICE_SET_FAVORITE = "set_to_favorite_sleep_number"

_LOGGER = logging.getLogger(__name__)

DATA = None
Expand Down Expand Up @@ -61,6 +67,22 @@ def setup(hass, config):
_LOGGER.error(message)
return False

def handle_set_number(call):
bed = call.data.get(BED, "")
side = call.data.get(SIDE, "")
new_sleep_number = call.data.get(SLEEP_NUMBER, 0)

DATA.set_new_sleep_number(bed, side, new_sleep_number)

def handle_set_favorite(call):
bed = call.data.get(BED, "")
side = call.data.get(SIDE, "")

DATA.set_to_favorite_sleep_number(bed, side)

hass.services.register(DOMAIN, SERVICE_SET_SLEEP_NUMBER, handle_set_number)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create service voluptuous schemas that validates the service data and pass the schema when registering the service. See other integrations for examples.

hass.services.register(DOMAIN, SERVICE_SET_FAVORITE, handle_set_favorite)

discovery.load_platform(hass, "sensor", DOMAIN, {}, config)
discovery.load_platform(hass, "binary_sensor", DOMAIN, {}, config)

Expand All @@ -85,6 +107,54 @@ def update(self):

self.beds = {bed.bed_id: bed for bed in beds}

def set_new_sleep_number(self, bed_name: str, side: str, sleep_number):
"""Change the sleep number on a side to a new value."""

# Sanity check: Sleep number has to be between 1-100.
if 0 < sleep_number <= 100:
self._set_sleep_number(bed_name, side, int(sleep_number))
else:
message = f"Invalid sleep number: {sleep_number}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't format the message before passing it to the logger. Use old style string formatting in combination with the logger to avoid not needed formatting if the logging isn't activated.

_LOGGER.warning(message)

def set_to_favorite_sleep_number(self, bed_name: str, side: str):
"""Change a side's sleep number to their 'favorite' setting."""
self._set_sleep_number(bed_name, side, PRESET_FAVORITE)

def get_favorite_sleep_number(self, bed_id: int, side: str) -> int:
"""Get a side's 'favorite' number, given a bed ID and a side."""
favorite_numbers = self._client.get_favsleepnumber(bed_id)
return getattr(favorite_numbers, side.lower())

def _set_sleep_number(self, bed_name: str, side: str, new_number: int):
"""Set the sleep number for a side on a bed."""
bed_name = bed_name.lower()
side = side.lower()

if len(side) == 0:
Jay2645 marked this conversation as resolved.
Show resolved Hide resolved
# No side specified, use both.
sides_to_set = SIDES
else:
# Just use the side we specified.
sides_to_set = [side]

for bed_id, bed_obj in self.beds.items():
# If no bed name is specified, set on all beds.
# Otherwise, ensure we only set on beds with the correct name.
if len(bed_name) == 0 or bed_name == bed_obj.name.lower():
Jay2645 marked this conversation as resolved.
Show resolved Hide resolved
for bed_side in sides_to_set:
# Check if we should use the "favorite" preset instead.
if new_number == PRESET_FAVORITE:
num = self.get_favorite_sleep_number(bed_id, bed_side)
else:
num = new_number

debug_msg = f"Setting {bed_side} of bed {bed_id} to {num}"
_LOGGER.debug(debug_msg)

# Actually set the Sleep Number.
self._client.set_sleepnumber(bed_id, bed_side, num)


class SleepIQSensor(Entity):
"""Implementation of a SleepIQ sensor."""
Expand Down
2 changes: 1 addition & 1 deletion homeassistant/components/sleepiq/manifest.json
Expand Up @@ -4,5 +4,5 @@
"documentation": "https://www.home-assistant.io/integrations/sleepiq",
"requirements": ["sleepyq==0.7"],
"dependencies": [],
"codeowners": []
"codeowners": ["@Jay2645"]
}
22 changes: 22 additions & 0 deletions homeassistant/components/sleepiq/services.yaml
@@ -0,0 +1,22 @@
set_sleep_number:
description: Changes the Sleep Number of a bed.
fields:
sleep_number:
description: The new sleep number, as a multiple of 5 between 5 and 100.
example: 45
bed:
description: The name of the bed. If unspecified, affects all beds.
example: 'Master Bedroom'
side:
description: The side to change. If unspecified, both sides will change.
example: 'right'

set_to_favorite_sleep_number:
description: Changes a bed's Sleep Number to the "favorite" preset.
fields:
bed:
description: The name of the bed. If unspecified, affects all beds.
example: 'Master Bedroom'
side:
description: The side to change. If unspecified, both sides will change.
example: 'right'