home-assistant / architecture

Repo to discuss Home Assistant architecture
317 stars 100 forks source link

New Entity Proposal: Cooker #51

Closed arbreng closed 3 years ago

arbreng commented 6 years ago

I am in the process of adding support for my Anova Precision Cooker in the Google Assistant and Alexa components, however this is currently not possible as none of the current components really matches up well with its functionality.

Connected microwaves, ovens, tea kettles, and coffee pots are all things, but we have no good way to support them natively in Home Assistant.

I propose creating a new type of Entity: the Cooker. A Cooker can encompass anything that heats food or beverage to a set temperature, for a set time, or both.

This is needed if we want to expose cooker-type entities to assistant services, since breaking the cooker up into its constituent switches and sensors will not work well for that.

State

Properties

Microwaves use power instead of temperature, which would have to be accounted for somehow.

I have a PR open for the sous-vide type cooker here.

arbreng commented 6 years ago

FWIW this guy already said he would convert his MQTT-based solution to an mqtt cooker platform if we implement this:

https://community.home-assistant.io/t/anova-sous-vide-control-over-mqtt/48146

balloob commented 6 years ago

Don't have time for full feedback, but just to let you know that we cannot store relative times in the state machine (Time left on timer). Instead, you could store the timestamp that the cooker will be done.

awarecan commented 6 years ago

My thought on this:

State: [
  STATE_OFF,  # offline or idle
  STATE_ON,  # working
  STATE_DONE,  # depends on device, may means keep warming or idle
]

State Attributes: [
  'operation_mode': [Bake, Broil, Warming, etc]  # when state is in STATE_ON or STATE_DONE
  'done_at': date_time  # when the state will change / has changed from STATE_ON to STATE_DONE
  'current_temperature', 
  'target_temperature', 
]

Device Attributes: [
  'unit_of_measurement ',
  'min_temperature',
  'max_temperature', 
  'precision',  #  whole degrees or tenths of a degree
]

Supported Feature: [
  'support_turn_off',
  'support_turn_on',  # some appliance won't allow remote turn on, only be able to remote turn off 
]

Services: [
  'turn_off',
  'turn_on': {
    'service_data': ['operation_mode', 'target_temperate', 'operation_period']
]
arbreng commented 6 years ago

@awarecan Nice proposal, I've added a little bit to it.

Also, can you explain to me the difference between state attributes and device attributes? I'm still learning hass :house_with_garden: :smile:

State: [
  STATE_OFF,  # offline or idle
  STATE_PREHEAT,  #  most devices have some sort of preheat phase.  Could also re-use STATE_HEAT for this?
  STATE_ON,  # working; if any time is present it will start running now
  STATE_DONE,  # depends on device, may means keep warming or idle
  STATE_PROBLEM,  # general error condition
]

State Attributes: [
  'preparation_mode': [Preheat, None]
  'operation_mode': [Bake, Broil, Warming, Grinding, etc]  # Grinding is for coffee makers, and implies warming
  'prepared_at': date_time  # when the state will change / has changed from STATE_PREPARING to STATE_ON.  optional, only used if support_prepare_timer is true
  'done_at': date_time  # when the state will change / has changed from STATE_ON to STATE_DONE.
  'idle_at':  date_time # when the state will change / has changed from STATE_DONE to STATE_OFF
  'current_temperature', # None if supports_temperature is false
  'target_temperature', # None if supports_temperature is false
  'power_level',  #  Numeric power level.  Devices which use low/medium/high can be converted to 1,2,3.  None if supports_power is false
  'unit_of_measurement ',  # None if supports_temperature is false
  'min_temperature',  # None if supports_temperature is false
  'max_temperature',  # None if supports_temperature is false 
  'precision',  #  whole degrees or tenths of a degree.  None if supports_temperature is false
  'min_power',  # None if supports_power is false
  'max_power',  # None if supports_power is false
]

Supported Feature: [
  'support_turn_off',
  'support_turn_on',  # some appliance won't allow remote turn on, only be able to remote turn off 
  'support_temperature',  # some appliances support direct temperature control (oven and teakettle, but not microwave or coffee maker)
  'support_power',  # some appliances instead support control via power levels (microwave and coffee maker, but not oven or tea kettle)
  'support_timer',  # some devices support timed cooking (oven, but not coffee maker)
  'support_prepare_timer',  # some devices support timed prewarming (coffee maker, but not oven)
  'support_done_timer',  # most devices with keep warm support a timer for it
]

Services: [  # some devices allow setting these parameters ahead of time
  'set_preparation_mode':  { 'service_data': ['preparation_mode'] }
  'set_preparation_period':  { 'service_data': ['preparation_period'] }
  'set_operation_mode':  { 'service_data': ['operation_mode'] }
  'set_operation_period':  { 'service_data': ['operation_period'] }
  'set_temperature': { 'service_data': ['target_temperature'] }
  'set_power': { 'service_data': ['power_level'] }

  'turn_off',
  'turn_on': {  'service_data': ['preparation_mode', 'preparation_period', 'operation_mode', 'target_temperate', 'power_level', 'operation_period'] }
]

I'm not sure how to support extra modes or toggles yet. I might look at the vacuum component for inspiration

I own the 4 devices that I linked in the OP, and this state should be able to support all 4 of them.

awarecan commented 6 years ago

Also, can you explain to me the difference between state attributes and device attributes?

I actually have same question, because device_state_attributes will override state_attributes... I finally found a piece of document this time

In order to expose attributes for a platform, you will need to define a property called device_state_attributes on the entity class, which will return a dictionary of attributes:

Entities also have a similar property state_attributes, which normally doesn't need to be defined by new platforms. This property is used by base components to add standard sets of attributes to a state. Example: The light component uses state_attributes to add brightness to the state dictionary. If you are designing a new component, you should define state_attributes instead. ref

arbreng commented 6 years ago

Awesome, thanks for the docs.

That means state_attributes is for all of the attributes we are defining here. device_state_attributes will be specific to the platform and won't have anything list here. Example: Anova lets you read calibration_factor and temperature_history.

I updated my proposal to reflect that everything should belong in state_attributes for what we are discussing now.

I also have a question about component/directory structure for these things. The type of entity is cooker, and I have multiple platforms to add. Even though 2 of the new platforms are by the same company (Smarter), I keep them as separate platforms because the config info is different per device.

Here is the proposed structure:

homeassistant/
    components/
        cooker/
            __init__.py
            anova.py  ## Configuration is bluetooh MAC of device, don't want an 'anova' component.

            demo.py  ## Will contain code for a a demo sous-vide, oven, microwave, coffee, and tea based on supported_features.  Similar to vacuum demo

            mqtt_anova.py  ## Do we want to merge with anova and make it a config of that platform to switch between bluetooth or MQTT?

            smarter_coffee.py   ## Configuration is IP:Port of device, do we still want a 'smarter' component?  Do we want a single 'smarter' platform with coffee or tea as a config (they both use the same library)?

            smarter_tea.py  ## Configuration is IP:Port of device, do we still want a 'smarter' component?
Do we want a single 'smarter' platform with coffee or tea as a config (they both use the same library)?

            whirlpool_microwave.py  # Will probably be combined with a whirlpool: component for login info
tests/
    components/
        cooker/
            __init__.py
            test_anova.py
            test_demo.py
            test_smarter_coffee.py
            test_smarter_tea.py

(I don't know how to write tests for mqtt_sous_vide or whirlpool_microwave yet)

awarecan commented 6 years ago

Component should support only one communication protocol, BLE and TCP/IP should resident in different component as my understanding.

MQTT is a different story, IMO, you should have a cooker/mqtt.py, not cooker/mqtt_anova.py. I know you familiar with vacuum component, you can reference vacuum/mqtt.py

demo.py is not for specific brand or communication protocol, it basic use as an example for other developers and for unit test purpose.

rytilahti commented 6 years ago

@syssi has a rice cooker, so pinging him if he has some ideas / to let him know this is being discussed here.

balloob commented 6 years ago

Had some time for this, this looks ok. Most of the linked examples companies like the ones for smart kettle or coffeemaker will probably be out of business in a couple of years, but sure let's add them to the mix ☕️ .

aprosvetova commented 5 years ago

Take a look at this. https://github.com/aprosvetova/xiaomi-kettle

arbreng commented 5 years ago

Awesome, ty. Looking into this over the weekend

niemyjski commented 5 years ago

I think this would be super useful

Hypfer commented 5 years ago

I second this. I've taken @aprosvetova s research and built an MQTT Bridge for the Mi Smart Kettle, but I can't really use it within HA because it doesn't match any existing entity.

ajdezigns commented 4 years ago

https://github.com/roblandry/pywemo/tree/crockpot This would make a good addition to this component

ajmarks commented 4 years ago

This would be fantastic. I'm currently working on a Python API for GE kitchen appliances, starting with my oven. I'd love to create an HA integration as well, but without a matching entity type, all I can do is be hacky with sensors and switches (and maybe water heaters?).

ajmarks commented 4 years ago

To maybe add a little motivation here, I've been able to implement a halfway (well, eighthway, anyway) decent oven and a pretty solid fridge using the WaterHeaterEntity for GE appliances. It's not ideal, but it's a very good start. This make me think that could be used to bootstrap a proper Cooker or Cooler entity.

Oven controls

sebirdman commented 3 years ago

I've begun thinking about this for my Traeger grill integration. While some of this makes sense for my cooker some of it doesn't quite line up with what I'd need.

I'm curious why this proposal and the climate/water heater entities are so specific?

It feels like it would be more powerful to have all these entities become collections of even smaller parts such as:

This would handle setting a temperature and maintaining a temperature. Could have the properties suggested above.

This would be an entity that basically lets you set modes in a drop down of some kind.

These two small entities would let any kind of device take advantage of these kinds of features. This way we can handle edge cases in higher level logic instead of continuing to duplicate entity logic (like we have now with climate and water heaters)

I can create more formal proposals for these if anyone's interested.

Edit: Renamed SwitchEntity because of course that already exists xD