From b7b1db79baa6b9876f6e718abedd16601794accb Mon Sep 17 00:00:00 2001 From: Emil Horpen Hetty Date: Wed, 27 Jul 2016 02:33:01 +0300 Subject: [PATCH 01/41] Added name option --- source/_components/sensor.yweather.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/_components/sensor.yweather.markdown b/source/_components/sensor.yweather.markdown index 899a0c0b704..b91d46d4426 100644 --- a/source/_components/sensor.yweather.markdown +++ b/source/_components/sensor.yweather.markdown @@ -45,6 +45,7 @@ sensor: platform: yweather woeid: YOUR_WOEID forecast: 3 + name: OPTIONAL_NAME monitored_conditions: - weather - temp_min @@ -55,6 +56,7 @@ Configuration variables: - **woeid** (*Optional*): See above. - **forecast** (*Optional*): Day of forecast. The default is the current day to display conditions. +- **name** (*Optional*): The name of the sensor. - **monitored_conditions** array (*Required*): Conditions to display in the frontend. - **weather**: A human-readable text summary with picture from yahoo. - **weather_current**: A human-readable text summary with picture from yahoo from current conditon. From 835bf7183fa11462ec003babe5fea53227031eb0 Mon Sep 17 00:00:00 2001 From: Emil Horpen Hetty Date: Wed, 27 Jul 2016 21:58:57 +0300 Subject: [PATCH 02/41] Update sensor.yweather.markdown --- source/_components/sensor.yweather.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_components/sensor.yweather.markdown b/source/_components/sensor.yweather.markdown index b91d46d4426..92bf8e303d2 100644 --- a/source/_components/sensor.yweather.markdown +++ b/source/_components/sensor.yweather.markdown @@ -56,7 +56,7 @@ Configuration variables: - **woeid** (*Optional*): See above. - **forecast** (*Optional*): Day of forecast. The default is the current day to display conditions. -- **name** (*Optional*): The name of the sensor. +- **name** (*Optional*): The name of the sensor. To easily recognize each sensor when adding more than one Yahoo weather sensor, it is recommended to use the name option. - **monitored_conditions** array (*Required*): Conditions to display in the frontend. - **weather**: A human-readable text summary with picture from yahoo. - **weather_current**: A human-readable text summary with picture from yahoo from current conditon. From 4a8137a89441c4dd0dc23675997969f7e33af977 Mon Sep 17 00:00:00 2001 From: Andrew Cockburn Date: Tue, 16 Aug 2016 03:36:54 -0400 Subject: [PATCH 03/41] Add APPDaemon BLOG entry (#758) * Add APPDaemon BLOG entry * Add more tag and make sections headers linkable * Add more tag and make sections headers linkable * Fix typo --- .../2016-08-09-we-have-apps-now.markdown | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100755 source/_posts/2016-08-09-we-have-apps-now.markdown diff --git a/source/_posts/2016-08-09-we-have-apps-now.markdown b/source/_posts/2016-08-09-we-have-apps-now.markdown new file mode 100755 index 00000000000..7c122331c0e --- /dev/null +++ b/source/_posts/2016-08-09-we-have-apps-now.markdown @@ -0,0 +1,132 @@ +--- +layout: post +title: "We Have Apps Now" +description: "A new subsystem that allows automations to be coded using Python" +date: 2016-08-09 14:00:00 -0400 +date_formatted: "August 09, 2016" +author: Andrew Cockburn +comments: true +categories: How-To +--- + +I have been working on a new subsystem to complement Home Assistant's Automation and Scripting components. `AppDaemon` is a python daemon that consumes events from Home Assistant and feeds them to snippets of python code called "Apps". An App is a Python class that is instantiated possibly multiple times from `AppDaemon` and registers callbacks for various system events. It is also able to inspect and set state and call services. The API provides a rich environment suited to home automation tasks that can also leverage all the power of Python. + + + +## {% linkable_title Another Take on Automation %} + +If you haven't yet read Paulus' excellent Blog entry on [Perfect Home Automation](https://home-assistant.io/blog/2016/01/19/perfect-home-automation/) I would encourage you to take a look. As a veteran of several Home Automation systems with varying degrees success, it was this article more than anything else that convinced me that Home Assistant had the right philosophy behind it and was on the right track. One of the most important points made is that being able to control your lights from your phone, 9 times out of 10 is harder than using a lightswitch - where Home Automation really comes into its own is when you start removing the need to use a phone or the switch - the "Automation" in Home Automation. A surprisingly large number of systems out there miss this essential point and have limited abilities to automate anything which is why a robust and open system such as Home Assistant is such an important part of the equation to bring this all together in the vast and chaotic ecosystem that is the "Internet of Things". + +So given the importance of Automation, what should Automation allow us to do? I am a pragmatist at heart so I judge individual systems by the ease of accomplishing a few basic but representative tasks: + +- Can the system respond to presence or absence of people? +- Can I turn a light on at Sunset +/- a certain amount of time? +- Can I arrive home in light or dark and have the lights figure out if they should be on or off? +- As I build my system out, can I get the individual pieces to co-operate and use and re-use (potentially complex) logic to make sure everything works smoothly? +- Is it open and expandable? +- Does it run locally without any reliance on the cloud? + +In my opinion, Home Assistant accomplishes the majority of these very well with a combination of Automations, Scripts and Templates, and it's Restful API. + +So why `AppDaemon`? `AppDaemon` is not meant to replace Home Assistant Automations and Scripts, rather complement them. For a lot of things, automations work well and can be very succinct. However, there is a class of more complex automations for which they become harder to use, and appdeamon then comes into its own. It brings quite a few things to the table: + +- New paradigm - some problems require a procedural and/or iterative approach, and `AppDaemon` Apps are a much more natural fit for this. Recent enhancements to Home Assistant scripts and templates have made huge strides, but for the most complex scenarios, Apps can do things that Automations can't +- Ease of use - `AppDaemon`'s API is full of helper functions that make programming as easy and natural as possible. The functions and their operation are as "Pythonic" as possible, experienced Python programmers should feel right at home. +- Reuse - write a piece of code once and instantiate it as an app as many times as you need with different parameters e.g. a motion light program that you can use in 5 different places around your home. The code stays the same, you just dynamically add new instances of it in the config file +- Dynamic - `AppDaemon` has been designed from the start to enable the user to make changes without requiring a restart of Home Assistant, thanks to it's loose coupling. However, it is better than that - the user can make changes to code and `AppDaemon` will automatically reload the code, figure out which Apps were using it and restart them to use the new code without the need to restart `AppDaemon` itself. It is also possible to change parameters for an individual or multiple apps and have them picked up dynamically, and for a final trick, removing or adding apps is also picked up dynamically. Testing cycles become a lot more efficient as a result. +- Complex logic - Python's If/Else constructs are clearer and easier to code for arbitrarily complex nested logic +- Durable variables and state - variables can be kept between events to keep track of things like the number of times a motion sensor has been activated, or how long it has been since a door opened +- All the power of Python - use any of Python's libraries, create your own modules, share variables, refactor and re-use code, create a single app to do everything, or multiple apps for individual tasks - nothing is off limits! + +It is in fact a testament to Home Assistant's open nature that a component like `AppDaemon` can be integrated so neatly and closely that it acts in all ways like an extension of the system, not a second class citizen. Part of the strength of Home Assistant's underlying design is that it makes no assumptions whatever about what it is controlling or reacting to, or reporting state on. This is made achievable in part by the great flexibility of Python as a programming environment for Home Assistant, and carrying that forward has enabled me to use the same philosophy for `AppDaemon` - it took surprisingly little code to be able to respond to basic events and call services in a completely open ended manner - the bulk of the work after that was adding additonal functions to make things that were already possible easier. + +## {% linkable_title How it Works %} + +The best way to show what `AppDaemon` does is through a few simple examples. + +### {% linkable_title Sunrise/Sunset Lighting %} + +Lets start with a simple App to turn a light on every night at sunset and off every morning at sunrise. Every App when first started will have its `initialize()` function called which gives it a chance to register a callback for `AppDaemons`'s scheduler for a specific time. In this case we are using `run_at_sunrise()` and `run_at_sunset()` to register 2 separate callbacks. The argument `0` is the number of seconds offset from sunrise or sunset and can be negative or positive. For complex intervals it can be convenient to use Python's `datetime.timedelta` class for calculations. When sunrise or sunset occurs, the appropriate callback function, `sunrise_cb()` or `sunset_cb()` is called which then makes a call to Home Assistant to turn the porch light on or off by activating a scene. The variables `args["on_scene"]` and `args["off_scene"]` are passed through from the configuration of this particular App, and the same code could be reused to activate completely different scenes in a different version of the App. + +```python +import appapi + +class OutsideLights(appapi.AppDaemon): + + def initialize(self): + self.run_at_sunrise(self.sunrise_cb, 0) + self.run_at_sunset(self.sunset_cb, 0) + + def sunrise_cb(self, args, kwargs): + self.turn_on(self.args["off_scene"]) + + def sunset_cb(self, args, kwargs): + self.turn_on(self.args["on_scene"]) + +``` + +This is also fairly easy to achieve with Home Assistant automations, but we are just getting started. + +### {% linkable_title Motion Light %} + +Our next example is to turn on a light when motion is detected and it is dark, and turn it off after a period of time. This time, the `initialize()` function registers a callback on a state change (of the motion sensor) rather than a specific time. We tell `AppDaemon` that we are only interested in state changes where the motion detector comes on by adding an additional parameter to the callback registration - `new = "on"`. When the motion is detected, the callack function `motion()` is called, and we check whether or not the sun has set using a built-in convenience function: `sun_down()`. Next, we turn the light on with `turn_on()`, then set a timer using `run_in()` to turn the light off after 60 seconds, which is another call to the scheduler to execute in a set time from now, which results in `AppDaemon` calling `light_off()` 60 seconds later using the `turn_off()` call to actually turn the light off. This is still pretty simple in code terms: + +```python +import appapi + +class MotionLights(appapi.AppDaemon): + + def initialize(self): + self.listen_state(self.motion, "binary_sensor.drive", new = "on") + + def motion(self, entity, attribute, old, new, kwargs): + if self.sun_down(): + self.turn_on("light.drive") + self.run_in(self.light_off, 60) + + def light_off(self, kwargs): + self.turn_off("light.drive") +``` + +This is starting to get a little more complex in Home Assistant automations requiring an Automation rule and two separate scripts. + +Now lets extend this with a somewhat artificial example to show something that is simple in `AppDaemon` but very difficult if not impossible using automations. Lets warn someone inside the house that there has been motion outside by flashing a lamp on and off 10 times. We are reacting to the motion as before by turning on the light and setting a timer to turn it off again, but in addition, we set a 1 second timer to run `flash_warning()` which when called, toggles the inside light and sets another timer to call itself a second later. To avoid re-triggering forever, it keeps a count of how many times it has been activated and bales out after 10 iterations. + +```python +import appapi + +class FlashyMotionLights(appapi.AppDaemon): + + def initialize(self): + self.listen_state(self.motion, "binary_sensor.drive", new = "on") + + def motion(self, entity, attribute, old, new, kwargs): + if self.self.sun_down(): + self.turn_on("light.drive") + self.run_in(self.light_off, 60) + self.flashcount = 0 + self.run_in(self.flash_warning, 1) + + def light_off(self, kwargs): + self.turn_off("light.drive") + + def flash_warning(self, kwargs): + self.toggle("light.living_room") + self.flashcount += 1 + if self.flashcount < 10: + self.run_in(self.flash_warning, 1) +``` + +Of course if I wanted to make this App or its predecessor reusable I would have provided parameters for the sensor, the light to activate on motion, the warning light and even the number of flashes and delay between flashes. + +In addition, Apps can write to `AppDaemon`'s logfiles, and there is a system of constraints that allows yout to control when and under what circumstances Apps and callbacks are active to keep the logic clean and simple. + +I have spent the last few weeks moving all of my (fairly complex) automations over to `APPDaemon` and so far it is working very reliably. + +Some people will maybe look at all of this and say "what use is this, I can already do all of this", and that is fine, as I said this is an alternative not a replacement, but I am hopeful that for some users this will seem a more natural, powerful and nimble way of building potentially very complex automations. + +If this has whet your appetite, feel free to give it a try. You can find it, [here](https://github.com/acockburn/appdaemon), including full installation instructions, an API reference, and a number of fully fleshed out examples. + +Happy Automating! + + From 8db83c1feb2628c580d766f6d3188df44361e22a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 16 Aug 2016 09:38:01 +0200 Subject: [PATCH 04/41] Rename blog post --- ...have-apps-now.markdown => 2016-08-16-we-have-apps-now.markdown | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/_posts/2016-08-09-we-have-apps-now.markdown => 2016-08-16-we-have-apps-now.markdown (100%) diff --git a/source/_posts/2016-08-09-we-have-apps-now.markdown b/2016-08-16-we-have-apps-now.markdown similarity index 100% rename from source/_posts/2016-08-09-we-have-apps-now.markdown rename to 2016-08-16-we-have-apps-now.markdown From 71ce65c5a2b74698eb9ccaf472759aa9ef2c9c2f Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 16 Aug 2016 09:51:36 +0200 Subject: [PATCH 05/41] Update date --- 2016-08-16-we-have-apps-now.markdown | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/2016-08-16-we-have-apps-now.markdown b/2016-08-16-we-have-apps-now.markdown index 7c122331c0e..a1c0eb8451a 100755 --- a/2016-08-16-we-have-apps-now.markdown +++ b/2016-08-16-we-have-apps-now.markdown @@ -2,11 +2,12 @@ layout: post title: "We Have Apps Now" description: "A new subsystem that allows automations to be coded using Python" -date: 2016-08-09 14:00:00 -0400 -date_formatted: "August 09, 2016" +date: 2016-08-16 06:00:00 -0400 +date_formatted: "August 16, 2016" author: Andrew Cockburn comments: true categories: How-To +og_image: /images/blog/default-social.png --- I have been working on a new subsystem to complement Home Assistant's Automation and Scripting components. `AppDaemon` is a python daemon that consumes events from Home Assistant and feeds them to snippets of python code called "Apps". An App is a Python class that is instantiated possibly multiple times from `AppDaemon` and registers callbacks for various system events. It is also able to inspect and set state and call services. The API provides a rich environment suited to home automation tasks that can also leverage all the power of Python. @@ -128,5 +129,3 @@ Some people will maybe look at all of this and say "what use is this, I can alre If this has whet your appetite, feel free to give it a try. You can find it, [here](https://github.com/acockburn/appdaemon), including full installation instructions, an API reference, and a number of fully fleshed out examples. Happy Automating! - - From eccd26a171f626e7a4b9831fd5df0127ee50d25a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 16 Aug 2016 09:55:41 +0200 Subject: [PATCH 06/41] Move to system monitoring --- source/_components/sensor.snmp.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_components/sensor.snmp.markdown b/source/_components/sensor.snmp.markdown index dbb531f4e58..dad233bf380 100644 --- a/source/_components/sensor.snmp.markdown +++ b/source/_components/sensor.snmp.markdown @@ -8,7 +8,7 @@ comments: false sharing: true footer: true logo: network-snmp.png -ha_category: Sensor +ha_category: System Monitor ha_iot_class: "Local Polling" ha_release: "0.22" --- From 01c598e1d7927b8eee7563561436338b0db60773 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 16 Aug 2016 10:05:04 +0200 Subject: [PATCH 07/41] Make title linkable --- source/_components/sensor.apcupsd.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_components/sensor.apcupsd.markdown b/source/_components/sensor.apcupsd.markdown index c93291ff725..1e46ca35e97 100644 --- a/source/_components/sensor.apcupsd.markdown +++ b/source/_components/sensor.apcupsd.markdown @@ -36,7 +36,7 @@ Configuration variables: - **resources** array (*Required*): Contains all entries to display. -#### Example +### {% linkable_title Example %} Given the following output from `apcaccess`: From d32f21954376e615389cf65eb569e21e7dff84a7 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Tue, 16 Aug 2016 14:15:01 +0200 Subject: [PATCH 08/41] Move the blog post into the right folder --- .../_posts/2016-08-16-we-have-apps-now.markdown | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename 2016-08-16-we-have-apps-now.markdown => source/_posts/2016-08-16-we-have-apps-now.markdown (100%) diff --git a/2016-08-16-we-have-apps-now.markdown b/source/_posts/2016-08-16-we-have-apps-now.markdown similarity index 100% rename from 2016-08-16-we-have-apps-now.markdown rename to source/_posts/2016-08-16-we-have-apps-now.markdown From d76d99c36a2d48d728695b2f316044f05925b212 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 16 Aug 2016 08:57:33 -0700 Subject: [PATCH 09/41] Update social image we have apps now --- source/_posts/2016-08-16-we-have-apps-now.markdown | 1 - 1 file changed, 1 deletion(-) diff --git a/source/_posts/2016-08-16-we-have-apps-now.markdown b/source/_posts/2016-08-16-we-have-apps-now.markdown index a1c0eb8451a..cc6ed602fc9 100755 --- a/source/_posts/2016-08-16-we-have-apps-now.markdown +++ b/source/_posts/2016-08-16-we-have-apps-now.markdown @@ -7,7 +7,6 @@ date_formatted: "August 16, 2016" author: Andrew Cockburn comments: true categories: How-To -og_image: /images/blog/default-social.png --- I have been working on a new subsystem to complement Home Assistant's Automation and Scripting components. `AppDaemon` is a python daemon that consumes events from Home Assistant and feeds them to snippets of python code called "Apps". An App is a Python class that is instantiated possibly multiple times from `AppDaemon` and registers callbacks for various system events. It is also able to inspect and set state and call services. The API provides a rich environment suited to home automation tasks that can also leverage all the power of Python. From da93836e227b8b72eb3e18a2df631abf52252e86 Mon Sep 17 00:00:00 2001 From: John Lindley Date: Tue, 16 Aug 2016 20:04:18 -0400 Subject: [PATCH 10/41] Fixed broken link from https://ohmconnect.com/ to https://www.ohmconnect.com/ --- source/_components/sensor.ohmconnect.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_components/sensor.ohmconnect.markdown b/source/_components/sensor.ohmconnect.markdown index 1bae8f6f8a5..9cc10a56258 100644 --- a/source/_components/sensor.ohmconnect.markdown +++ b/source/_components/sensor.ohmconnect.markdown @@ -14,7 +14,7 @@ ha_release: 0.26 --- -The `ohmconnect` sensor will show you the current [OhmConnect](https://ohmconnect.com) status for the given OhmConnect ID. +The `ohmconnect` sensor will show you the current [OhmConnect](https://www.ohmconnect.com/) status for the given OhmConnect ID. > OhmConnect monitors real-time conditions on the electricity grid. When dirty and unsustainable power plants turn on, our users receive a notification to save energy. By saving energy at that time, California does not have to turn on additional power plants and California's energy authorities pay you for that. From fc942a9b5e9e6fb43375ffb1fe6d5dd2515857c7 Mon Sep 17 00:00:00 2001 From: Tom Behets Date: Wed, 17 Aug 2016 12:54:38 +0200 Subject: [PATCH 11/41] small typo (#794) --- source/_components/modbus.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_components/modbus.markdown b/source/_components/modbus.markdown index 133e1692097..9f206276fc7 100644 --- a/source/_components/modbus.markdown +++ b/source/_components/modbus.markdown @@ -29,7 +29,7 @@ modbus: Configuration variables: -- **type** (*Required*): Type of the connection to Modebus. +- **type** (*Required*): Type of the connection to Modbus. - **host** (*Required*): The IP address of your router, eg. 192.168.1.1. - **port** (*Required*): The port for the comminication. From 0f665e48862029b4e79a4c56d599d43035457b80 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 17 Aug 2016 08:04:16 +0200 Subject: [PATCH 12/41] Add port --- source/developers/development_validation.markdown | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/developers/development_validation.markdown b/source/developers/development_validation.markdown index cd36cb57315..34b82d77ae9 100644 --- a/source/developers/development_validation.markdown +++ b/source/developers/development_validation.markdown @@ -57,15 +57,14 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ ### {% linkable_title Port %} -As all port numbers are coming out of the range 1 till 65535 a range check should be performed. +As all port numbers are coming out of the range 1 till 65535. ```python DEFAULT_PORT = 993 PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ ... - vol.Optional(CONF_PORT, default=DEFAULT_PORT): - vol.All(vol.Coerce(int), vol.Range(min=1, max=65535)), + vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, ``` ### {% linkable_title Sensor types %} From 7ba873a03e167d42438aaccecb5fdc8a87259b98 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Wed, 17 Aug 2016 13:53:30 +0200 Subject: [PATCH 13/41] Mark example as JSON --- source/_components/sensor.mqtt.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/_components/sensor.mqtt.markdown b/source/_components/sensor.mqtt.markdown index d1704a7bf07..29510c858a5 100644 --- a/source/_components/sensor.mqtt.markdown +++ b/source/_components/sensor.mqtt.markdown @@ -65,7 +65,7 @@ sensor: If you are using a DHT sensor and a NodeMCU board (esp8266), you can retrieve temperature and humidity with a MQTT sensor. A code example can be found [here](https://github.com/mertenats/open-home-automation/tree/master/ha_mqtt_sensor_dht22). A regular MQTT message from this example looks like this: -``` +```json office/sensor1 { "temperature": 23.20, From d813cf1e2750ae7ac0e0f982502575c7f688069c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 17 Aug 2016 18:50:31 -0700 Subject: [PATCH 14/41] Update snapcast --- .../_components/media_player.snapcast.markdown | 10 +++++----- source/images/supported_brands/snapcast.png | Bin 0 -> 24653 bytes 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 source/images/supported_brands/snapcast.png diff --git a/source/_components/media_player.snapcast.markdown b/source/_components/media_player.snapcast.markdown index f694932b9b6..080d3a2e2b3 100644 --- a/source/_components/media_player.snapcast.markdown +++ b/source/_components/media_player.snapcast.markdown @@ -1,21 +1,21 @@ --- layout: page -title: "SnapCast" -description: "Instructions on how to integrate SnapCast into Home Assistant." +title: "Snapcast" +description: "Instructions on how to integrate Snapcast into Home Assistant." date: 2016-02-01 19:00 sidebar: true comments: false sharing: true footer: true -logo: +logo: snapcast.png ha_category: Media Player featured: false ha_release: 0.13 --- -The `snapcast` platform allows you to control [SnapCast](https://github.com/badaix/snapcast) from Home Assistant. +The `snapcast` platform allows you to control [Snapcast](https://github.com/badaix/snapcast) from Home Assistant. -To add SnapCast to your installation, add the following to your `configuration.yaml` file: +To add Snapcast to your installation, add the following to your `configuration.yaml` file: ```yaml # Example configuration.yaml entry diff --git a/source/images/supported_brands/snapcast.png b/source/images/supported_brands/snapcast.png new file mode 100644 index 0000000000000000000000000000000000000000..8baa14fa102b2e082238ab451eee538009fa981b GIT binary patch literal 24653 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

G^nj9|J+#2Y*77>}Z)XR8Yxh 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 B(e?lU literal 0 HcmV?d00001 From 95b8444ecf164499099376ddbbc1d380f45270b1 Mon Sep 17 00:00:00 2001 From: Robbie Trencheny Date: Wed, 17 Aug 2016 22:02:31 -0700 Subject: [PATCH 15/41] Pushbullet not PushBullet --- source/_components/notify.pushbullet.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/_components/notify.pushbullet.markdown b/source/_components/notify.pushbullet.markdown index 5860998a158..1d58f8bf193 100644 --- a/source/_components/notify.pushbullet.markdown +++ b/source/_components/notify.pushbullet.markdown @@ -1,6 +1,6 @@ --- layout: page -title: "PushBullet" +title: "Pushbullet" description: "Instructions how to add user notifications to Home Assistant." date: 2015-01-20 22:36 sidebar: true @@ -12,9 +12,9 @@ ha_category: Notifications featured: true --- -The `pushbullet` notification platform sends messages to [PushBullet](https://www.pushbullet.com/), a free service to send information between your phones, browsers, and friends. +The `pushbullet` notification platform sends messages to [Pushbullet](https://www.pushbullet.com/), a free service to send information between your phones, browsers, and friends. -To enable PushBullet notifications in your installation, add the following to your `configuration.yaml` file: +To enable Pushbullet notifications in your installation, add the following to your `configuration.yaml` file: ```yaml # Example configuration.yaml entry @@ -26,12 +26,12 @@ notify: Configuration variables: -- **api_key** (*Required*): Enter the API key for PushBullet. Go to https://www.pushbullet.com/ to retrieve your API key. +- **api_key** (*Required*): Enter the API key for Pushbullet. Go to https://www.pushbullet.com/ to retrieve your API key. - **name** (*Optional*): Setting the optional parameter `name` allows multiple notifiers to be created. The default value is `notify`. The notifier will bind to the service `notify.NOTIFIER_NAME`. ### {% linkable_title Usage %} -PushBullet is a notify platform and thus can be controlled by calling the notify service [as described here](/components/notify/). It will send a notification to all devices registered in the PushBullet account. An optional **target** parameter can be given to PushBullet to specify specific account's devices, contacts or channels. +Pushbullet is a notify platform and thus can be controlled by calling the notify service [as described here](/components/notify/). It will send a notification to all devices registered in the Pushbullet account. An optional **target** parameter can be given to Pushbullet to specify specific account's devices, contacts or channels. Type | Prefix | Suffix | Example ---- | ------ | ------ | ------- From fe13d53fe5f7345060f46f5da763b70f60be1a93 Mon Sep 17 00:00:00 2001 From: andrew-curtis Date: Thu, 18 Aug 2016 15:42:50 +1000 Subject: [PATCH 16/41] Update input_slider.markdown (#795) * Update input_slider.markdown Was missing practical code examples. hopefully someone else will find this useful. Can someone please check my comments in the code examples about the use of 'data_template: '? Is 'input variables' the correct term here? * Update input_slider.markdown --- source/_components/input_slider.markdown | 75 ++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/source/_components/input_slider.markdown b/source/_components/input_slider.markdown index 0fc6fc08975..be056b391eb 100644 --- a/source/_components/input_slider.markdown +++ b/source/_components/input_slider.markdown @@ -34,3 +34,78 @@ Configuration variables: - **max** (*Optional*): Maximum value for the slider. - **step** (*Optional*): Step value for the slider. +# Automation Examples + +Here's an example of `input_slider` being used as a trigger in an automation. + +{% raw %} +``` +# Example configuration.yaml entry using 'input_slider' as a trigger in an automation + +# Define input_slider +input_slider: + bedroom_brightness: + name: Brightness + initial: 254 + min: 0 + max: 254 + step: 1 + +# Automation. +automation: + - alias: Bedroom Light - Adjust Brightness + trigger: + platform: state + entity_id: input_slider.bedroom_brightness + action: + - service: light.turn_on +# Note the use of 'data_template:' below rather than the normal 'data:' if you weren't using an input variable + data_template: + entity_id: light.bedroom + brightness: '{{ trigger.to_state.state | int }}' +``` +{% endraw %} + +Another code example using `input_slider`, this time being used in an action in an automation. + +{% raw %} +``` +# Example configuration.yaml entry using 'input_slider' in an action in an automation + +# Define 'input_select' +input_select: + scene_bedroom: + name: Scene + options: + - Select + - Concentrate + - Energize + - Reading + - Relax + - 'OFF' + initial: 'Select' + +# Define input_slider +input_slider: + bedroom_brightness: + name: Brightness + initial: 254 + min: 0 + max: 254 + step: 1 + +# Automation. +automation: + - alias: Bedroom Light - Custom + trigger: + platform: state + entity_id: input_select.scene_bedroom + to: CUSTOM + action: + - service: light.turn_on +# Again, note the use of 'data_template:' rather than the normal 'data:' if you weren't using an input variable. + data_template: + entity_id: light.bedroom + brightness: '{{ states.input_slider.bedroom_brightness.state | int }}' +``` +{% endraw %} From a9ea2066de02a9e6f8008ea1d4ffd8379cfc8b56 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 18 Aug 2016 07:49:20 +0200 Subject: [PATCH 17/41] Update list --- source/developers/development_validation.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/developers/development_validation.markdown b/source/developers/development_validation.markdown index 34b82d77ae9..5e87ad5e553 100644 --- a/source/developers/development_validation.markdown +++ b/source/developers/development_validation.markdown @@ -67,7 +67,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port, ``` -### {% linkable_title Sensor types %} +### {% linkable_title Lists %} If a sensor has a pre-defined list of available options it should be tested if the configuration entry matches it. @@ -80,7 +80,7 @@ SENSOR_TYPES = { PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ ... vol.Optional(CONF_MONITORED_VARIABLES, default=[]): - [vol.In(SENSOR_TYPES)], + vol.All(ensure_list, [vol.In(SENSOR_TYPES)]), ``` From a0dc4382bbd77e5da18799861709a3cff703809a Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 18 Aug 2016 07:50:57 +0200 Subject: [PATCH 18/41] Move raw --- source/_components/input_slider.markdown | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/_components/input_slider.markdown b/source/_components/input_slider.markdown index be056b391eb..a4f4ebd9ce6 100644 --- a/source/_components/input_slider.markdown +++ b/source/_components/input_slider.markdown @@ -38,8 +38,9 @@ Configuration variables: Here's an example of `input_slider` being used as a trigger in an automation. -{% raw %} + ``` +{% raw %} # Example configuration.yaml entry using 'input_slider' as a trigger in an automation # Define input_slider @@ -63,13 +64,13 @@ automation: data_template: entity_id: light.bedroom brightness: '{{ trigger.to_state.state | int }}' -``` {% endraw %} +``` Another code example using `input_slider`, this time being used in an action in an automation. -{% raw %} ``` +{% raw %} # Example configuration.yaml entry using 'input_slider' in an action in an automation # Define 'input_select' @@ -107,5 +108,6 @@ automation: data_template: entity_id: light.bedroom brightness: '{{ states.input_slider.bedroom_brightness.state | int }}' -``` {% endraw %} +``` + From 76425c9f4442f6b6f1a5fe77212639af2a5abe4b Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Thu, 18 Aug 2016 07:56:03 +0200 Subject: [PATCH 19/41] Make title linkable and format sample as yaml --- source/_components/input_slider.markdown | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/_components/input_slider.markdown b/source/_components/input_slider.markdown index a4f4ebd9ce6..4d9765bec0f 100644 --- a/source/_components/input_slider.markdown +++ b/source/_components/input_slider.markdown @@ -34,12 +34,11 @@ Configuration variables: - **max** (*Optional*): Maximum value for the slider. - **step** (*Optional*): Step value for the slider. -# Automation Examples +## {% linkable_title Automation Examples %} Here's an example of `input_slider` being used as a trigger in an automation. - -``` +```yaml {% raw %} # Example configuration.yaml entry using 'input_slider' as a trigger in an automation @@ -69,7 +68,7 @@ automation: Another code example using `input_slider`, this time being used in an action in an automation. -``` +```yaml {% raw %} # Example configuration.yaml entry using 'input_slider' in an action in an automation @@ -96,7 +95,7 @@ input_slider: step: 1 # Automation. -automation: +automation: - alias: Bedroom Light - Custom trigger: platform: state From 7b9364b56f7d3f092170d7738893b3ee3c89facb Mon Sep 17 00:00:00 2001 From: Teagan Glenn Date: Thu, 18 Aug 2016 12:10:33 -0600 Subject: [PATCH 20/41] flake8 hook needs a type! --- source/developers/development_testing.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/developers/development_testing.markdown b/source/developers/development_testing.markdown index 6845acfc617..4226fbe1d26 100644 --- a/source/developers/development_testing.markdown +++ b/source/developers/development_testing.markdown @@ -37,7 +37,7 @@ You can save yourself the hassle of extra commits just to fix style errors by en ```bash $ pip3 install flake8 flake8-docstrings -$ flake8 --install-hook +$ flake8 --install-hook=git ``` The flake8-docstrings extension will check docstrings according to [PEP257](https://www.python.org/dev/peps/pep-0257/) when running flake8. From 5d43377f7e2ad14e63d8723390602da9737cc9d9 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 18 Aug 2016 13:04:11 -0700 Subject: [PATCH 21/41] Update templating.markdown --- source/_topics/templating.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/_topics/templating.markdown b/source/_topics/templating.markdown index 0918ded8050..9090180b9d9 100644 --- a/source/_topics/templating.markdown +++ b/source/_topics/templating.markdown @@ -143,11 +143,11 @@ If only 1 location is passed in will measure the distance from home. {% raw %} Using Lat Lng coordinates: {{ distance(123.45, 123.45) }} -Using State: {{ distance(device_tracker.paulus) }} +Using State: {{ distance(states.device_tracker.paulus) }} These can also be combined in any combination: -{{ distance(123.45, 123.45, device_tracker.paulus) }} -{{ distance(device_tracker.anne_therese, device_tracker.paulus) }}{% endraw %} +{{ distance(123.45, 123.45, 'device_tracker.paulus') }} +{{ distance('device_tracker.anne_therese', 'device_tracker.paulus') }}{% endraw %} ``` ### {% linkable_title Closest examples %} @@ -157,7 +157,7 @@ Find entities closest to the Home Assistant location: ```jinja2 {% raw %} Query all entities: {{ closest(states) }} -Query all entities of a specific domain: {{ closest(states.device_tracker) }} +Query all entities of a specific domain: {{ closest('states.device_tracker') }} Query all entities in group.children: {{ closest('group.children') }} Query all entities in group.children: {{ closest(states.group.children) }}{% endraw %} ``` From 47a6123acf22b70d0f7db717e9495c2097203e1c Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 18 Aug 2016 22:49:33 -0700 Subject: [PATCH 22/41] Release 0.26.3 --- .../2016-08-13-foursquare--fast.com--ffmpeg--gpsd.markdown | 5 +++++ source/index.html | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source/_posts/2016-08-13-foursquare--fast.com--ffmpeg--gpsd.markdown b/source/_posts/2016-08-13-foursquare--fast.com--ffmpeg--gpsd.markdown index 56046fa08ea..d06a7d29486 100644 --- a/source/_posts/2016-08-13-foursquare--fast.com--ffmpeg--gpsd.markdown +++ b/source/_posts/2016-08-13-foursquare--fast.com--ffmpeg--gpsd.markdown @@ -54,6 +54,10 @@ This release includes code contributed by 31 different people. The biggest chang - Fix Wemo: have PyWemo play nicely with the latest Requests ([@pavoni]) +### {% linkable_title Hotfix 0.26.3 - August 19 %} + +- Media Player cover art would not work when an API password was set. Thanks to [@maddox] for reporting it and [@balloob] for the fix. + ### {% linkable_title Breaking changes %} - A new unit system has superseded the temperature unit option in the core configuration. For now it is backwards compatible, but you should update soon: @@ -65,6 +69,7 @@ homeassistant: unit_system: metric ``` +[@maddox]: https://github.com/maddox [@pavoni]: https://github.com/pavoni [@mKeRix]: https://github.com/mKeRix [@abcminiuser]: https://github.com/abcminiuser diff --git a/source/index.html b/source/index.html index ffa5962b1ed..03d98d1525e 100644 --- a/source/index.html +++ b/source/index.html @@ -15,8 +15,8 @@ hide_github_edit: true