Initial commit
This commit is contained in:
commit
e86e5b5183
43
.devcontainer/README.md
Normal file
43
.devcontainer/README.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
## Developing with Visual Studio Code + devcontainer
|
||||||
|
|
||||||
|
The easiest way to get started with custom integration development is to use Visual Studio Code with devcontainers. This approach will create a preconfigured development environment with all the tools you need.
|
||||||
|
|
||||||
|
In the container you will have a dedicated Home Assistant core instance running with your custom compnent code. You can configure this instance by updating the `./devcontainer/configuration.yaml` file.
|
||||||
|
|
||||||
|
**Prerequisites**
|
||||||
|
|
||||||
|
- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
|
||||||
|
- Docker
|
||||||
|
- For Linux, macOS, or Windows 10 Pro/Enterprise/Education use the [current release version of Docker](https://docs.docker.com/install/)
|
||||||
|
- Windows 10 Home requires [WSL 2](https://docs.microsoft.com/windows/wsl/wsl2-install) and the current Edge version of Docker Desktop (see instructions [here](https://docs.docker.com/docker-for-windows/wsl-tech-preview/)). This can also be used for Windows Pro/Enterprise/Education.
|
||||||
|
- [Visual Studio code](https://code.visualstudio.com/)
|
||||||
|
- [Remote - Containers (VSC Extension)][extension-link]
|
||||||
|
|
||||||
|
[More info about requirements and devcontainer in general](https://code.visualstudio.com/docs/remote/containers#_getting-started)
|
||||||
|
|
||||||
|
[extension-link]: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
|
||||||
|
|
||||||
|
**Getting started:**
|
||||||
|
|
||||||
|
1. Fork the repository.
|
||||||
|
2. Clone the repository to your computer.
|
||||||
|
3. Open the repository using Visual Studio code.
|
||||||
|
|
||||||
|
When you open this repository with Visual Studio code you are asked to "Reopen in Container", this will start the build of the container.
|
||||||
|
|
||||||
|
_If you don't see this notification, open the command palette and select `Remote-Containers: Reopen Folder in Container`._
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
The devcontainter comes with some useful tasks to help you with development, you can start these tasks by opening the command palette and select `Tasks: Run Task` then select the task you want to run.
|
||||||
|
|
||||||
|
When a task is currently running (like `Run Home Assistant on port 9123` for the docs), it can be restarted by opening the command palette and selecting `Tasks: Restart Running Task`, then select the task you want to restart.
|
||||||
|
|
||||||
|
The available tasks are:
|
||||||
|
|
||||||
|
Task | Description
|
||||||
|
-- | --
|
||||||
|
Run Home Assistant on port 9123 | Launch Home assistant with your custom compnent code and the configuration defined in `.devcontainer/configuration.yaml`.
|
||||||
|
Run Home Assistant configuration against /config | Check the configuration.
|
||||||
|
Upgrade Home Assistant to latest dev | Upgrade the Home Assitant core version in the container to the latest version of the `dev` branch.
|
||||||
|
Install a spesific version of Home Assistant | Install a specific version of Home Assistant core in the container.
|
9
.devcontainer/configuration.yaml
Normal file
9
.devcontainer/configuration.yaml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
default_config:
|
||||||
|
|
||||||
|
automation: !include automations.yaml
|
||||||
|
|
||||||
|
logger:
|
||||||
|
default: error
|
||||||
|
logs:
|
||||||
|
custom_components.blueprint: debug
|
||||||
|
|
31
.devcontainer/devcontainer.json
Normal file
31
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// See https://aka.ms/vscode-remote/devcontainer.json for format details.
|
||||||
|
{
|
||||||
|
"image": "ludeeus/container:integration",
|
||||||
|
"context": "..",
|
||||||
|
"appPort": [
|
||||||
|
"9123:8123"
|
||||||
|
],
|
||||||
|
"postCreateCommand": "container install",
|
||||||
|
"runArgs": [
|
||||||
|
"-v",
|
||||||
|
"${env:HOME}${env:USERPROFILE}/.ssh:/tmp/.ssh"
|
||||||
|
],
|
||||||
|
"extensions": [
|
||||||
|
"ms-python.python",
|
||||||
|
"github.vscode-pull-request-github",
|
||||||
|
"tabnine.tabnine-vscode"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"files.eol": "\n",
|
||||||
|
"editor.tabSize": 4,
|
||||||
|
"terminal.integrated.shell.linux": "/bin/bash",
|
||||||
|
"python.pythonPath": "/usr/bin/python3",
|
||||||
|
"python.linting.pylintEnabled": true,
|
||||||
|
"python.linting.enabled": true,
|
||||||
|
"python.formatting.provider": "black",
|
||||||
|
"editor.formatOnPaste": false,
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"editor.formatOnType": true,
|
||||||
|
"files.trimTrailingWhitespace": true
|
||||||
|
}
|
||||||
|
}
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
* text=auto eol=lf
|
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@ -0,0 +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**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
42
.github/ISSUE_TEMPLATE/issue.md
vendored
Normal file
42
.github/ISSUE_TEMPLATE/issue.md
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
name: Issue
|
||||||
|
about: Create a report to help us improve
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!-- Before you open a new issue, search through the existing issues to see if others have had the same problem.
|
||||||
|
|
||||||
|
Issues not containing the minimum requirements will be closed:
|
||||||
|
|
||||||
|
- Issues without a description (using the header is not good enough) will be closed.
|
||||||
|
- Issues without debug logging will be closed.
|
||||||
|
- Issues without configuration will be closed
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Version of the custom_component
|
||||||
|
<!-- If you are not using the newest version, download and try that before opening an issue
|
||||||
|
If you are unsure about the version check the const.py file.
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
|
||||||
|
Add your logs here.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Describe the bug
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
|
||||||
|
|
||||||
|
## Debug log
|
||||||
|
|
||||||
|
<!-- To enable debug logs check this https://www.home-assistant.io/components/logger/ -->
|
||||||
|
|
||||||
|
```text
|
||||||
|
|
||||||
|
Add your logs here.
|
||||||
|
|
||||||
|
```
|
21
.github/workflows/cron.yaml
vendored
Normal file
21
.github/workflows/cron.yaml
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
name: Cron actions
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
name: Validate
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v2"
|
||||||
|
|
||||||
|
- name: HACS validation
|
||||||
|
uses: "hacs/integration/action@master"
|
||||||
|
with:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
CATEGORY: "integration"
|
||||||
|
|
||||||
|
- name: Hassfest validation
|
||||||
|
uses: "home-assistant/actions/hassfest@master"
|
31
.github/workflows/pull.yml
vendored
Normal file
31
.github/workflows/pull.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
name: Pull actions
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
name: Validate
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v2"
|
||||||
|
|
||||||
|
- name: HACS validation
|
||||||
|
uses: "hacs/integration/action@master"
|
||||||
|
with:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
CATEGORY: "integration"
|
||||||
|
|
||||||
|
- name: Hassfest validation
|
||||||
|
uses: "home-assistant/actions/hassfest@master"
|
||||||
|
|
||||||
|
style:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
name: Check style formatting
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v2"
|
||||||
|
- uses: "actions/setup-python@v1"
|
||||||
|
with:
|
||||||
|
python-version: "3.x"
|
||||||
|
- run: python3 -m pip install black
|
||||||
|
- run: black .
|
34
.github/workflows/push.yml
vendored
Normal file
34
.github/workflows/push.yml
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
name: Push actions
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- dev
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
name: Validate
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v2"
|
||||||
|
|
||||||
|
- name: HACS validation
|
||||||
|
uses: "hacs/integration/action@master"
|
||||||
|
with:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
CATEGORY: "integration"
|
||||||
|
|
||||||
|
- name: Hassfest validation
|
||||||
|
uses: "home-assistant/actions/hassfest@master"
|
||||||
|
|
||||||
|
style:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
name: Check style formatting
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v2"
|
||||||
|
- uses: "actions/setup-python@v1"
|
||||||
|
with:
|
||||||
|
python-version: "3.x"
|
||||||
|
- run: python3 -m pip install black
|
||||||
|
- run: black .
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
__pycache__
|
29
.vscode/tasks.json
vendored
Normal file
29
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Run Home Assistant on port 9123",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "container start",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Run Home Assistant configuration against /config",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "container check",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Upgrade Home Assistant to latest dev",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "container install",
|
||||||
|
"problemMatcher": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Install a spesific version of Home Assistant",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "container set-version",
|
||||||
|
"problemMatcher": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
61
CONTRIBUTING.md
Normal file
61
CONTRIBUTING.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# 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. Test you contribution.
|
||||||
|
5. 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.
|
||||||
|
|
||||||
|
## Test your code modification
|
||||||
|
|
||||||
|
This custom component is based on [blueprint template](https://github.com/custom-components/blueprint).
|
||||||
|
|
||||||
|
It comes with development environement in a container, easy to launch
|
||||||
|
if you use Visual Studio Code. With this container you will have a stand alone
|
||||||
|
Home Assistant instance running and already configured with the included
|
||||||
|
[`.devcontainer/configuration.yaml`](https://github.com/oncleben31/ha-pool_pump/blob/master/.devcontainer/configuration.yaml)
|
||||||
|
file.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing, you agree that your contributions will be licensed under its MIT License.
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 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.
|
144
README.md
Normal file
144
README.md
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# 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
|
||||||
|
-- | --
|
||||||
|
`.devcontainer/*` | Used for development/testing with VSCODE, more info in the readme file in that dir.
|
||||||
|
`.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.
|
||||||
|
`.vscode/tasks.json` | Tasks for the devcontainer.
|
||||||
|
`custom_components/blueprint/.translations/*` | [Translation files.](https://developers.home-assistant.io/docs/en/next/internationalization_custom_component_localization.html#translation-strings)
|
||||||
|
`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/config_flow.py` | Config flow file, this adds the UI configuration possibilities.
|
||||||
|
`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.
|
||||||
|
`requirements.txt` | Python packages used by this integration.
|
||||||
|
|
||||||
|
## How?
|
||||||
|
|
||||||
|
If you want to use all the potential and features of this blueprint tempalte you
|
||||||
|
should use Visual Studio Code to develop in a container. In this container you
|
||||||
|
will have all the tools to ease your python development and a dedicated Home
|
||||||
|
Assistant core instance to run your integration. See `.devcontainer/README.md` for more information.
|
||||||
|
|
||||||
|
If you need to work on the python library in parallel of this integration
|
||||||
|
(`sampleclient` in this example) there are different options. The following one seems
|
||||||
|
easy to implement:
|
||||||
|
|
||||||
|
- Create a dedicated branch for your python library on a public git repository (example: branch
|
||||||
|
`dev` on `https://github.com/ludeeus/sampleclient`)
|
||||||
|
- Update in the `manifest.json` file the `requirements` key to point on your development branch
|
||||||
|
( example: `"requirements": ["git+https://github.com/ludeeus/sampleclient.git@dev#devp==0.0.1beta1"]`)
|
||||||
|
- Each time you need to make a modification to your python library, push it to your
|
||||||
|
development branch and increase the number of the python library version in `manifest.json` file
|
||||||
|
to ensure Home Assistant update the code of the python library. (example `"requirements": ["git+https://...==0.0.1beta2"]`).
|
||||||
|
|
||||||
|
|
||||||
|
***
|
||||||
|
README content if this was a published component:
|
||||||
|
***
|
||||||
|
|
||||||
|
# blueprint
|
||||||
|
|
||||||
|
[![GitHub Release][releases-shield]][releases]
|
||||||
|
[![GitHub Activity][commits-shield]][commits]
|
||||||
|
[![License][license-shield]](LICENSE)
|
||||||
|
|
||||||
|
[![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. Restart Home Assistant
|
||||||
|
7. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Blueprint"
|
||||||
|
|
||||||
|
Using your HA configuration directory (folder) as a starting point you should now also have this:
|
||||||
|
|
||||||
|
```text
|
||||||
|
custom_components/blueprint/.translations/en.json
|
||||||
|
custom_components/blueprint/.translations/nb.json
|
||||||
|
custom_components/blueprint/.translations/sensor.nb.json
|
||||||
|
custom_components/blueprint/__init__.py
|
||||||
|
custom_components/blueprint/binary_sensor.py
|
||||||
|
custom_components/blueprint/config_flow.py
|
||||||
|
custom_components/blueprint/const.py
|
||||||
|
custom_components/blueprint/manifest.json
|
||||||
|
custom_components/blueprint/sensor.py
|
||||||
|
custom_components/blueprint/switch.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration is done in the UI
|
||||||
|
|
||||||
|
<!---->
|
||||||
|
|
||||||
|
## 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
|
32
custom_components/blueprint/.translations/en.json
Normal file
32
custom_components/blueprint/.translations/en.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"title": "Blueprint",
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"title": "Blueprint",
|
||||||
|
"description": "If you need help with the configuration have a look here: https://github.com/custom-components/blueprint",
|
||||||
|
"data": {
|
||||||
|
"username": "Username",
|
||||||
|
"password": "Password"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"auth": "Username/Password is wrong."
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"single_instance_allowed": "Only a single configuration of Blueprint is allowed."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"binary_sensor": "Binary sensor enabled",
|
||||||
|
"sensor": "Sensor enabled",
|
||||||
|
"switch": "Switch enabled"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
custom_components/blueprint/.translations/nb.json
Normal file
32
custom_components/blueprint/.translations/nb.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"config": {
|
||||||
|
"title": "Blueprint",
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"title": "Blueprint",
|
||||||
|
"description": "Hvis du trenger hjep til konfigurasjon ta en titt her: https://github.com/custom-components/blueprint",
|
||||||
|
"data": {
|
||||||
|
"username": "Brukernavn",
|
||||||
|
"password": "Passord"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"auth": "Brukernavn/Passord er feil."
|
||||||
|
},
|
||||||
|
"abort": {
|
||||||
|
"single_instance_allowed": "Du kan konfigurere Blueprint kun en gang."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"binary_sensor": "Binær sensor aktivert",
|
||||||
|
"sensor": "Sensor aktivert",
|
||||||
|
"switch": "Bryter aktivert"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
custom_components/blueprint/.translations/sensor.nb.json
Normal file
5
custom_components/blueprint/.translations/sensor.nb.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"state": {
|
||||||
|
"Some sample static text.": "Eksempel tekst."
|
||||||
|
}
|
||||||
|
}
|
105
custom_components/blueprint/__init__.py
Normal file
105
custom_components/blueprint/__init__.py
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
"""
|
||||||
|
Custom integration to integrate blueprint with Home Assistant.
|
||||||
|
|
||||||
|
For more details about this integration, please refer to
|
||||||
|
https://github.com/custom-components/blueprint
|
||||||
|
"""
|
||||||
|
import asyncio
|
||||||
|
from datetime import timedelta
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
from homeassistant.core import Config, HomeAssistant
|
||||||
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||||
|
from sampleclient.client import Client
|
||||||
|
|
||||||
|
from custom_components.blueprint.const import (
|
||||||
|
CONF_PASSWORD,
|
||||||
|
CONF_USERNAME,
|
||||||
|
DOMAIN,
|
||||||
|
PLATFORMS,
|
||||||
|
STARTUP_MESSAGE,
|
||||||
|
)
|
||||||
|
|
||||||
|
SCAN_INTERVAL = timedelta(seconds=30)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup(hass: HomeAssistant, config: Config):
|
||||||
|
"""Set up this integration using YAML is not supported."""
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||||
|
"""Set up this integration using UI."""
|
||||||
|
if hass.data.get(DOMAIN) is None:
|
||||||
|
hass.data.setdefault(DOMAIN, {})
|
||||||
|
_LOGGER.info(STARTUP_MESSAGE)
|
||||||
|
|
||||||
|
username = entry.data.get(CONF_USERNAME)
|
||||||
|
password = entry.data.get(CONF_PASSWORD)
|
||||||
|
|
||||||
|
coordinator = BlueprintDataUpdateCoordinator(
|
||||||
|
hass, username=username, password=password
|
||||||
|
)
|
||||||
|
await coordinator.async_refresh()
|
||||||
|
|
||||||
|
if not coordinator.last_update_success:
|
||||||
|
raise ConfigEntryNotReady
|
||||||
|
|
||||||
|
hass.data[DOMAIN][entry.entry_id] = coordinator
|
||||||
|
|
||||||
|
for platform in PLATFORMS:
|
||||||
|
if entry.options.get(platform, True):
|
||||||
|
coordinator.platforms.append(platform)
|
||||||
|
hass.async_add_job(
|
||||||
|
hass.config_entries.async_forward_entry_setup(entry, platform)
|
||||||
|
)
|
||||||
|
|
||||||
|
entry.add_update_listener(async_reload_entry)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class BlueprintDataUpdateCoordinator(DataUpdateCoordinator):
|
||||||
|
"""Class to manage fetching data from the API."""
|
||||||
|
|
||||||
|
def __init__(self, hass, username, password):
|
||||||
|
"""Initialize."""
|
||||||
|
self.api = Client(username, password)
|
||||||
|
self.platforms = []
|
||||||
|
|
||||||
|
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=SCAN_INTERVAL)
|
||||||
|
|
||||||
|
async def _async_update_data(self):
|
||||||
|
"""Update data via library."""
|
||||||
|
try:
|
||||||
|
data = await self.api.async_get_data()
|
||||||
|
return data.get("data", {})
|
||||||
|
except Exception as exception:
|
||||||
|
raise UpdateFailed(exception)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||||
|
"""Handle removal of an entry."""
|
||||||
|
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
unloaded = all(
|
||||||
|
await asyncio.gather(
|
||||||
|
*[
|
||||||
|
hass.config_entries.async_forward_entry_unload(entry, platform)
|
||||||
|
for platform in PLATFORMS
|
||||||
|
if platform in coordinator.platforms
|
||||||
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if unloaded:
|
||||||
|
hass.data[DOMAIN].pop(entry.entry_id)
|
||||||
|
|
||||||
|
return unloaded
|
||||||
|
|
||||||
|
|
||||||
|
async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||||
|
"""Reload config entry."""
|
||||||
|
await async_unload_entry(hass, entry)
|
||||||
|
await async_setup_entry(hass, entry)
|
35
custom_components/blueprint/binary_sensor.py
Normal file
35
custom_components/blueprint/binary_sensor.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
"""Binary sensor platform for blueprint."""
|
||||||
|
from homeassistant.components.binary_sensor import BinarySensorDevice
|
||||||
|
|
||||||
|
from custom_components.blueprint.const import (
|
||||||
|
BINARY_SENSOR,
|
||||||
|
BINARY_SENSOR_DEVICE_CLASS,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
from custom_components.blueprint.entity import BlueprintEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, entry, async_add_devices):
|
||||||
|
"""Setup binary_sensor platform."""
|
||||||
|
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
async_add_devices([BlueprintBinarySensor(coordinator, entry)])
|
||||||
|
|
||||||
|
|
||||||
|
class BlueprintBinarySensor(BlueprintEntity, BinarySensorDevice):
|
||||||
|
"""blueprint binary_sensor class."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the binary_sensor."""
|
||||||
|
return f"{DEFAULT_NAME}_{BINARY_SENSOR}"
|
||||||
|
|
||||||
|
@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.coordinator.data.get("bool_on", False)
|
108
custom_components/blueprint/config_flow.py
Normal file
108
custom_components/blueprint/config_flow.py
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
"""Adds config flow for Blueprint."""
|
||||||
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.core import callback
|
||||||
|
from sampleclient.client import Client
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from custom_components.blueprint.const import ( # pylint: disable=unused-import
|
||||||
|
CONF_PASSWORD,
|
||||||
|
CONF_USERNAME,
|
||||||
|
DOMAIN,
|
||||||
|
PLATFORMS,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class BlueprintFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
|
"""Config flow for Blueprint."""
|
||||||
|
|
||||||
|
VERSION = 1
|
||||||
|
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Initialize."""
|
||||||
|
self._errors = {}
|
||||||
|
|
||||||
|
async def async_step_user(
|
||||||
|
self, user_input=None # pylint: disable=bad-continuation
|
||||||
|
):
|
||||||
|
"""Handle a flow initialized by the user."""
|
||||||
|
self._errors = {}
|
||||||
|
|
||||||
|
# Uncomment the next 2 lines if only a single instance of the integration is allowed:
|
||||||
|
# if self._async_current_entries():
|
||||||
|
# return self.async_abort(reason="single_instance_allowed")
|
||||||
|
|
||||||
|
if user_input is not None:
|
||||||
|
valid = await self._test_credentials(
|
||||||
|
user_input[CONF_USERNAME], user_input[CONF_PASSWORD]
|
||||||
|
)
|
||||||
|
if valid:
|
||||||
|
return self.async_create_entry(
|
||||||
|
title=user_input[CONF_USERNAME], data=user_input
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self._errors["base"] = "auth"
|
||||||
|
|
||||||
|
return await self._show_config_form(user_input)
|
||||||
|
|
||||||
|
return await self._show_config_form(user_input)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
@callback
|
||||||
|
def async_get_options_flow(config_entry):
|
||||||
|
return BlueprintOptionsFlowHandler(config_entry)
|
||||||
|
|
||||||
|
async def _show_config_form(self, user_input): # pylint: disable=unused-argument
|
||||||
|
"""Show the configuration form to edit location data."""
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="user",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str}
|
||||||
|
),
|
||||||
|
errors=self._errors,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _test_credentials(self, username, password):
|
||||||
|
"""Return true if credentials is valid."""
|
||||||
|
try:
|
||||||
|
client = Client(username, password)
|
||||||
|
await client.async_get_data()
|
||||||
|
return True
|
||||||
|
except Exception: # pylint: disable=broad-except
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class BlueprintOptionsFlowHandler(config_entries.OptionsFlow):
|
||||||
|
"""Blueprint config flow options handler."""
|
||||||
|
|
||||||
|
def __init__(self, config_entry):
|
||||||
|
"""Initialize HACS options flow."""
|
||||||
|
self.config_entry = config_entry
|
||||||
|
self.options = dict(config_entry.options)
|
||||||
|
|
||||||
|
async def async_step_init(self, user_input=None): # pylint: disable=unused-argument
|
||||||
|
"""Manage the options."""
|
||||||
|
return await self.async_step_user()
|
||||||
|
|
||||||
|
async def async_step_user(self, user_input=None):
|
||||||
|
"""Handle a flow initialized by the user."""
|
||||||
|
if user_input is not None:
|
||||||
|
self.options.update(user_input)
|
||||||
|
return await self._update_options()
|
||||||
|
|
||||||
|
return self.async_show_form(
|
||||||
|
step_id="user",
|
||||||
|
data_schema=vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(x, default=self.options.get(x, True)): bool
|
||||||
|
for x in sorted(PLATFORMS)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
async def _update_options(self):
|
||||||
|
"""Update config entry options."""
|
||||||
|
return self.async_create_entry(
|
||||||
|
title=self.config_entry.data.get(CONF_USERNAME), data=self.options
|
||||||
|
)
|
40
custom_components/blueprint/const.py
Normal file
40
custom_components/blueprint/const.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
"""Constants for blueprint."""
|
||||||
|
# Base component constants
|
||||||
|
NAME = "Blueprint"
|
||||||
|
DOMAIN = "blueprint"
|
||||||
|
DOMAIN_DATA = f"{DOMAIN}_data"
|
||||||
|
VERSION = "0.0.1"
|
||||||
|
|
||||||
|
ISSUE_URL = "https://github.com/custom-components/blueprint/issues"
|
||||||
|
|
||||||
|
# Icons
|
||||||
|
ICON = "mdi:format-quote-close"
|
||||||
|
|
||||||
|
# Device classes
|
||||||
|
BINARY_SENSOR_DEVICE_CLASS = "connectivity"
|
||||||
|
|
||||||
|
# Platforms
|
||||||
|
BINARY_SENSOR = "binary_sensor"
|
||||||
|
SENSOR = "sensor"
|
||||||
|
SWITCH = "switch"
|
||||||
|
PLATFORMS = [BINARY_SENSOR, SENSOR, SWITCH]
|
||||||
|
|
||||||
|
|
||||||
|
# Configuration and options
|
||||||
|
CONF_ENABLED = "enabled"
|
||||||
|
CONF_USERNAME = "username"
|
||||||
|
CONF_PASSWORD = "password"
|
||||||
|
|
||||||
|
# Defaults
|
||||||
|
DEFAULT_NAME = DOMAIN
|
||||||
|
|
||||||
|
|
||||||
|
STARTUP_MESSAGE = f"""
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
{NAME}
|
||||||
|
Version: {VERSION}
|
||||||
|
This is a custom integration!
|
||||||
|
If you have any issues with this you need to open an issue here:
|
||||||
|
{ISSUE_URL}
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
"""
|
52
custom_components/blueprint/entity.py
Normal file
52
custom_components/blueprint/entity.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
"""BlueprintEntity class"""
|
||||||
|
from homeassistant.helpers import entity
|
||||||
|
|
||||||
|
from custom_components.blueprint.const import DOMAIN, NAME, VERSION
|
||||||
|
|
||||||
|
|
||||||
|
class BlueprintEntity(entity.Entity):
|
||||||
|
def __init__(self, coordinator, config_entry):
|
||||||
|
self.coordinator = coordinator
|
||||||
|
self.config_entry = config_entry
|
||||||
|
|
||||||
|
@property
|
||||||
|
def should_poll(self):
|
||||||
|
"""No need to poll. Coordinator notifies entity of updates."""
|
||||||
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self):
|
||||||
|
"""Return if entity is available."""
|
||||||
|
return self.coordinator.last_update_success
|
||||||
|
|
||||||
|
@property
|
||||||
|
def unique_id(self):
|
||||||
|
"""Return a unique ID to use for this entity."""
|
||||||
|
return self.config_entry.entry_id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_info(self):
|
||||||
|
return {
|
||||||
|
"identifiers": {(DOMAIN, self.unique_id)},
|
||||||
|
"name": NAME,
|
||||||
|
"model": VERSION,
|
||||||
|
"manufacturer": NAME,
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_state_attributes(self):
|
||||||
|
"""Return the state attributes."""
|
||||||
|
return {
|
||||||
|
"time": str(self.coordinator.data.get("time")),
|
||||||
|
"static": self.coordinator.data.get("static"),
|
||||||
|
}
|
||||||
|
|
||||||
|
async def async_added_to_hass(self):
|
||||||
|
"""Connect to dispatcher listening for entity data notifications."""
|
||||||
|
self.async_on_remove(
|
||||||
|
self.coordinator.async_add_listener(self.async_write_ha_state)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_update(self):
|
||||||
|
"""Update Brother entity."""
|
||||||
|
await self.coordinator.async_request_refresh()
|
13
custom_components/blueprint/manifest.json
Normal file
13
custom_components/blueprint/manifest.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"domain": "blueprint",
|
||||||
|
"name": "Blueprint",
|
||||||
|
"documentation": "https://github.com/custom-components/blueprint",
|
||||||
|
"dependencies": [],
|
||||||
|
"config_flow": true,
|
||||||
|
"codeowners": [
|
||||||
|
"@ludeeus"
|
||||||
|
],
|
||||||
|
"requirements": [
|
||||||
|
"sampleclient"
|
||||||
|
]
|
||||||
|
}
|
28
custom_components/blueprint/sensor.py
Normal file
28
custom_components/blueprint/sensor.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
"""Sensor platform for blueprint."""
|
||||||
|
from custom_components.blueprint.const import DEFAULT_NAME, DOMAIN, ICON, SENSOR
|
||||||
|
from custom_components.blueprint.entity import BlueprintEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, entry, async_add_devices):
|
||||||
|
"""Setup sensor platform."""
|
||||||
|
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
async_add_devices([BlueprintSensor(coordinator, entry)])
|
||||||
|
|
||||||
|
|
||||||
|
class BlueprintSensor(BlueprintEntity):
|
||||||
|
"""blueprint Sensor class."""
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the sensor."""
|
||||||
|
return f"{DEFAULT_NAME}_{SENSOR}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def state(self):
|
||||||
|
"""Return the state of the sensor."""
|
||||||
|
return self.coordinator.data.get("static")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def icon(self):
|
||||||
|
"""Return the icon of the sensor."""
|
||||||
|
return ICON
|
40
custom_components/blueprint/switch.py
Normal file
40
custom_components/blueprint/switch.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
"""Switch platform for blueprint."""
|
||||||
|
from homeassistant.components.switch import SwitchDevice
|
||||||
|
|
||||||
|
from custom_components.blueprint.const import DEFAULT_NAME, DOMAIN, ICON, SWITCH
|
||||||
|
from custom_components.blueprint.entity import BlueprintEntity
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(hass, entry, async_add_devices):
|
||||||
|
"""Setup sensor platform."""
|
||||||
|
coordinator = hass.data[DOMAIN][entry.entry_id]
|
||||||
|
async_add_devices([BlueprintBinarySwitch(coordinator, entry)])
|
||||||
|
|
||||||
|
|
||||||
|
class BlueprintBinarySwitch(BlueprintEntity, SwitchDevice):
|
||||||
|
"""blueprint switch class."""
|
||||||
|
|
||||||
|
async def async_turn_on(self, **kwargs): # pylint: disable=unused-argument
|
||||||
|
"""Turn on the switch."""
|
||||||
|
await self.coordinator.api.async_change_something(True)
|
||||||
|
await self.coordinator.async_request_refresh()
|
||||||
|
|
||||||
|
async def async_turn_off(self, **kwargs): # pylint: disable=unused-argument
|
||||||
|
"""Turn off the switch."""
|
||||||
|
await self.coordinator.api.async_change_something(False)
|
||||||
|
await self.coordinator.async_request_refresh()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Return the name of the switch."""
|
||||||
|
return f"{DEFAULT_NAME}_{SWITCH}"
|
||||||
|
|
||||||
|
@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.coordinator.api.something
|
BIN
example.png
Normal file
BIN
example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 142 KiB |
11
hacs.json
Normal file
11
hacs.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "Blueprint",
|
||||||
|
"hacs": "0.24.0",
|
||||||
|
"domains": [
|
||||||
|
"binary_sensor",
|
||||||
|
"sensor",
|
||||||
|
"switch"
|
||||||
|
],
|
||||||
|
"iot_class": "Cloud Polling",
|
||||||
|
"homeassistant": "0.108.0"
|
||||||
|
}
|
54
info.md
Normal file
54
info.md
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
[![GitHub Release][releases-shield]][releases]
|
||||||
|
[![GitHub Activity][commits-shield]][commits]
|
||||||
|
[![License][license-shield]](LICENSE)
|
||||||
|
|
||||||
|
[![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. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Blueprint".
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
## Configuration is done in the UI
|
||||||
|
|
||||||
|
<!---->
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
[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
|
35
setup.cfg
Normal file
35
setup.cfg
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[flake8]
|
||||||
|
exclude = .venv,.git,.tox,docs,venv,bin,lib,deps,build
|
||||||
|
doctests = True
|
||||||
|
# To work with Black
|
||||||
|
max-line-length = 88
|
||||||
|
# E501: line too long
|
||||||
|
# W503: Line break occurred before a binary operator
|
||||||
|
# E203: Whitespace before ':'
|
||||||
|
# D202 No blank lines allowed after function docstring
|
||||||
|
# W504 line break after binary operator
|
||||||
|
ignore =
|
||||||
|
E501,
|
||||||
|
W503,
|
||||||
|
E203,
|
||||||
|
D202,
|
||||||
|
W504
|
||||||
|
|
||||||
|
[isort]
|
||||||
|
# https://github.com/timothycrosley/isort
|
||||||
|
# https://github.com/timothycrosley/isort/wiki/isort-Settings
|
||||||
|
# splits long import on multiple lines indented by 4 spaces
|
||||||
|
multi_line_output = 3
|
||||||
|
include_trailing_comma=True
|
||||||
|
force_grid_wrap=0
|
||||||
|
use_parentheses=True
|
||||||
|
line_length=88
|
||||||
|
indent = " "
|
||||||
|
# by default isort don't check module indexes
|
||||||
|
not_skip = __init__.py
|
||||||
|
# will group `import x` and `from x import` of the same module.
|
||||||
|
force_sort_within_sections = true
|
||||||
|
sections = FUTURE,STDLIB,INBETWEENS,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
|
||||||
|
default_section = THIRDPARTY
|
||||||
|
known_first_party = custom_components.blueprint
|
||||||
|
combine_as_imports = true
|
Loading…
Reference in New Issue
Block a user