Skip to content

Commit

Permalink
Good enough - initial integration
Browse files Browse the repository at this point in the history
  • Loading branch information
Netzwerkfehler committed Aug 12, 2024
1 parent 42ba8a8 commit dd2de28
Show file tree
Hide file tree
Showing 30 changed files with 744 additions and 577 deletions.
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ body:
required: true
- label: This issue only contains 1 issue (if you have multiple issues, open one issue for each issue).
required: true
- label: This issue is not a duplicate issue of any [previous issues](https://github.com/ludeeus/integration_blueprint/issues?q=is%3Aissue+label%3A%22Bug%22+)..
- label: This issue is not a duplicate issue of any [previous issues](https://github.com/Netzwerkfehler/hass-GFM2/issues?q=is%3Aissue+label%3A%22Bug%22+)..
required: true
- type: textarea
attributes:
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ body:
required: true
- label: This only contains 1 feature request (if you have multiple feature requests, open one feature request for each feature request).
required: true
- label: This issue is not a duplicate feature request of [previous feature requests](https://github.com/ludeeus/integration_blueprint/issues?q=is%3Aissue+label%3A%22Feature+Request%22+).
- label: This issue is not a duplicate feature request of [previous feature requests](https://github.com/Netzwerkfehler/hass-GFM2/issues?q=is%3Aissue+label%3A%22Feature+Request%22+).
required: true

- type: textarea
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ jobs:
- name: "ZIP the integration directory"
shell: "bash"
run: |
cd "${{ github.workspace }}/custom_components/integration_blueprint"
zip integration_blueprint.zip -r ./
cd "${{ github.workspace }}/custom_components/gfm2"
zip gfm2.zip -r ./
- name: "Upload the ZIP file to the release"
uses: "softprops/action-gh-release@v2.0.8"
with:
files: ${{ github.workspace }}/custom_components/integration_blueprint/integration_blueprint.zip
files: ${{ github.workspace }}/custom_components/gfm2/gfm2.zip
109 changes: 62 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,62 @@
# 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.

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 | Documentation
-- | -- | --
`.devcontainer.json` | Used for development/testing with Visual Studio Code. | [Documentation](https://code.visualstudio.com/docs/remote/containers)
`.github/ISSUE_TEMPLATE/*.yml` | Templates for the issue tracker | [Documentation](https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository)
`.vscode/tasks.json` | Tasks for the devcontainer. | [Documentation](https://code.visualstudio.com/docs/editor/tasks)
`custom_components/integration_blueprint/*` | Integration files, this is where everything happens. | [Documentation](https://developers.home-assistant.io/docs/creating_component_index)
`CONTRIBUTING.md` | Guidelines on how to contribute. | [Documentation](https://help.github.com/en/github/building-a-strong-community/setting-guidelines-for-repository-contributors)
`LICENSE` | The license file for the project. | [Documentation](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/licensing-a-repository)
`README.md` | The file you are reading now, should contain info about the integration, installation and configuration instructions. | [Documentation](https://help.github.com/en/github/writing-on-github/basic-writing-and-formatting-syntax)
`requirements.txt` | Python packages used for development/lint/testing this integration. | [Documentation](https://pip.pypa.io/en/stable/user_guide/#requirements-files)

## How?

1. Create a new repository in GitHub, using this repository as a template by clicking the "Use this template" button in the GitHub UI.
1. Open your new repository in Visual Studio Code devcontainer (Preferably with the "`Dev Containers: Clone Repository in Named Container Volume...`" option).
1. Rename all instances of the `integration_blueprint` to `custom_components/<your_integration_domain>` (e.g. `custom_components/awesome_integration`).
1. Rename all instances of the `Integration Blueprint` to `<Your Integration Name>` (e.g. `Awesome Integration`).
1. Run the `scripts/develop` to start HA and test out your new integration.

## Next steps

These are some next steps you may want to look into:
- Add tests to your integration, [`pytest-homeassistant-custom-component`](https://github.com/MatthewFlamm/pytest-homeassistant-custom-component) can help you get started.
- Add brand images (logo/icon) to https://github.com/home-assistant/brands.
- Create your first release.
- Share your integration on the [Home Assistant Forum](https://community.home-assistant.io/).
- Submit your integration to [HACS](https://hacs.xyz/docs/publish/start).
# Telekom Glasfaser-Modem 2

[![GitHub Release][releases-shield]][releases]
[![GitHub Activity][commits-shield]][commits]
[![License][license-shield]](LICENSE)

_Home Assistant integration to integrate with the [Telekom Glasfaser-Modem 2](https://www.telekom.de/zuhause/geraete-und-zubehoer/wlan-und-router/glasfaser-modem-2)._

## Sensors
TODO
## Buttons
TODO

### Internals
This integration queries these endpoints:
Method | Endpoint
------ | --------
GET | /ONT/client/data/Status.json
GET | /ONT/client/data/FirmwareUpdate.json
GET | /ONT/client/data/Reboot.json
POST | /ONT/client/data/Reboot.json

## Installation

### Preconditions
For this integration to work, the modem must be accessible from the Home Assistant host. This requires certain NAT rules to be configured on the router, which is unfortunately not possible with most home routers. (Advanced routers such as OPNsense, pfSense or similar are required for this)

You can use this link to check whether your modem can be reached if you are using the default IP address:
http://192.168.100.1/ONT/client/html/content/overview/status.html

**If the modem is not reachable, you cannot use this integration!**

### Custom Repository (Recommended)
1. Add `https://github.com/Netzwerkfehler/hass-GFM2` as a [custom repository](https://hacs.xyz/docs/faq/custom_repositories/) in HACS.
1. Restart Home Assistant
1. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Telekom Glasfaser-Modem 2"

### Manual
1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`).
1. If you do not have a `custom_components` directory (folder) there, you need to create it.
1. In the `custom_components` directory (folder) create a new folder called `gfm2`.
1. Download _all_ the files from the `custom_components/gfm2/` directory (folder) in this repository.
1. Place the files you downloaded in the new directory (folder) you created.
1. Restart Home Assistant
1. In the HA UI go to "Configuration" -> "Integrations" click "+" and search for "Telekom Glasfaser-Modem 2"

## Configuration is done in the UI

In this integration, only the IP address of the modem is required as a configuration parameter. It is prefilled with `192.168.100.1` and does not normally need to be changed.

## Contributions are welcome!

If you want to contribute to this please read the [Contribution guidelines](CONTRIBUTING.md)

***

[commits-shield]: https://img.shields.io/github/commit-activity/y/Netzwerkfehler/hass-GFM2.svg?style=for-the-badge
[commits]: https://github.com/Netzwerkfehler/hass-GFM2/commits/main
[exampleimg]: example.png
[license-shield]: https://img.shields.io/github/license/Netzwerkfehler/hass-GFM2.svg?style=for-the-badge
[releases-shield]: https://img.shields.io/github/release/Netzwerkfehler/hass-GFM2.svg?style=for-the-badge
[releases]: https://github.com/Netzwerkfehler/hass-GFM2/releases
56 changes: 0 additions & 56 deletions README_EXAMPLE.md

This file was deleted.

2 changes: 1 addition & 1 deletion config/configuration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ homeassistant:
logger:
default: info
logs:
custom_components.integration_blueprint: debug
custom_components.gfm2: debug
Original file line number Diff line number Diff line change
@@ -1,48 +1,49 @@
"""
Custom integration to integrate integration_blueprint with Home Assistant.
Custom integration to integrate Glasfaser-Modem 2 with Home Assistant.
For more details about this integration, please refer to
https://github.com/ludeeus/integration_blueprint
https://github.com/Netzwerkfehler/hass-GFM2
"""

from __future__ import annotations

from typing import TYPE_CHECKING

from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.const import CONF_IP_ADDRESS, Platform
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.loader import async_get_loaded_integration

from .api import IntegrationBlueprintApiClient
from .coordinator import BlueprintDataUpdateCoordinator
from .data import IntegrationBlueprintData
from custom_components.gfm2.gfm2 import Gfm2

from .api import Gfm2ApiClient
from .coordinator import Gfm2DataUpdateCoordinator
from .data import Gfm2Data

if TYPE_CHECKING:
from homeassistant.core import HomeAssistant

from .data import IntegrationBlueprintConfigEntry
from .data import Gfm2ConfigEntry

PLATFORMS: list[Platform] = [
Platform.SENSOR,
Platform.BINARY_SENSOR,
Platform.SWITCH,
Platform.BUTTON,
]


# https://developers.home-assistant.io/docs/config_entries_index/#setting-up-an-entry
async def async_setup_entry(
hass: HomeAssistant,
entry: IntegrationBlueprintConfigEntry,
entry: Gfm2ConfigEntry,
) -> bool:
"""Set up this integration using UI."""
coordinator = BlueprintDataUpdateCoordinator(
hass=hass,
)
entry.runtime_data = IntegrationBlueprintData(
client=IntegrationBlueprintApiClient(
username=entry.data[CONF_USERNAME],
password=entry.data[CONF_PASSWORD],
session=async_get_clientsession(hass),
coordinator = Gfm2DataUpdateCoordinator(hass=hass)
entry.runtime_data = Gfm2Data(
device=Gfm2(
Gfm2ApiClient(
ip_address=entry.data[CONF_IP_ADDRESS],
session=async_get_clientsession(hass),
)
),
integration=async_get_loaded_integration(hass, entry.domain),
coordinator=coordinator,
Expand All @@ -57,18 +58,18 @@ async def async_setup_entry(
return True


async def async_unload_entry(
hass: HomeAssistant,
entry: IntegrationBlueprintConfigEntry,
) -> bool:
"""Handle removal of an entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)


async def async_reload_entry(
hass: HomeAssistant,
entry: IntegrationBlueprintConfigEntry,
entry: Gfm2ConfigEntry,
) -> None:
"""Reload config entry."""
await async_unload_entry(hass, entry)
await async_setup_entry(hass, entry)


async def async_unload_entry(
hass: HomeAssistant,
entry: Gfm2ConfigEntry,
) -> bool:
"""Handle removal of an entry."""
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
99 changes: 99 additions & 0 deletions custom_components/gfm2/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
"""GFM2 API Client."""

from __future__ import annotations

import socket
from typing import Any

import aiohttp
import async_timeout


class Gfm2ApiClientError(Exception):
"""Exception to indicate a general API error."""


class Gfm2ApiClientCommunicationError(
Gfm2ApiClientError,
):
"""Exception to indicate a communication error."""


class Gfm2ApiClient:
"""GFM2 API Client."""

def __init__(
self,
ip_address: str,
session: aiohttp.ClientSession,
) -> None:
"""GFM2 API Client."""
self._ip_address = ip_address
self._session = session

async def async_get_status_data(self) -> Any:
"""Get status data from the API."""
return await self._api_wrapper(
method="get",
url=f"http://{self._ip_address}/ONT/client/data/Status.json",
headers={"Accept-Language": "en"},
)

async def async_get_firmware_data(self) -> Any:
"""Get firmware status data from the API."""
return await self._api_wrapper(
method="get",
url=f"http://{self._ip_address}/ONT/client/data/FirmwareUpdate.json",
headers={"Accept-Language": "en"},
)

async def async_get_reboot_data(self) -> Any:
"""Get reboot status data from the API."""
return await self._api_wrapper(
method="get",
url=f"http://{self._ip_address}/ONT/client/data/Reboot.json",
headers={"Accept-Language": "en"},
)

async def async_do_reboot(self) -> Any:
"""Trigger a reboot from the API."""
return await self._api_wrapper(
method="post",
url=f"http://{self._ip_address}/ONT/client/data/Reboot.json",
headers={"Accept-Language": "en"},
data={"Reboot": "true"},
)

async def _api_wrapper(
self,
method: str,
url: str,
data: dict | None = None,
headers: dict | None = None,
) -> Any:
"""Get information from the API."""
try:
async with async_timeout.timeout(10):
response = await self._session.request(
method=method,
url=url,
headers=headers,
json=data,
)
return await response.json(content_type="application/javascript")

except TimeoutError as exception:
msg = f"Timeout error fetching information - {exception}"
raise Gfm2ApiClientCommunicationError(
msg,
) from exception
except (aiohttp.ClientError, socket.gaierror) as exception:
msg = f"Error fetching information - {exception}"
raise Gfm2ApiClientCommunicationError(
msg,
) from exception
except Exception as exception: # pylint: disable=broad-except
msg = f"Something really wrong happened! - {exception}"
raise Gfm2ApiClientError(
msg,
) from exception
Loading

0 comments on commit dd2de28

Please sign in to comment.