Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pywemo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .ouimeaux_device import Device as WeMoDevice
from .ouimeaux_device.bridge import Bridge
from .ouimeaux_device.coffeemaker import CoffeeMaker
from .ouimeaux_device.crockpot import CrockPot
from .ouimeaux_device.dimmer import Dimmer
from .ouimeaux_device.humidifier import Humidifier
from .ouimeaux_device.insight import Insight
Expand Down
3 changes: 3 additions & 0 deletions pywemo/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from .ouimeaux_device.api.xsd import device as deviceParser
from .ouimeaux_device.bridge import Bridge
from .ouimeaux_device.coffeemaker import CoffeeMaker
from .ouimeaux_device.crockpot import CrockPot
from .ouimeaux_device.dimmer import Dimmer
from .ouimeaux_device.humidifier import Humidifier
from .ouimeaux_device.insight import Insight
Expand Down Expand Up @@ -87,6 +88,8 @@ def device_from_uuid_and_location(uuid, location, debug=False):
return Bridge(location)
if uuid.startswith('uuid:CoffeeMaker'):
return CoffeeMaker(location)
if uuid.startswith('uuid:Crockpot'):
return CrockPot(location)
if uuid.startswith('uuid:Humidifier'):
return Humidifier(location)
if uuid.startswith('uuid:OutdoorPlug'):
Expand Down
111 changes: 111 additions & 0 deletions pywemo/ouimeaux_device/crockpot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"""Representation of a WeMo CrockPot device."""
from enum import IntEnum

from .switch import Switch


# These enums were derived from the CrockPot.basicevent.GetCrockpotState()
# service call. Thus these names/values were not chosen randomly and the
# numbers have meaning.
class CrockPotMode(IntEnum):
"""Modes for the CrockPot."""

Off = 0
Warm = 50
Low = 51
High = 52


MODE_NAMES = {
CrockPotMode.Off: "Turned Off",
CrockPotMode.Warm: "Warm",
CrockPotMode.Low: "Low",
CrockPotMode.High: "High",
}


class CrockPot(Switch):
"""WeMo Crockpot."""

def __init__(self, *args, **kwargs):
"""Create a WeMo CrockPot device."""
Switch.__init__(self, *args, **kwargs)
self._attributes = {}

def update_attributes(self):
"""Request state from device."""
state_attributes = self.basicevent.GetCrockpotState()

# Only update our state on complete updates from the device
if (
state_attributes is not None
and state_attributes["mode"] is not None
and state_attributes["time"] is not None
and state_attributes["cookedTime"] is not None
):
self._attributes = state_attributes
self._state = self.mode

def subscription_update(self, _type, _params):
"""Handle reports from device."""
if _params is None:
return False

if _type == "mode":
self._attributes['mode'] = str(_params)
self._state = self.mode
return True
if _type == "time":
self._attributes['time'] = str(_params)
return True
if _type == "cookedTime":
self._attributes['cookedTime'] = str(_params)
return True

return Switch.subscription_update(self, _type, _params)

@property
def mode(self) -> int:
"""Return the mode of the device."""
return int(self._attributes.get('mode'))

@property
def mode_string(self) -> str:
"""Return the mode of the device as a string."""
return MODE_NAMES.get(self.mode, "Unknown")

@property
def remaining_time(self) -> int:
"""Return the remaining time in minutes."""
return int(self._attributes.get('time'))

@property
def cooked_time(self) -> int:
"""Return the cooked time in minutes."""
return int(self._attributes.get('cookedTime'))

def get_state(self, force_update=False):
"""Return 0 if off and 1 if on."""
# The base implementation using GetBinaryState doesn't work for
# CrockPot (always returns 0) so use mode instead.
if force_update or self.mode is None:
self.update_attributes()

return int(self.mode != CrockPotMode.Off)

def set_state(self, state):
"""Set the state of this device to on or off."""
if state:
self.update_settings(
CrockPotMode.High, int(self._attributes.get('time'))
)
else:
self.update_settings(CrockPotMode.Off, 0)

def update_settings(self, mode: CrockPotMode, time: int):
"""Update mode and cooking time."""
self.basicevent.SetCrockpotState(mode=str(int(mode)), time=str(time))

# The CrockPot might not be ready - so it's not safe to assume the
# state is what you just set so re-read it from the device.
self.get_state(True)