diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000..7759ebb --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,17 @@ +FROM python:3.7 + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + git \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN python -m pip install --upgrade colorlog black +RUN python -m pip install --upgrade git+git://github.com/home-assistant/home-assistant.git@dev +RUN cd && mkdir -p /config/custom_components + + +WORKDIR /workspace + +# Set the default shell to bash instead of sh +ENV SHELL /bin/bash \ No newline at end of file diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000..f52282a --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,53 @@ +# Devcontainer + +_The easiest way to contribute to and/or test this repository._ + +## Requirements + +- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +- [docker](https://docs.docker.com/install/) +- [VS Code](https://code.visualstudio.com/) +- [Remote - Containers (VSC Extention)](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + +[More info about requirements and devcontainer in general](https://code.visualstudio.com/docs/remote/containers#_getting-started) + +## How to use Devcontainer for development/test + +1. Make sure your computer meets the requirements. +1. Fork this repository. +1. Clone the repository to your computer. +1. Open the repository using VS Code. + +When you open this repository with VSCode and your computer meets the requirements you are asked to "Reopen in Container", do that. + +![reopen](images/reopen.png) + +If you don't see this notification, open the command pallet (ctrl+shift+p) and select `Remote-Containers: Reopen Folder in Container`. + +_It will now build the devcontainer._ + +The container have some "tasks" to help you testing your changes. + +## Custom Tasks in this repository + +_Start "tasks" by opening the the command pallet (ctrl+shift+p) and select `Tasks: Run Task`_ + +Running tasks like `Start Home Assistant on port 8124` can be restarted by opening the the command pallet (ctrl+shift+p) and select `Tasks: Restart Running Task`, then select the task you want to restart. + +### Start Home Assistant on port 8124 + +This will copy the configuration and the integration files to the expected location in the container. + +And start up Home Assistant on [port 8124.](http://localhost:8124) + +### Upgrade Home Assistant to latest dev + +This will upgrade Home Assistant to the latest dev version. + +### Set Home Assistant Version + +This allows you to specify a version of Home Assistant to install inside the devcontainer. + +### Home Assistant Config Check + +This runs a config check to make sure your config is valid. diff --git a/example.yaml b/.devcontainer/configuration.yaml similarity index 60% rename from example.yaml rename to .devcontainer/configuration.yaml index fe7edcc..adbd88c 100644 --- a/example.yaml +++ b/.devcontainer/configuration.yaml @@ -1,12 +1,20 @@ -blueprint: - username: my_username - password: my_password - binary_sensor: - - enabled: true - name: My custom name - sensor: - - enabled: true - name: My custom name - switch: - - enabled: true - name: My custom name +default_config: +logger: + default: error + logs: + custom_components.blueprint: debug + + + +blueprint: + username: my_username + password: my_password + binary_sensor: + - enabled: true + name: My custom name + sensor: + - enabled: true + name: My custom name + switch: + - enabled: true + name: My custom name \ No newline at end of file diff --git a/.devcontainer/custom_component_helper b/.devcontainer/custom_component_helper new file mode 100644 index 0000000..40165d9 --- /dev/null +++ b/.devcontainer/custom_component_helper @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +function StartHomeAssistant { + echo "Copy configuration.yaml" + cp -f .devcontainer/configuration.yaml /config || echo ".devcontainer/configuration.yaml are missing!" exit 1 + + echo "Copy the custom component" + rm -R /config/custom_components/ || echo "" + cp -r custom_components /config/custom_components/ || echo "Could not copy the custom_component" exit 1 + + echo "Start Home Assistant" + hass -c /config +} + +function UpdgradeHomeAssistantDev { + python -m pip install --upgrade git+git://github.com/home-assistant/home-assistant.git@dev +} + +function SetHomeAssistantVersion { + read -p 'Version: ' version + python -m pip install --upgrade homeassistant==$version +} + +function HomeAssistantConfigCheck { + hass -c /config --script check_config +} \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..ee2577a --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,23 @@ +// See https://aka.ms/vscode-remote/devcontainer.json for format details. +{ + "context": "..", + "dockerFile": "Dockerfile", + "appPort": "8124:8123", + "runArgs": [ + "-e", + "GIT_EDTIOR='code --wait'" + ], + "extensions": [ + "ms-python.python" + ], + "settings": { + "python.pythonPath": "/usr/local/bin/python", + "python.linting.pylintEnabled": true, + "python.linting.enabled": true, + "python.formatting.provider": "black", + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "editor.formatOnType": true, + "files.trimTrailingWhitespace": true + } +} \ No newline at end of file diff --git a/.devcontainer/images/reopen.png b/.devcontainer/images/reopen.png new file mode 100644 index 0000000..cbcec3c Binary files /dev/null and b/.devcontainer/images/reopen.png differ diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 6bcce42..507f06e 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,17 +1,17 @@ ---- -name: Feature request -about: Suggest an idea for this project - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** +--- +name: Feature request +about: Suggest an idea for this project + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** Add any other context or screenshots about the feature request here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/issue.md b/.github/ISSUE_TEMPLATE/issue.md index bbd0345..70f3d5b 100644 --- a/.github/ISSUE_TEMPLATE/issue.md +++ b/.github/ISSUE_TEMPLATE/issue.md @@ -1,42 +1,42 @@ ---- -name: Issue -about: Create a report to help us improve - ---- - - - -## Version of the custom_component - - -## Configuration - -```yaml - -Add your logs here. - -``` - -## Describe the bug -A clear and concise description of what the bug is. - - -## Debug log - - - -```text - -Add your logs here. - +--- +name: Issue +about: Create a report to help us improve + +--- + + + +## Version of the custom_component + + +## Configuration + +```yaml + +Add your logs here. + +``` + +## Describe the bug +A clear and concise description of what the bug is. + + +## Debug log + + + +```text + +Add your logs here. + ``` \ No newline at end of file diff --git a/.github/main.workflow b/.github/main.workflow deleted file mode 100644 index b9e98f5..0000000 --- a/.github/main.workflow +++ /dev/null @@ -1,9 +0,0 @@ -workflow "Trigger: Push" { - on = "push" - resolves = ["Black Code Formatter"] -} - -action "Black Code Formatter" { - uses = "lgeiger/black-action@master" - args = "$GITHUB_WORKSPACE --check --diff" -} diff --git a/.github/settings.yml b/.github/settings.yml index 6b75ccc..717c121 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -1,23 +1,23 @@ -repository: - private: false - has_issues: true - has_projects: false - has_wiki: false - has_downloads: false - default_branch: master - allow_squash_merge: true - allow_merge_commit: false - allow_rebase_merge: false -labels: - - name: "Feature Request" - color: "fbca04" - - name: "Bug" - color: "b60205" - - name: "Wont Fix" - color: "ffffff" - - name: "Enhancement" - color: a2eeef - - name: "Documentation" - color: "008672" - - name: "Stale" +repository: + private: false + has_issues: true + has_projects: false + has_wiki: false + has_downloads: false + default_branch: master + allow_squash_merge: true + allow_merge_commit: false + allow_rebase_merge: false +labels: + - name: "Feature Request" + color: "fbca04" + - name: "Bug" + color: "b60205" + - name: "Wont Fix" + color: "ffffff" + - name: "Enhancement" + color: a2eeef + - name: "Documentation" + color: "008672" + - name: "Stale" color: "930191" \ No newline at end of file diff --git a/.github/stale.yml b/.github/stale.yml index 78973bc..668aea6 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -1,16 +1,16 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 14 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 7 -# Issues with these labels will never be considered stale -#exemptLabels: -# - pinned -# - security -# Label to use when marking an issue as stale -staleLabel: Stale -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. -# Comment to post when closing a stale issue. Set to `false` to disable +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 14 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +#exemptLabels: +# - pinned +# - security +# Label to use when marking an issue as stale +staleLabel: Stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. +# Comment to post when closing a stale issue. Set to `false` to disable closeComment: false \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..31504d9 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,61 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Start Home Assistant on port 8124", + "type": "shell", + "command": "source .devcontainer/custom_component_helper && StartHomeAssistant", + "group": { + "kind": "test", + "isDefault": true, + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Upgrade Home Assistant to latest dev", + "type": "shell", + "command": "source .devcontainer/custom_component_helper && UpdgradeHomeAssistantDev", + "group": { + "kind": "test", + "isDefault": true, + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Set Home Assistant Version", + "type": "shell", + "command": "source .devcontainer/custom_component_helper && SetHomeAssistantVersion", + "group": { + "kind": "test", + "isDefault": true, + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + }, + { + "label": "Home Assistant Config Check", + "type": "shell", + "command": "source .devcontainer/custom_component_helper && HomeAssistantConfigCheck", + "group": { + "kind": "test", + "isDefault": true, + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e91c221..f291aca 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,50 +1,50 @@ -# Contribution guidelines - -Contributing to this project should be as easy and transparent as possible, whether it's: - -- Reporting a bug -- Discussing the current state of the code -- Submitting a fix -- Proposing new features - -## Github is used for everything - -Github is used to host code, to track issues and feature requests, as well as accept pull requests. - -Pull requests are the best way to propose changes to the codebase. - -1. Fork the repo and create your branch from `master`. -2. If you've changed something, update the documentation. -3. Make sure your code lints (using black). -4. Issue that pull request! - -## Any contributions you make will be under the MIT Software License - -In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. - -## Report bugs using Github's [issues](../../issues) - -GitHub issues are used to track public bugs. -Report a bug by [opening a new issue](../../issues/new/choose); it's that easy! - -## Write bug reports with detail, background, and sample code - -**Great Bug Reports** tend to have: - -- A quick summary and/or background -- Steps to reproduce - - Be specific! - - Give sample code if you can. -- What you expected would happen -- What actually happens -- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) - -People *love* thorough bug reports. I'm not even kidding. - -## Use a Consistent Coding Style - -Use [black](https://github.com/ambv/black) to make sure the code follows the style. - -## License - -By contributing, you agree that your contributions will be licensed under its MIT License. +# Contribution guidelines + +Contributing to this project should be as easy and transparent as possible, whether it's: + +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features + +## Github is used for everything + +Github is used to host code, to track issues and feature requests, as well as accept pull requests. + +Pull requests are the best way to propose changes to the codebase. + +1. Fork the repo and create your branch from `master`. +2. If you've changed something, update the documentation. +3. Make sure your code lints (using black). +4. Issue that pull request! + +## Any contributions you make will be under the MIT Software License + +In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. + +## Report bugs using Github's [issues](../../issues) + +GitHub issues are used to track public bugs. +Report a bug by [opening a new issue](../../issues/new/choose); it's that easy! + +## Write bug reports with detail, background, and sample code + +**Great Bug Reports** tend to have: + +- A quick summary and/or background +- Steps to reproduce + - Be specific! + - Give sample code if you can. +- What you expected would happen +- What actually happens +- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) + +People *love* thorough bug reports. I'm not even kidding. + +## Use a Consistent Coding Style + +Use [black](https://github.com/ambv/black) to make sure the code follows the style. + +## License + +By contributing, you agree that your contributions will be licensed under its MIT License. diff --git a/LICENSE b/LICENSE index eadefd3..8d266b9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2019 Joakim Sørensen @ludeeus - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +MIT License + +Copyright (c) 2019 Joakim Sørensen @ludeeus + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 64a96d2..24dc247 100644 --- a/README.md +++ b/README.md @@ -1,160 +1,159 @@ -# Notice - -The component and platforms in this repository are not meant to be used by a -user, but as a "blueprint" that custom component developers can build -upon, to make more awesome stuff. - -This blueprint uses ['sampleclient'](https://github.com/ludeeus/sampleclient) to simulate what you actually might use in your integration. - -HAVE FUN! 😎 - -## Why? - -This is simple, by having custom_components look (README + structure) the same -it is easier for developers to help each other and for users to start using them. - -If you are a developer and you want to add things to this "blueprint" that you think more -developers will have use for, please open a PR to add it :) - -## What? - -This repository contains multiple files, here is a overview: - -File | Purpose --- | -- -`.github/ISSUE_TEMPLATE/feature_request.md` | Template for Feature Requests -`.github/ISSUE_TEMPLATE/issue.md` | Template for issues -`.github/main.workflow` | Workflow file for GitHub Actions -`.github/settings.yml` | Probot settings to control the repository settings. -`custom_components/blueprint/__init__.py` | The component file for the integration. -`custom_components/blueprint/binary_sensor.py` | Binary sensor platform for the integration. -`custom_components/blueprint/const.py` | A file to hold shared variables/constants for the entire integration. -`custom_components/blueprint/manifest.json` | A [manifest file](https://developers.home-assistant.io/docs/en/creating_integration_manifest.html) for Home Assistant. -`custom_components/blueprint/sensor.py` | Sensor platform for the integration. -`custom_components/blueprint/switch.py` | Switch sensor platform for the integration. -`CONTRIBUTING.md` | Guidelines on how to contribute. -`example.png` | Screenshot that demonstrate how it might look in the UI. -`example.yaml` | An example on how it might look in the users configuration.yaml file. -`LICENSE` | The license file for the project. -`README.md` | The file you are reading now, should contain info about the integration, installation and configuration instructions. - -*** -README content if this was a published component: -*** - -# blueprint - -[![GitHub Release][releases-shield]][releases] -[![GitHub Activity][commits-shield]][commits] -[![custom_updater][customupdaterbadge]][customupdater] -[![License][license-shield]](LICENSE.md) - -![Project Maintenance][maintenance-shield] -[![BuyMeCoffee][buymecoffeebadge]][buymecoffee] - -[![Discord][discord-shield]][discord] -[![Community Forum][forum-shield]][forum] - -_Component to integrate with [blueprint][blueprint]._ - -**This component will set up the following platforms.** - -Platform | Description --- | -- -`binary_sensor` | Show something `True` or `False`. -`sensor` | Show info from blueprint API. -`switch` | Switch something `True` or `False`. - -![example][exampleimg] - -## Installation - -1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`). -2. If you do not have a `custom_components` directory (folder) there, you need to create it. -3. In the `custom_components` directory (folder) create a new folder called `blueprint`. -4. Download _all_ the files from the `custom_components/blueprint/` directory (folder) in this repository. -5. Place the files you downloaded in the new directory (folder) you created. -6. Add `blueprint:` to your HA configuration. - -Using your HA configuration directory (folder) as a starting point you should now also have this: - -```text -custom_components/blueprint/__init__.py -custom_components/blueprint/binary_sensor.py -custom_components/blueprint/const.py -custom_components/blueprint/manifest.json -custom_components/blueprint/sensor.py -custom_components/blueprint/switch.py -``` - -## Example configuration.yaml - -```yaml -blueprint: - username: my_username - password: my_password - binary_sensor: - - enabled: true - name: My custom name - sensor: - - enabled: true - name: My custom name - switch: - - enabled: true - name: My custom name -``` - -## Configuration options - -Key | Type | Required | Description --- | -- | -- | -- -`username` | `string` | `False` | Username for the client. -`password` | `string` | `False` | Password for the client. -`binary_sensor` | `list` | `False` | Configuration for the `binary_sensor` platform. -`sensor` | `list` | `False` | Configuration for the `sensor` platform. -`switch` | `list` | `False` | Configuration for the `switch` platform. - -### Configuration options for `binary_sensor` list - -Key | Type | Required | Default | Description --- | -- | -- | -- | -- -`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. -`name` | `string` | `False` | `blueprint` | Custom name for the entity. - -### Configuration options for `sensor` list - -Key | Type | Required | Default | Description --- | -- | -- | -- | -- -`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. -`name` | `string` | `False` | `blueprint` | Custom name for the entity. - - -### Configuration options for `switch` list - -Key | Type | Required | Default | Description --- | -- | -- | -- | -- -`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. -`name` | `string` | `False` | `blueprint` | Custom name for the entity. - -## Contributions are welcome! - -If you want to contribute to this please read the [Contribution guidelines](CONTRIBUTING.md) - -*** - -[blueprint]: https://github.com/custom-components/blueprint -[buymecoffee]: https://www.buymeacoffee.com/ludeeus -[buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=for-the-badge -[commits-shield]: https://img.shields.io/github/commit-activity/y/custom-components/blueprint.svg?style=for-the-badge -[commits]: https://github.com/custom-components/blueprint/commits/master -[customupdater]: https://github.com/custom-components/custom_updater -[customupdaterbadge]: https://img.shields.io/badge/custom__updater-true-success.svg?style=for-the-badge -[discord]: https://discord.gg/Qa5fW2R -[discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge -[exampleimg]: example.png -[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge -[forum]: https://community.home-assistant.io/ -[license-shield]: https://img.shields.io/github/license/custom-components/blueprint.svg?style=for-the-badge -[maintenance-shield]: https://img.shields.io/badge/maintainer-Joakim%20Sørensen%20%40ludeeus-blue.svg?style=for-the-badge -[releases-shield]: https://img.shields.io/github/release/custom-components/blueprint.svg?style=for-the-badge -[releases]: https://github.com/custom-components/blueprint/releases +# Notice + +The component and platforms in this repository are not meant to be used by a +user, but as a "blueprint" that custom component developers can build +upon, to make more awesome stuff. + +This blueprint uses ['sampleclient'](https://github.com/ludeeus/sampleclient) to simulate what you actually might use in your integration. + +HAVE FUN! 😎 + +## Why? + +This is simple, by having custom_components look (README + structure) the same +it is easier for developers to help each other and for users to start using them. + +If you are a developer and you want to add things to this "blueprint" that you think more +developers will have use for, please open a PR to add it :) + +## What? + +This repository contains multiple files, here is a overview: + +File | Purpose +-- | -- +`.github/ISSUE_TEMPLATE/feature_request.md` | Template for Feature Requests +`.github/ISSUE_TEMPLATE/issue.md` | Template for issues +`.github/settings.yml` | Probot settings to control the repository settings. +`custom_components/blueprint/__init__.py` | The component file for the integration. +`custom_components/blueprint/binary_sensor.py` | Binary sensor platform for the integration. +`custom_components/blueprint/const.py` | A file to hold shared variables/constants for the entire integration. +`custom_components/blueprint/manifest.json` | A [manifest file](https://developers.home-assistant.io/docs/en/creating_integration_manifest.html) for Home Assistant. +`custom_components/blueprint/sensor.py` | Sensor platform for the integration. +`custom_components/blueprint/switch.py` | Switch sensor platform for the integration. +`CONTRIBUTING.md` | Guidelines on how to contribute. +`example.png` | Screenshot that demonstrate how it might look in the UI. +`info.md` | An example on a info file (used by [hacs][hacs]). +`LICENSE` | The license file for the project. +`README.md` | The file you are reading now, should contain info about the integration, installation and configuration instructions. + +*** +README content if this was a published component: +*** + +# blueprint + +[![GitHub Release][releases-shield]][releases] +[![GitHub Activity][commits-shield]][commits] +[![License][license-shield]](LICENSE.md) + +[![hacs][hacsbadge]](hacs) +![Project Maintenance][maintenance-shield] +[![BuyMeCoffee][buymecoffeebadge]][buymecoffee] + +[![Discord][discord-shield]][discord] +[![Community Forum][forum-shield]][forum] + +_Component to integrate with [blueprint][blueprint]._ + +**This component will set up the following platforms.** + +Platform | Description +-- | -- +`binary_sensor` | Show something `True` or `False`. +`sensor` | Show info from blueprint API. +`switch` | Switch something `True` or `False`. + +![example][exampleimg] + +## Installation + +1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`). +2. If you do not have a `custom_components` directory (folder) there, you need to create it. +3. In the `custom_components` directory (folder) create a new folder called `blueprint`. +4. Download _all_ the files from the `custom_components/blueprint/` directory (folder) in this repository. +5. Place the files you downloaded in the new directory (folder) you created. +6. Add `blueprint:` to your HA configuration. + +Using your HA configuration directory (folder) as a starting point you should now also have this: + +```text +custom_components/blueprint/__init__.py +custom_components/blueprint/binary_sensor.py +custom_components/blueprint/const.py +custom_components/blueprint/manifest.json +custom_components/blueprint/sensor.py +custom_components/blueprint/switch.py +``` + +## Example configuration.yaml + +```yaml +blueprint: + username: my_username + password: my_password + binary_sensor: + - enabled: true + name: My custom name + sensor: + - enabled: true + name: My custom name + switch: + - enabled: true + name: My custom name +``` + +## Configuration options + +Key | Type | Required | Description +-- | -- | -- | -- +`username` | `string` | `False` | Username for the client. +`password` | `string` | `False` | Password for the client. +`binary_sensor` | `list` | `False` | Configuration for the `binary_sensor` platform. +`sensor` | `list` | `False` | Configuration for the `sensor` platform. +`switch` | `list` | `False` | Configuration for the `switch` platform. + +### Configuration options for `binary_sensor` list + +Key | Type | Required | Default | Description +-- | -- | -- | -- | -- +`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. +`name` | `string` | `False` | `blueprint` | Custom name for the entity. + +### Configuration options for `sensor` list + +Key | Type | Required | Default | Description +-- | -- | -- | -- | -- +`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. +`name` | `string` | `False` | `blueprint` | Custom name for the entity. + + +### Configuration options for `switch` list + +Key | Type | Required | Default | Description +-- | -- | -- | -- | -- +`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. +`name` | `string` | `False` | `blueprint` | Custom name for the entity. + +## Contributions are welcome! + +If you want to contribute to this please read the [Contribution guidelines](CONTRIBUTING.md) + +*** + +[blueprint]: https://github.com/custom-components/blueprint +[buymecoffee]: https://www.buymeacoffee.com/ludeeus +[buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=for-the-badge +[commits-shield]: https://img.shields.io/github/commit-activity/y/custom-components/blueprint.svg?style=for-the-badge +[commits]: https://github.com/custom-components/blueprint/commits/master +[hacs]: https://github.com/custom-components/hacs +[hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge +[discord]: https://discord.gg/Qa5fW2R +[discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge +[exampleimg]: example.png +[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge +[forum]: https://community.home-assistant.io/ +[license-shield]: https://img.shields.io/github/license/custom-components/blueprint.svg?style=for-the-badge +[maintenance-shield]: https://img.shields.io/badge/maintainer-Joakim%20Sørensen%20%40ludeeus-blue.svg?style=for-the-badge +[releases-shield]: https://img.shields.io/github/release/custom-components/blueprint.svg?style=for-the-badge +[releases]: https://github.com/custom-components/blueprint/releases diff --git a/custom_components/blueprint/__init__.py b/custom_components/blueprint/__init__.py index 6b942d6..7f90a41 100644 --- a/custom_components/blueprint/__init__.py +++ b/custom_components/blueprint/__init__.py @@ -1,160 +1,159 @@ -""" -Component to integrate with blueprint. - -For more details about this component, please refer to -https://github.com/custom-components/blueprint -""" -import os -from datetime import timedelta -import logging -import voluptuous as vol -import homeassistant.helpers.config_validation as cv -from homeassistant.helpers import discovery -from homeassistant.util import Throttle -from .const import ( - CONF_BINARY_SENSOR, - CONF_ENABLED, - CONF_NAME, - CONF_PASSWORD, - CONF_SENSOR, - CONF_SWITCH, - CONF_USERNAME, - DEFAULT_NAME, - DOMAIN_DATA, - DOMAIN, - ISSUE_URL, - PLATFORMS, - REQUIRED_FILES, - STARTUP, - VERSION, -) - -MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) - -_LOGGER = logging.getLogger(__name__) - -BINARY_SENSOR_SCHEMA = vol.Schema( - { - vol.Optional(CONF_ENABLED, default=True): cv.boolean, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - } -) - -SENSOR_SCHEMA = vol.Schema( - { - vol.Optional(CONF_ENABLED, default=True): cv.boolean, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - } -) - -SWITCH_SCHEMA = vol.Schema( - { - vol.Optional(CONF_ENABLED, default=True): cv.boolean, - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - } -) - -CONFIG_SCHEMA = vol.Schema( - { - DOMAIN: vol.Schema( - { - vol.Optional(CONF_USERNAME): cv.string, - vol.Optional(CONF_PASSWORD): cv.string, - vol.Optional(CONF_BINARY_SENSOR): vol.All( - cv.ensure_list, [BINARY_SENSOR_SCHEMA] - ), - vol.Optional(CONF_SENSOR): vol.All(cv.ensure_list, [SENSOR_SCHEMA]), - vol.Optional(CONF_SWITCH): vol.All(cv.ensure_list, [SWITCH_SCHEMA]), - } - ) - }, - extra=vol.ALLOW_EXTRA, -) - - -async def async_setup(hass, config): - """Set up this component.""" - # Import client from a external python package hosted on PyPi - from sampleclient.client import Client - - # Print startup message - startup = STARTUP.format(name=DOMAIN, version=VERSION, issueurl=ISSUE_URL) - _LOGGER.info(startup) - - # Check that all required files are present - file_check = await check_files(hass) - if not file_check: - return False - - # Create DATA dict - hass.data[DOMAIN_DATA] = {} - - # Get "global" configuration. - username = config[DOMAIN].get(CONF_USERNAME) - password = config[DOMAIN].get(CONF_PASSWORD) - - # Configure the client. - client = Client(username, password) - hass.data[DOMAIN_DATA]["client"] = BlueprintData(hass, client) - - # Load platforms - for platform in PLATFORMS: - # Get platform specific configuration - platform_config = config[DOMAIN].get(platform, {}) - - # If platform is not enabled, skip. - if not platform_config: - continue - - for entry in platform_config: - entry_config = entry - _LOGGER.critical(entry_config) - - # If entry is not enabled, skip. - if not entry_config[CONF_ENABLED]: - continue - - hass.async_create_task( - discovery.async_load_platform( - hass, platform, DOMAIN, entry_config, config - ) - ) - return True - - -class BlueprintData: - """This class handle communication and stores the data.""" - - def __init__(self, hass, client): - """Initialize the class.""" - self.hass = hass - self.client = client - - @Throttle(MIN_TIME_BETWEEN_UPDATES) - async def update_data(self): - """Update data.""" - # This is where the main logic to update platform data goes. - try: - data = self.client.get_data() - self.hass.data[DOMAIN_DATA]["data"] = data - except Exception as error: # pylint: disable=broad-except - _LOGGER.error("Could not update data - %s", error) - - -async def check_files(hass): - """Return bool that indicates if all files are present.""" - # Verify that the user downloaded all files. - base = "{}/custom_components/{}/".format(hass.config.path(), DOMAIN) - missing = [] - for file in REQUIRED_FILES: - fullpath = "{}{}".format(base, file) - if not os.path.exists(fullpath): - missing.append(file) - - if missing: - _LOGGER.critical("The following files are missing: %s", str(missing)) - returnvalue = False - else: - returnvalue = True - - return returnvalue +""" +Component to integrate with blueprint. + +For more details about this component, please refer to +https://github.com/custom-components/blueprint +""" +import os +from datetime import timedelta +import logging +import voluptuous as vol +import homeassistant.helpers.config_validation as cv +from homeassistant.helpers import discovery +from homeassistant.util import Throttle +from .const import ( + CONF_BINARY_SENSOR, + CONF_ENABLED, + CONF_NAME, + CONF_PASSWORD, + CONF_SENSOR, + CONF_SWITCH, + CONF_USERNAME, + DEFAULT_NAME, + DOMAIN_DATA, + DOMAIN, + ISSUE_URL, + PLATFORMS, + REQUIRED_FILES, + STARTUP, + VERSION, +) + +MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) + +_LOGGER = logging.getLogger(__name__) + +BINARY_SENSOR_SCHEMA = vol.Schema( + { + vol.Optional(CONF_ENABLED, default=True): cv.boolean, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + } +) + +SENSOR_SCHEMA = vol.Schema( + { + vol.Optional(CONF_ENABLED, default=True): cv.boolean, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + } +) + +SWITCH_SCHEMA = vol.Schema( + { + vol.Optional(CONF_ENABLED, default=True): cv.boolean, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + } +) + +CONFIG_SCHEMA = vol.Schema( + { + DOMAIN: vol.Schema( + { + vol.Optional(CONF_USERNAME): cv.string, + vol.Optional(CONF_PASSWORD): cv.string, + vol.Optional(CONF_BINARY_SENSOR): vol.All( + cv.ensure_list, [BINARY_SENSOR_SCHEMA] + ), + vol.Optional(CONF_SENSOR): vol.All(cv.ensure_list, [SENSOR_SCHEMA]), + vol.Optional(CONF_SWITCH): vol.All(cv.ensure_list, [SWITCH_SCHEMA]), + } + ) + }, + extra=vol.ALLOW_EXTRA, +) + + +async def async_setup(hass, config): + """Set up this component.""" + # Import client from a external python package hosted on PyPi + from sampleclient.client import Client + + # Print startup message + startup = STARTUP.format(name=DOMAIN, version=VERSION, issueurl=ISSUE_URL) + _LOGGER.info(startup) + + # Check that all required files are present + file_check = await check_files(hass) + if not file_check: + return False + + # Create DATA dict + hass.data[DOMAIN_DATA] = {} + + # Get "global" configuration. + username = config[DOMAIN].get(CONF_USERNAME) + password = config[DOMAIN].get(CONF_PASSWORD) + + # Configure the client. + client = Client(username, password) + hass.data[DOMAIN_DATA]["client"] = BlueprintData(hass, client) + + # Load platforms + for platform in PLATFORMS: + # Get platform specific configuration + platform_config = config[DOMAIN].get(platform, {}) + + # If platform is not enabled, skip. + if not platform_config: + continue + + for entry in platform_config: + entry_config = entry + + # If entry is not enabled, skip. + if not entry_config[CONF_ENABLED]: + continue + + hass.async_create_task( + discovery.async_load_platform( + hass, platform, DOMAIN, entry_config, config + ) + ) + return True + + +class BlueprintData: + """This class handle communication and stores the data.""" + + def __init__(self, hass, client): + """Initialize the class.""" + self.hass = hass + self.client = client + + @Throttle(MIN_TIME_BETWEEN_UPDATES) + async def update_data(self): + """Update data.""" + # This is where the main logic to update platform data goes. + try: + data = self.client.get_data() + self.hass.data[DOMAIN_DATA]["data"] = data + except Exception as error: # pylint: disable=broad-except + _LOGGER.error("Could not update data - %s", error) + + +async def check_files(hass): + """Return bool that indicates if all files are present.""" + # Verify that the user downloaded all files. + base = "{}/custom_components/{}/".format(hass.config.path(), DOMAIN) + missing = [] + for file in REQUIRED_FILES: + fullpath = "{}{}".format(base, file) + if not os.path.exists(fullpath): + missing.append(file) + + if missing: + _LOGGER.critical("The following files are missing: %s", str(missing)) + returnvalue = False + else: + returnvalue = True + + return returnvalue diff --git a/custom_components/blueprint/binary_sensor.py b/custom_components/blueprint/binary_sensor.py index 6466019..5c92716 100644 --- a/custom_components/blueprint/binary_sensor.py +++ b/custom_components/blueprint/binary_sensor.py @@ -1,59 +1,59 @@ -"""Binary sensor platform for blueprint.""" -from homeassistant.components.binary_sensor import BinarySensorDevice -from .const import ATTRIBUTION, BINARY_SENSOR_DEVICE_CLASS, DEFAULT_NAME, DOMAIN_DATA - - -async def async_setup_platform( - hass, config, async_add_entities, discovery_info=None -): # pylint: disable=unused-argument - """Setup binary_sensor platform.""" - async_add_entities([BlueprintBinarySensor(hass, discovery_info)], True) - - -class BlueprintBinarySensor(BinarySensorDevice): - """blueprint binary_sensor class.""" - - def __init__(self, hass, config): - self.hass = hass - self.attr = {} - self._status = False - self._name = config.get("name", DEFAULT_NAME) - - async def async_update(self): - """Update the binary_sensor.""" - # Send update "signal" to the component - await self.hass.data[DOMAIN_DATA]["client"].update_data() - - # Get new data (if any) - updated = self.hass.data[DOMAIN_DATA]["data"].get("data", {}) - - # Check the data and update the value. - if updated.get("bool_on") is None: - self._status = self._status - else: - self._status = updated.get("bool_on") - - # Set/update attributes - self.attr["attribution"] = ATTRIBUTION - self.attr["time"] = str(updated.get("time")) - self.attr["static"] = updated.get("static") - - @property - def name(self): - """Return the name of the binary_sensor.""" - return self._name - - @property - def device_class(self): - """Return the class of this binary_sensor.""" - return BINARY_SENSOR_DEVICE_CLASS - - @property - def is_on(self): - """Return true if the binary_sensor is on.""" - return self._status - - @property - def device_state_attributes(self): - """Return the state attributes.""" - return self.attr +"""Binary sensor platform for blueprint.""" +from homeassistant.components.binary_sensor import BinarySensorDevice +from .const import ATTRIBUTION, BINARY_SENSOR_DEVICE_CLASS, DEFAULT_NAME, DOMAIN_DATA + + +async def async_setup_platform( + hass, config, async_add_entities, discovery_info=None +): # pylint: disable=unused-argument + """Setup binary_sensor platform.""" + async_add_entities([BlueprintBinarySensor(hass, discovery_info)], True) + + +class BlueprintBinarySensor(BinarySensorDevice): + """blueprint binary_sensor class.""" + + def __init__(self, hass, config): + self.hass = hass + self.attr = {} + self._status = False + self._name = config.get("name", DEFAULT_NAME) + + async def async_update(self): + """Update the binary_sensor.""" + # Send update "signal" to the component + await self.hass.data[DOMAIN_DATA]["client"].update_data() + + # Get new data (if any) + updated = self.hass.data[DOMAIN_DATA]["data"].get("data", {}) + + # Check the data and update the value. + if updated.get("bool_on") is None: + self._status = self._status + else: + self._status = updated.get("bool_on") + + # Set/update attributes + self.attr["attribution"] = ATTRIBUTION + self.attr["time"] = str(updated.get("time")) + self.attr["static"] = updated.get("static") + + @property + def name(self): + """Return the name of the binary_sensor.""" + return self._name + + @property + def device_class(self): + """Return the class of this binary_sensor.""" + return BINARY_SENSOR_DEVICE_CLASS + + @property + def is_on(self): + """Return true if the binary_sensor is on.""" + return self._status + + @property + def device_state_attributes(self): + """Return the state attributes.""" + return self.attr diff --git a/custom_components/blueprint/const.py b/custom_components/blueprint/const.py index 7e3a620..da457c2 100644 --- a/custom_components/blueprint/const.py +++ b/custom_components/blueprint/const.py @@ -1,42 +1,42 @@ -"""Constants for blueprint.""" -# Base component constants -DOMAIN = "blueprint" -DOMAIN_DATA = "{}_data".format(DOMAIN) -VERSION = "0.0.1" -PLATFORMS = ["binary_sensor", "sensor", "switch"] -REQUIRED_FILES = [ - "binary_sensor.py", - "const.py", - "manifest.json", - "sensor.py", - "switch.py", -] -ISSUE_URL = "https://github.com/custom-components/blueprint/issues" -ATTRIBUTION = "Data from this is provided by blueprint." -STARTUP = """ -------------------------------------------------------------------- -{name} -Version: {version} -This is a custom component -If you have any issues with this you need to open an issue here: -{issueurl} -------------------------------------------------------------------- -""" - -# Icons -ICON = "mdi:format-quote-close" - -# Device classes -BINARY_SENSOR_DEVICE_CLASS = "connectivity" - -# Configuration -CONF_BINARY_SENSOR = "binary_sensor" -CONF_SENSOR = "sensor" -CONF_SWITCH = "switch" -CONF_ENABLED = "enabled" -CONF_NAME = "name" -CONF_USERNAME = "username" -CONF_PASSWORD = "password" - -# Defaults -DEFAULT_NAME = DOMAIN +"""Constants for blueprint.""" +# Base component constants +DOMAIN = "blueprint" +DOMAIN_DATA = "{}_data".format(DOMAIN) +VERSION = "0.0.1" +PLATFORMS = ["binary_sensor", "sensor", "switch"] +REQUIRED_FILES = [ + "binary_sensor.py", + "const.py", + "manifest.json", + "sensor.py", + "switch.py", +] +ISSUE_URL = "https://github.com/custom-components/blueprint/issues" +ATTRIBUTION = "Data from this is provided by blueprint." +STARTUP = """ +------------------------------------------------------------------- +{name} +Version: {version} +This is a custom component +If you have any issues with this you need to open an issue here: +{issueurl} +------------------------------------------------------------------- +""" + +# Icons +ICON = "mdi:format-quote-close" + +# Device classes +BINARY_SENSOR_DEVICE_CLASS = "connectivity" + +# Configuration +CONF_BINARY_SENSOR = "binary_sensor" +CONF_SENSOR = "sensor" +CONF_SWITCH = "switch" +CONF_ENABLED = "enabled" +CONF_NAME = "name" +CONF_USERNAME = "username" +CONF_PASSWORD = "password" + +# Defaults +DEFAULT_NAME = DOMAIN diff --git a/custom_components/blueprint/manifest.json b/custom_components/blueprint/manifest.json index 05e6909..b51d2e9 100644 --- a/custom_components/blueprint/manifest.json +++ b/custom_components/blueprint/manifest.json @@ -1,8 +1,8 @@ -{ - "domain": "blueprint", - "name": "Blueprint", - "documentation": "https://github.com/custom-components/blueprint", - "dependencies": [], - "codeowners": ["@ludeeus"], - "requirements": ["sampleclient==0.0.1"] -} +{ + "domain": "blueprint", + "name": "Blueprint", + "documentation": "https://github.com/custom-components/blueprint", + "dependencies": [], + "codeowners": ["@ludeeus"], + "requirements": ["sampleclient==0.0.1"] +} diff --git a/custom_components/blueprint/sensor.py b/custom_components/blueprint/sensor.py index 7864a79..05fa2a4 100644 --- a/custom_components/blueprint/sensor.py +++ b/custom_components/blueprint/sensor.py @@ -1,59 +1,59 @@ -"""Sensor platform for blueprint.""" -from homeassistant.helpers.entity import Entity -from .const import ATTRIBUTION, DEFAULT_NAME, DOMAIN_DATA, ICON - - -async def async_setup_platform( - hass, config, async_add_entities, discovery_info=None -): # pylint: disable=unused-argument - """Setup sensor platform.""" - async_add_entities([BlueprintSensor(hass, discovery_info)], True) - - -class BlueprintSensor(Entity): - """blueprint Sensor class.""" - - def __init__(self, hass, config): - self.hass = hass - self.attr = {} - self._state = None - self._name = config.get("name", DEFAULT_NAME) - - async def async_update(self): - """Update the sensor.""" - # Send update "signal" to the component - await self.hass.data[DOMAIN_DATA]["client"].update_data() - - # Get new data (if any) - updated = self.hass.data[DOMAIN_DATA]["data"].get("data", {}) - - # Check the data and update the value. - if updated.get("static") is None: - self._state = self._status - else: - self._state = updated.get("static") - - # Set/update attributes - self.attr["attribution"] = ATTRIBUTION - self.attr["time"] = str(updated.get("time")) - self.attr["none"] = updated.get("none") - - @property - def name(self): - """Return the name of the sensor.""" - return self._name - - @property - def state(self): - """Return the state of the sensor.""" - return self._state - - @property - def icon(self): - """Return the icon of the sensor.""" - return ICON - - @property - def device_state_attributes(self): - """Return the state attributes.""" - return self.attr +"""Sensor platform for blueprint.""" +from homeassistant.helpers.entity import Entity +from .const import ATTRIBUTION, DEFAULT_NAME, DOMAIN_DATA, ICON + + +async def async_setup_platform( + hass, config, async_add_entities, discovery_info=None +): # pylint: disable=unused-argument + """Setup sensor platform.""" + async_add_entities([BlueprintSensor(hass, discovery_info)], True) + + +class BlueprintSensor(Entity): + """blueprint Sensor class.""" + + def __init__(self, hass, config): + self.hass = hass + self.attr = {} + self._state = None + self._name = config.get("name", DEFAULT_NAME) + + async def async_update(self): + """Update the sensor.""" + # Send update "signal" to the component + await self.hass.data[DOMAIN_DATA]["client"].update_data() + + # Get new data (if any) + updated = self.hass.data[DOMAIN_DATA]["data"].get("data", {}) + + # Check the data and update the value. + if updated.get("static") is None: + self._state = self._status + else: + self._state = updated.get("static") + + # Set/update attributes + self.attr["attribution"] = ATTRIBUTION + self.attr["time"] = str(updated.get("time")) + self.attr["none"] = updated.get("none") + + @property + def name(self): + """Return the name of the sensor.""" + return self._name + + @property + def state(self): + """Return the state of the sensor.""" + return self._state + + @property + def icon(self): + """Return the icon of the sensor.""" + return ICON + + @property + def device_state_attributes(self): + """Return the state attributes.""" + return self.attr diff --git a/custom_components/blueprint/switch.py b/custom_components/blueprint/switch.py index e588db8..051de45 100644 --- a/custom_components/blueprint/switch.py +++ b/custom_components/blueprint/switch.py @@ -1,64 +1,64 @@ -"""Switch platform for blueprint.""" -from homeassistant.components.switch import SwitchDevice -from .const import ATTRIBUTION, DEFAULT_NAME, DOMAIN_DATA, ICON - - -async def async_setup_platform( - hass, config, async_add_entities, discovery_info=None -): # pylint: disable=unused-argument - """Setup switch platform.""" - async_add_entities([BlueprintBinarySwitch(hass, discovery_info)], True) - - -class BlueprintBinarySwitch(SwitchDevice): - """blueprint switch class.""" - - def __init__(self, hass, config): - self.hass = hass - self.attr = {} - self._status = False - self._name = config.get("name", DEFAULT_NAME) - - async def async_update(self): - """Update the switch.""" - # Send update "signal" to the component - await self.hass.data[DOMAIN_DATA]["client"].update_data() - - # Get new data (if any) - updated = self.hass.data[DOMAIN_DATA]["data"].get("data", {}) - - # Check the data and update the value. - self._status = self.hass.data[DOMAIN_DATA]["client"].client.something - - # Set/update attributes - self.attr["attribution"] = ATTRIBUTION - self.attr["time"] = str(updated.get("time")) - self.attr["static"] = updated.get("static") - - async def async_turn_on(self, **kwargs): # pylint: disable=unused-argument - """Turn on the switch.""" - await self.hass.data[DOMAIN_DATA]["client"].client.change_something(True) - - async def async_turn_off(self, **kwargs): # pylint: disable=unused-argument - """Turn off the switch.""" - await self.hass.data[DOMAIN_DATA]["client"].client.change_something(False) - - @property - def name(self): - """Return the name of the switch.""" - return self._name - - @property - def icon(self): - """Return the icon of this switch.""" - return ICON - - @property - def is_on(self): - """Return true if the switch is on.""" - return self._status - - @property - def device_state_attributes(self): - """Return the state attributes.""" - return self.attr +"""Switch platform for blueprint.""" +from homeassistant.components.switch import SwitchDevice +from .const import ATTRIBUTION, DEFAULT_NAME, DOMAIN_DATA, ICON + + +async def async_setup_platform( + hass, config, async_add_entities, discovery_info=None +): # pylint: disable=unused-argument + """Setup switch platform.""" + async_add_entities([BlueprintBinarySwitch(hass, discovery_info)], True) + + +class BlueprintBinarySwitch(SwitchDevice): + """blueprint switch class.""" + + def __init__(self, hass, config): + self.hass = hass + self.attr = {} + self._status = False + self._name = config.get("name", DEFAULT_NAME) + + async def async_update(self): + """Update the switch.""" + # Send update "signal" to the component + await self.hass.data[DOMAIN_DATA]["client"].update_data() + + # Get new data (if any) + updated = self.hass.data[DOMAIN_DATA]["data"].get("data", {}) + + # Check the data and update the value. + self._status = self.hass.data[DOMAIN_DATA]["client"].client.something + + # Set/update attributes + self.attr["attribution"] = ATTRIBUTION + self.attr["time"] = str(updated.get("time")) + self.attr["static"] = updated.get("static") + + async def async_turn_on(self, **kwargs): # pylint: disable=unused-argument + """Turn on the switch.""" + await self.hass.data[DOMAIN_DATA]["client"].client.change_something(True) + + async def async_turn_off(self, **kwargs): # pylint: disable=unused-argument + """Turn off the switch.""" + await self.hass.data[DOMAIN_DATA]["client"].client.change_something(False) + + @property + def name(self): + """Return the name of the switch.""" + return self._name + + @property + def icon(self): + """Return the icon of this switch.""" + return ICON + + @property + def is_on(self): + """Return true if the switch is on.""" + return self._status + + @property + def device_state_attributes(self): + """Return the state attributes.""" + return self.attr diff --git a/info.md b/info.md new file mode 100644 index 0000000..c893c7d --- /dev/null +++ b/info.md @@ -0,0 +1,98 @@ +[![GitHub Release][releases-shield]][releases] +[![GitHub Activity][commits-shield]][commits] +[![License][license-shield]](LICENSE.md) + +[![hacs][hacsbadge]](hacs) +![Project Maintenance][maintenance-shield] +[![BuyMeCoffee][buymecoffeebadge]][buymecoffee] + +[![Discord][discord-shield]][discord] +[![Community Forum][forum-shield]][forum] + +_Component to integrate with [blueprint][blueprint]._ + +**This component will set up the following platforms.** + +Platform | Description +-- | -- +`binary_sensor` | Show something `True` or `False`. +`sensor` | Show info from blueprint API. +`switch` | Switch something `True` or `False`. + +![example][exampleimg] + +{% if not installed %} +## Installation + +1. Click install. +1. Add `blueprint:` to your HA configuration. + +{% endif %} +## Example configuration.yaml + +```yaml +blueprint: + username: my_username + password: my_password + binary_sensor: + - enabled: true + name: My custom name + sensor: + - enabled: true + name: My custom name + switch: + - enabled: true + name: My custom name +``` + +## Configuration options + +Key | Type | Required | Description +-- | -- | -- | -- +`username` | `string` | `False` | Username for the client. +`password` | `string` | `False` | Password for the client. +`binary_sensor` | `list` | `False` | Configuration for the `binary_sensor` platform. +`sensor` | `list` | `False` | Configuration for the `sensor` platform. +`switch` | `list` | `False` | Configuration for the `switch` platform. + +### Configuration options for `binary_sensor` list + +Key | Type | Required | Default | Description +-- | -- | -- | -- | -- +`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. +`name` | `string` | `False` | `blueprint` | Custom name for the entity. + +### Configuration options for `sensor` list + +Key | Type | Required | Default | Description +-- | -- | -- | -- | -- +`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. +`name` | `string` | `False` | `blueprint` | Custom name for the entity. + + +### Configuration options for `switch` list + +Key | Type | Required | Default | Description +-- | -- | -- | -- | -- +`enabled` | `boolean` | `False` | `True` | Boolean to enable/disable the platform. +`name` | `string` | `False` | `blueprint` | Custom name for the entity. + + +*** + +[blueprint]: https://github.com/custom-components/blueprint +[buymecoffee]: https://www.buymeacoffee.com/ludeeus +[buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=for-the-badge +[commits-shield]: https://img.shields.io/github/commit-activity/y/custom-components/blueprint.svg?style=for-the-badge +[commits]: https://github.com/custom-components/blueprint/commits/master +[hacs]: https://github.com/custom-components/hacs +[hacsbadge]: https://img.shields.io/badge/HACS-Custom-orange.svg?style=for-the-badge +[discord]: https://discord.gg/Qa5fW2R +[discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge +[exampleimg]: example.png +[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge +[forum]: https://community.home-assistant.io/ +[license-shield]: https://img.shields.io/github/license/custom-components/blueprint.svg?style=for-the-badge +[maintenance-shield]: https://img.shields.io/badge/maintainer-Joakim%20Sørensen%20%40ludeeus-blue.svg?style=for-the-badge +[releases-shield]: https://img.shields.io/github/release/custom-components/blueprint.svg?style=for-the-badge +[releases]: https://github.com/custom-components/blueprint/releases