From 5e225f3bb79db5bc4972b2f39d0c8b6a36755de1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 6 Aug 2020 14:29:27 +0200 Subject: [PATCH] Initial commit --- .gitattributes | 1 + .github/ISSUE_TEMPLATE/feature_request.md | 17 +++ .gitignore | 2 + LICENSE | 21 +++ README.md | 144 ++++++++++++++++++ custom_components/dwd_weather/__init__.py | 69 +++++++++ custom_components/dwd_weather/config_flow.py | 73 +++++++++ custom_components/dwd_weather/connector.py | 65 ++++++++ custom_components/dwd_weather/const.py | 14 ++ custom_components/dwd_weather/manifest.json | 11 ++ custom_components/dwd_weather/strings.json | 23 +++ .../dwd_weather/translations/en.json | 22 +++ custom_components/dwd_weather/weather.py | 108 +++++++++++++ hacs.json | 8 + info.md | 54 +++++++ requirements.txt | 0 16 files changed, 632 insertions(+) create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 custom_components/dwd_weather/__init__.py create mode 100644 custom_components/dwd_weather/config_flow.py create mode 100644 custom_components/dwd_weather/connector.py create mode 100644 custom_components/dwd_weather/const.py create mode 100644 custom_components/dwd_weather/manifest.json create mode 100644 custom_components/dwd_weather/strings.json create mode 100644 custom_components/dwd_weather/translations/en.json create mode 100644 custom_components/dwd_weather/weather.py create mode 100644 hacs.json create mode 100644 info.md create mode 100644 requirements.txt diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..94f480d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..6bcce42 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -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. \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b62f12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +.vscode \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cd61917 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 FL550 + +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 new file mode 100644 index 0000000..1d56b27 --- /dev/null +++ b/README.md @@ -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 diff --git a/custom_components/dwd_weather/__init__.py b/custom_components/dwd_weather/__init__.py new file mode 100644 index 0000000..ccca1f9 --- /dev/null +++ b/custom_components/dwd_weather/__init__.py @@ -0,0 +1,69 @@ +"""The DWD Weather component.""" + +import logging + +from homeassistant.core import Config, HomeAssistant +from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME +from homeassistant.exceptions import ConfigEntryNotReady +from homeassistant.helpers.update_coordinator import DataUpdateCoordinator + +# from .config_flow import DWDWeatherConfigFlow # noqa: F401 +from .const import (DOMAIN, DEFAULT_SCAN_INTERVAL, DWDWEATHER_DATA, + DWDWEATHER_COORDINATOR, DWDWEATHER_NAME) # noqa: F401 +from .connector import DWDWeatherData + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup(hass: HomeAssistant, config: Config) -> bool: + """Set up configured DWD Weather.""" + return True + + +async def async_setup_entry(hass, entry): + """Set up DWD Weather as config entry.""" + + latitude = entry.data[CONF_LATITUDE] + longitude = entry.data[CONF_LONGITUDE] + site_name = entry.data[CONF_NAME] + + dwd_weather_data = DWDWeatherData(hass, latitude, longitude) + + await dwd_weather_data.async_update() + if dwd_weather_data.weather_data.get_station_name(False) == '': + raise ConfigEntryNotReady() + + dwdweather_coordinator = DataUpdateCoordinator( + hass, + _LOGGER, + name=f"DWD Weather Coordinator for {site_name}", + update_method=dwd_weather_data.async_update, + update_interval=DEFAULT_SCAN_INTERVAL, + ) + + dwdweather_hass_data = hass.data.setdefault(DOMAIN, {}) + dwdweather_hass_data[entry.entry_id] = { + DWDWEATHER_DATA: dwd_weather_data, + DWDWEATHER_COORDINATOR: dwdweather_coordinator, + DWDWEATHER_NAME: site_name, + } + + # Fetch initial data so we have data when entities subscribe + await dwdweather_coordinator.async_refresh() + if dwd_weather_data.weather_data.get_station_name == '': + raise ConfigEntryNotReady() + hass.async_create_task( + hass.config_entries.async_forward_entry_setup(entry, "weather")) + return True + + +async def async_update(self): + """Async wrapper for update method.""" + return await self._hass.async_add_executor_job(self._update) + + +async def async_unload_entry(hass, config_entry): + """Unload a config entry.""" + await hass.config_entries.async_forward_entry_unload( + config_entry, "weather") + return True diff --git a/custom_components/dwd_weather/config_flow.py b/custom_components/dwd_weather/config_flow.py new file mode 100644 index 0000000..a811a62 --- /dev/null +++ b/custom_components/dwd_weather/config_flow.py @@ -0,0 +1,73 @@ +"""Config flow for Deutscher Wetterdienst integration.""" +import logging + +import voluptuous as vol + +from homeassistant import config_entries, core, exceptions +from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME +from homeassistant.helpers import config_validation as cv + +from .const import DOMAIN + +from .connector import DWDWeatherData + +_LOGGER = logging.getLogger(__name__) + + +async def validate_input(hass: core.HomeAssistant, data): + """Validate the user input + + Data has the keys from DATA_SCHEMA with values provided by the user. + """ + latitude = data[CONF_LATITUDE] + longitude = data[CONF_LONGITUDE] + + dwd_weather_data = DWDWeatherData(hass, latitude, longitude) + await dwd_weather_data.async_update() + if dwd_weather_data.weather_data.get_station_name(False) == '': + raise CannotConnect() + + return {"site_name": dwd_weather_data.weather_data.get_station_name(False)} + + +class DWDWeatherConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): + """Handle a config flow for DWD weather integration.""" + + VERSION = 1 + CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL + + async def async_step_user(self, user_input=None): + """Handle the initial step.""" + errors = {} + if user_input is not None: + await self.async_set_unique_id( + f"{user_input[CONF_LATITUDE]}_{user_input[CONF_LONGITUDE]}") + self._abort_if_unique_id_configured() + + try: + info = await validate_input(self.hass, user_input) + except CannotConnect: + errors["base"] = "cannot_connect" + except Exception: # pylint: disable=broad-except + _LOGGER.exception("Unexpected exception") + errors["base"] = "unknown" + else: + user_input[CONF_NAME] = info["site_name"] + return self.async_create_entry(title=user_input[CONF_NAME], + data=user_input) + + data_schema = vol.Schema( + { + vol.Required(CONF_LATITUDE, default=self.hass.config.latitude): + cv.latitude, + vol.Required(CONF_LONGITUDE, default=self.hass.config.longitude): + cv.longitude, + },) + + return self.async_show_form(step_id="user", + data_schema=data_schema, + errors=errors) + + +class CannotConnect(exceptions.HomeAssistantError): + """Error to indicate we cannot connect.""" diff --git a/custom_components/dwd_weather/connector.py b/custom_components/dwd_weather/connector.py new file mode 100644 index 0000000..931fc1c --- /dev/null +++ b/custom_components/dwd_weather/connector.py @@ -0,0 +1,65 @@ +import logging +from datetime import datetime, timezone, timedelta + +from simple_dwd_weatherforecast import dwdforecast + +from homeassistant.components.weather import ( + ATTR_FORECAST_CONDITION, + ATTR_FORECAST_PRECIPITATION, + ATTR_FORECAST_TEMP, + ATTR_FORECAST_TEMP_LOW, + ATTR_FORECAST_TIME, +) + +_LOGGER = logging.getLogger(__name__) + + +class DWDWeatherData: + + def __init__(self, hass, latitude, longitude): + """Initialize the data object.""" + self._hass = hass + self._site = None + self.forecast = None + + # Public attributes + self.latitude = latitude + self.longitude = longitude + + # Holds the current data from the Met Office + self.site_id = dwdforecast.get_nearest_station_id(latitude, longitude) + self.weather_data = dwdforecast.Weather(self.site_id) + + async def async_update(self): + """Async wrapper for update method.""" + return await self._hass.async_add_executor_job(self._update) + + def _update(self): + """Get the latest data from DWD.""" + self.weather_data.update() + forecast_data = [] + timestamp = datetime.now(timezone.utc) + for x in range(0, 8): + forecast_data.append({ + ATTR_FORECAST_TIME: + timestamp.strftime("%Y-%m-%d"), + ATTR_FORECAST_CONDITION: + self.weather_data.get_daily_condition(timestamp, False), + ATTR_FORECAST_TEMP: + float(self.weather_data.get_daily_temp_max( + timestamp, False)), + ATTR_FORECAST_TEMP_LOW: + float(self.weather_data.get_daily_temp_min( + timestamp, False)), + ATTR_FORECAST_PRECIPITATION: + float( + self.weather_data.get_daily_precipitation( + timestamp, False)), + "precipitation_probability": + int( + self.weather_data.get_daily_precipitation_probability( + timestamp, + False)), # ATTR_FORECAST_PRECIPITATION_PROBABILITY + }) + timestamp = timestamp + timedelta(days=1) + self.forecast = forecast_data diff --git a/custom_components/dwd_weather/const.py b/custom_components/dwd_weather/const.py new file mode 100644 index 0000000..1a72cba --- /dev/null +++ b/custom_components/dwd_weather/const.py @@ -0,0 +1,14 @@ +"""Constants for the DWD Weather integration.""" +from datetime import timedelta + +DOMAIN = "dwd_weather" + +DEFAULT_NAME = "DWD Weather" +ATTRIBUTION = "Data provided by Deutscher Wetterdienst (DWD)" + +DEFAULT_SCAN_INTERVAL = timedelta(minutes=15) + +DWDWEATHER_DATA = "dwd_weather_data" +DWDWEATHER_COORDINATOR = "dwd_weather_coordinator" +DWDWEATHER_MONITORED_CONDITIONS = "dwd_weather_monitored_conditions" +DWDWEATHER_NAME = "dwd_weather_name" diff --git a/custom_components/dwd_weather/manifest.json b/custom_components/dwd_weather/manifest.json new file mode 100644 index 0000000..83c3018 --- /dev/null +++ b/custom_components/dwd_weather/manifest.json @@ -0,0 +1,11 @@ +{ + "domain": "dwd_weather", + "name": "DWD Weather", + "documentation": "https://github.com/FL550/dwd_weather", + "dependencies": [], + "config_flow": true, + "codeowners": [ + "@FL550" + ], + "requirements": ["simple_dwd_weatherforecast==0.9.10"] +} diff --git a/custom_components/dwd_weather/strings.json b/custom_components/dwd_weather/strings.json new file mode 100644 index 0000000..197ff47 --- /dev/null +++ b/custom_components/dwd_weather/strings.json @@ -0,0 +1,23 @@ +{ + "#TODO": "Check values", + "title": "Deutscher Wetterdienst", + "config": { + "step": { + "user": { + "data": { + "host": "[%key:common::config_flow::data::host%]", + "username": "[%key:common::config_flow::data::username%]", + "password": "[%key:common::config_flow::data::password%]" + } + } + }, + "error": { + "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", + "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", + "unknown": "[%key:common::config_flow::error::unknown%]" + }, + "abort": { + "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" + } + } +} \ No newline at end of file diff --git a/custom_components/dwd_weather/translations/en.json b/custom_components/dwd_weather/translations/en.json new file mode 100644 index 0000000..a2b4f4d --- /dev/null +++ b/custom_components/dwd_weather/translations/en.json @@ -0,0 +1,22 @@ +{ + "config": { + "abort": { + "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" + }, + "error": { + "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", + "invalid_auth": "[%key:common::config_flow::error::invalid_auth%]", + "unknown": "[%key:common::config_flow::error::unknown%]" + }, + "step": { + "user": { + "data": { + "host": "[%key:common::config_flow::data::host%]", + "password": "[%key:common::config_flow::data::password%]", + "username": "[%key:common::config_flow::data::username%]" + } + } + } + }, + "title": "Deutscher Wetterdienst" +} \ No newline at end of file diff --git a/custom_components/dwd_weather/weather.py b/custom_components/dwd_weather/weather.py new file mode 100644 index 0000000..485058c --- /dev/null +++ b/custom_components/dwd_weather/weather.py @@ -0,0 +1,108 @@ +"""Support for DWD weather service.""" +import logging +from datetime import datetime, timezone + +from homeassistant.components.weather import WeatherEntity +from homeassistant.const import ( + TEMP_CELSIUS,) + +from homeassistant.helpers.typing import ConfigType, HomeAssistantType + +from .const import (DEFAULT_NAME, ATTRIBUTION, DOMAIN, DWDWEATHER_DATA, + DWDWEATHER_COORDINATOR, DWDWEATHER_NAME) + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry(hass: HomeAssistantType, entry: ConfigType, + async_add_entities) -> None: + """Add a weather entity from a config_entry.""" + hass_data = hass.data[DOMAIN][entry.entry_id] + async_add_entities([DWDWeather(entry.data, hass_data)], False) + + +class DWDWeather(WeatherEntity): + """Implementation of DWD weather.""" + + def __init__(self, entry_data, hass_data): + """Initialise the platform with a data instance and site.""" + self._data = hass_data[DWDWEATHER_DATA] + self._coordinator = hass_data[DWDWEATHER_COORDINATOR] + + self._name = f"{DEFAULT_NAME} {hass_data[DWDWEATHER_NAME]}" + self._unique_id = f"{self._data.latitude}_{self._data.longitude}" + + @property + def should_poll(self): + """No polling needed.""" + return False + + @property + def unique_id(self): + """Return unique ID.""" + return self._unique_id + + @property + def name(self): + """Return the name of the sensor.""" + self._name + + @property + def condition(self): + """Return the current condition.""" + return self._data.weather_data.get_forecast_condition( + datetime.now(timezone.utc), False) + + @property + def temperature(self): + """Return the temperature.""" + return float( + self._data.weather_data.get_forecast_temperature( + datetime.now(timezone.utc), False)) + + @property + def temperature_unit(self): + """Return the unit of measurement.""" + return TEMP_CELSIUS + + @property + def pressure(self): + """Return the pressure.""" + return float( + self._data.weather_data.get_forecast_pressure( + datetime.now(timezone.utc), False)) + + @property + def wind_speed(self): + """Return the wind speed.""" + return float( + self._data.weather_data.get_forecast_wind_speed( + datetime.now(timezone.utc), False)) + + @property + def wind_bearing(self): + """Return the wind direction.""" + return self._data.weather_data.get_forecast_wind_direction( + datetime.now(timezone.utc), False) + + @property + def visibility(self): + """Return the visibility.""" + return float( + self._data.weather_data.get_forecast_visibility( + datetime.now(timezone.utc), False)) / 1000 + + @property + def humidity(self): + """Return the relative humidity.""" + return None + + @property + def attribution(self): + """Return the attribution.""" + return ATTRIBUTION + + @property + def forecast(self): + """Return the forecast array.""" + return self._data.forecast diff --git a/hacs.json b/hacs.json new file mode 100644 index 0000000..672c49a --- /dev/null +++ b/hacs.json @@ -0,0 +1,8 @@ +{ + "name": "Deutscher Wetterdienst", + "domains": [ + "weather" + ], + "iot_class": "Cloud Polling", + "render_readme": true +} \ No newline at end of file diff --git a/info.md b/info.md new file mode 100644 index 0000000..4a097f5 --- /dev/null +++ b/info.md @@ -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 diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e69de29