Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
th0r88 committed Dec 19, 2024
0 parents commit 70a4d87
Show file tree
Hide file tree
Showing 12 changed files with 433 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
14 changes: 14 additions & 0 deletions .github/workflows/hassfest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Validate with hassfest

on:
push:
pull_request:
schedule:
- cron: "0 0 * * *"

jobs:
validate:
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v3"
- uses: home-assistant/actions/hassfest@master
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Jan Ferme

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.
74 changes: 74 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Waste Collection Kranj

[![hacs_badge](https://img.shields.io/badge/HACS-Custom-41BDF5.svg)](https://github.com/hacs/integration)

Home Assistant integration for Komunala Kranj waste collection schedule. Get notifications about upcoming waste collection dates and see the schedule in a color-coded dashboard.

## Features

- Shows upcoming waste collection dates
- Color-coded by waste type (Yellow for EMB, Brown for BIO, Green for MKO)
- Sends notifications day before collection at 8 PM
- Easy setup through UI
- Supports multiple waste types:
- ODPADNA EMBALAŽA (Waste Packaging)
- BIOLOŠKI ODPADKI (Biological Waste)
- MEŠANI KOMUNALNI ODPADKI (Mixed Waste)

## Installation

1. Add this repository to HACS as a custom repository:
- HACS -> Integrations -> Three dots menu -> Custom repositories
- URL: https://github.com/th0r88/hacs-waste-collection-komunala-kranj
- Category: Integration

2. Install the integration through HACS
3. Restart Home Assistant
4. Go to Settings -> Devices & Services
5. Click "+ ADD INTEGRATION"
6. Search for "Waste Collection Kranj"
7. Enter your household ID (hsMid)

## Configuration

| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| hsmid | string | yes | - | Your household ID from Komunala Kranj |
| name | string | no | Waste Collection Kranj | Name of the sensor |

## Dashboard Card

After installation, you can add this card to your dashboard:

```yaml
type: custom:auto-entities
filter:
include:
- entity_id: sensor.waste_collection_kranj
card:
type: custom:stack-in-card
cards:
- type: markdown
content: >
{% set collections = state_attr('sensor.waste_collection_kranj',
'collections') %}
{% if collections %}
{% for collection in collections %}
{% set color = collection.color %}
{% set date = collection.date %}
{% set type = collection.description %}
<div style="
padding: 10px;
margin: 5px;
background-color: {{ color }};
border-radius: 5px;
color: {% if color == '#f9df2e' %}black{% else %}white{% endif %};
">
{{ date }} - {{ type }}
</div>
{% endfor %}
{% else %}
<div style="padding: 10px; margin: 5px;">
No upcoming waste collections found
</div>
{% endif %}
Binary file added custom_components/.DS_Store
Binary file not shown.
30 changes: 30 additions & 0 deletions custom_components/waste_collection_komunala_kranj/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""The Waste Collection Kranj integration."""
from __future__ import annotations

import logging

from homeassistant.config_entries import ConfigEntry # type: ignore
from homeassistant.const import Platform # type: ignore
from homeassistant.core import HomeAssistant # type: ignore

from .const import DOMAIN

PLATFORMS: list[Platform] = [Platform.SENSOR]

_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Waste Collection Kranj from a config entry."""
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = entry.data

await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

return True

async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Unload a config entry."""
if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS):
hass.data[DOMAIN].pop(entry.entry_id)

return unload_ok
76 changes: 76 additions & 0 deletions custom_components/waste_collection_komunala_kranj/config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Config flow for Waste Collection Kranj integration."""
from __future__ import annotations

import logging
from typing import Any

import voluptuous as vol # type: ignore
import aiohttp # type: ignore

from homeassistant import config_entries # type: ignore
from homeassistant.core import HomeAssistant # type: ignore
from homeassistant.data_entry_flow import FlowResult # type: ignore
from homeassistant.exceptions import HomeAssistantError # type: ignore

from .const import DOMAIN, BASE_URL

_LOGGER = logging.getLogger(__name__)

STEP_USER_DATA_SCHEMA = vol.Schema(
{
vol.Required("hsmid"): str,
vol.Optional("name", default="Waste Collection Kranj"): str,
}
)

async def validate_input(hass: HomeAssistant, data: dict[str, Any]) -> dict[str, Any]:
"""Validate the user input allows us to connect."""

# Test the connection and data
async with aiohttp.ClientSession() as session:
params = {
"a": "komunalakranj",
"hsMid": data["hsmid"],
"stDni": "30",
"_": "1"
}

async with session.get(BASE_URL, params=params) as response:
if response.status != 200:
raise InvalidAuth

return {"title": f"Waste Collection Kranj {data['hsmid']}"}

class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Waste Collection Kranj."""

VERSION = 1

async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> FlowResult:
"""Handle the initial step."""
errors: dict[str, str] = {}

if user_input is not None:
try:
info = await validate_input(self.hass, user_input)
except CannotConnect:
errors["base"] = "cannot_connect"
except InvalidAuth:
errors["base"] = "invalid_auth"
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"
else:
return self.async_create_entry(title=info["title"], data=user_input)

return self.async_show_form(
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors
)

class CannotConnect(HomeAssistantError):
"""Error to indicate we cannot connect."""

class InvalidAuth(HomeAssistantError):
"""Error to indicate there is invalid auth."""
24 changes: 24 additions & 0 deletions custom_components/waste_collection_komunala_kranj/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Constants for the Waste Collection Kranj integration."""
DOMAIN = "waste_collection_kranj"

DEFAULT_NAME = "Waste Collection Kranj"
DEFAULT_UPDATE_INTERVAL = 3600 # 1 hour in seconds

# Configuration constants
CONF_HSMID = "hsmid"

# API constants
BASE_URL = "https://gis.komunala-kranj.si/ddmoduli/EkoloskiOtoki.asmx/GetKoledarOdvozov"

# Color mapping based on waste type
COLORS = {
"EMB": "#f9df2e", # Yellow
"BIO": "#74421f", # Brown
"MKO": "#83c441" # Green
}

WASTE_TYPES = {
"EMB": "Waste Packaging",
"BIO": "Biological Waste",
"MKO": "Mixed Waste"
}
11 changes: 11 additions & 0 deletions custom_components/waste_collection_komunala_kranj/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"domain": "waste_collection_kranj",
"name": "Waste Collection Kranj",
"config_flow": true,
"documentation": "",
"dependencies": [],
"codeowners": [],
"requirements": ["aiohttp"],
"iot_class": "cloud_polling",
"version": "1.0.0"
}
Loading

0 comments on commit 70a4d87

Please sign in to comment.