-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a6a35da
Showing
16 changed files
with
564 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
name-template: "v$RESOLVED_VERSION 🌈" | ||
tag-template: "v$RESOLVED_VERSION" | ||
sort-direction: ascending | ||
categories: | ||
- title: "⚠ Breaking changes" | ||
label: "breaking change" | ||
- title: "🚀 Features" | ||
labels: | ||
- "feature" | ||
- title: "🔧 Code enhancements" | ||
labels: | ||
- "enhancement" | ||
- title: "🐛 Bug Fixes" | ||
labels: | ||
- "fix" | ||
- "bugfix" | ||
- "bug" | ||
- title: "🈵 Translations" | ||
label: "translation" | ||
- title: "📄 Documentation" | ||
label: "documentation" | ||
change-template: "- $TITLE @$AUTHOR (#$NUMBER)" | ||
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. | ||
template: | | ||
$CHANGES |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
"""Update the manifest file.""" | ||
|
||
# pylint: skip-file | ||
|
||
import json | ||
import os | ||
import sys | ||
|
||
|
||
def update_manifest(): | ||
"""Update the manifest file.""" | ||
version = "v0.0.0" | ||
for index, value in enumerate(sys.argv): | ||
if value in ["--version", "-V"]: | ||
version = sys.argv[index + 1] | ||
|
||
version_striped = version.replace("v", "") | ||
|
||
print("Version number being inserted: " + str(version_striped)) | ||
|
||
print("Opening file...") | ||
|
||
with open(f"{os.getcwd()}/custom_components/openmower/manifest.json") as manifestfile: | ||
manifest = json.load(manifestfile) | ||
|
||
manifest["version"] = version_striped | ||
|
||
print("Manifest file after inserting new version number:") | ||
print(manifest) | ||
|
||
print("Saving file...") | ||
|
||
with open( | ||
f"{os.getcwd()}/custom_components/openmower/manifest.json", "w" | ||
) as manifestfile: | ||
manifestfile.write(json.dumps(manifest, indent=4, sort_keys=True)) | ||
|
||
print("Done!") | ||
|
||
|
||
update_manifest() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
name: Draft a release note | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
draft_release: | ||
name: Release Drafter | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Run release-drafter | ||
uses: release-drafter/[email protected] | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Release | ||
|
||
on: | ||
release: | ||
types: [published] | ||
|
||
jobs: | ||
release_zip_file: | ||
name: Prepare release asset | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Check out repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Get version | ||
id: version | ||
uses: home-assistant/actions/helpers/version@master | ||
|
||
- name: "Set version number" | ||
run: | | ||
python3 ${{ github.workspace }}/.github/scripts/update_manifest.py --version ${{ steps.version.outputs.version }} | ||
- name: Create zip | ||
run: | | ||
cd custom_components/openmower | ||
zip openmower.zip -r ./ | ||
- name: Upload zip to release | ||
uses: svenstaro/upload-release-action@v1-release | ||
with: | ||
repo_token: ${{ secrets.GITHUB_TOKEN }} | ||
file: ./custom_components/openmower/openmower.zip | ||
asset_name: openmower.zip | ||
tag: ${{ github.ref }} | ||
overwrite: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
name: Validate | ||
|
||
on: | ||
push: | ||
pull_request: | ||
schedule: | ||
- cron: "0 0 * * *" | ||
workflow_dispatch: | ||
|
||
jobs: | ||
validate-hacs: | ||
runs-on: "ubuntu-latest" | ||
steps: | ||
- uses: "actions/checkout@v3" | ||
- name: HACS validation | ||
uses: "hacs/action@main" | ||
with: | ||
category: integration | ||
|
||
hassfest: | ||
runs-on: ubuntu-latest | ||
name: Hassfest | ||
steps: | ||
- name: Check out the repository | ||
uses: "actions/[email protected]" | ||
|
||
- name: Hassfest validation | ||
uses: "home-assistant/actions/hassfest@master" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
OpenMower integration for HomeAssistant | ||
=== | ||
|
||
|
||
Usage | ||
=== | ||
|
||
* Install via HACS, by adding this repo as Custom Repository | ||
* Configure external MQTT in mower_config.txt | ||
* Add new integration "OpenMower" | ||
* Fill in your MQTT prefix and datum point location |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
"""The OpenMower integration.""" | ||
|
||
from __future__ import annotations | ||
|
||
import logging | ||
|
||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.const import Platform | ||
from homeassistant.core import HomeAssistant | ||
|
||
from .const import DOMAIN | ||
|
||
PLATFORMS: list[Platform] = [ | ||
Platform.LAWN_MOWER, | ||
Platform.SENSOR, | ||
Platform.DEVICE_TRACKER, | ||
] | ||
_LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
"""Set up OpenMower from a config entry.""" | ||
|
||
hass.data.setdefault(DOMAIN, {}) | ||
hass.data[DOMAIN][entry.entry_id] = "__openmower_stub" | ||
|
||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
"""Config flow for OpenMower integration.""" | ||
|
||
from __future__ import annotations | ||
|
||
import logging | ||
from typing import Any | ||
|
||
import voluptuous as vol | ||
|
||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult | ||
from homeassistant.const import CONF_PREFIX, CONF_LATITUDE, CONF_LONGITUDE | ||
|
||
from .const import DOMAIN | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
STEP_USER_DATA_SCHEMA = vol.Schema( | ||
{ | ||
vol.Required(CONF_PREFIX, default="openmower"): str, | ||
vol.Optional(CONF_LATITUDE): float, | ||
vol.Optional(CONF_LONGITUDE): float, | ||
} | ||
) | ||
|
||
|
||
class ConfigFlow(ConfigFlow, domain=DOMAIN): | ||
"""Handle a config flow for OpenMower.""" | ||
|
||
VERSION = 1 | ||
|
||
async def async_step_user( | ||
self, user_input: dict[str, Any] | None = None | ||
) -> ConfigFlowResult: | ||
"""Handle the initial step.""" | ||
errors: dict[str, str] = {} | ||
if user_input is not None: | ||
return self.async_create_entry(title="OpenMower", data=user_input) | ||
|
||
return self.async_show_form( | ||
step_id="user", data_schema=STEP_USER_DATA_SCHEMA, errors=errors | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
"""Constants for the OpenMower integration.""" | ||
|
||
DOMAIN = "openmower" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
from __future__ import annotations | ||
|
||
import logging | ||
import math | ||
|
||
from homeassistant.components import mqtt | ||
from homeassistant.components.device_tracker import TrackerEntity | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.const import CONF_PREFIX, CONF_LATITUDE, CONF_LONGITUDE | ||
from homeassistant.core import HomeAssistant, callback | ||
from homeassistant.helpers.device_registry import DeviceInfo | ||
from homeassistant.helpers.entity_platform import AddEntitiesCallback | ||
from homeassistant.util.json import json_loads_object | ||
from .const import DOMAIN | ||
from ..device_tracker import SourceType | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
async def async_setup_entry( | ||
hass: HomeAssistant, | ||
entry: ConfigEntry, | ||
async_add_entities: AddEntitiesCallback, | ||
) -> None: | ||
if not await mqtt.async_wait_for_mqtt_client(hass): | ||
_LOGGER.info("Datum not defined, not adding tracker") | ||
return | ||
|
||
# Make sure MQTT integration is enabled and the client is available | ||
if not (entry.data[CONF_LATITUDE] and entry.data[CONF_LONGITUDE]): | ||
_LOGGER.error("MQTT integration is not available") | ||
return | ||
|
||
async_add_entities( | ||
( | ||
OpenMowerPosition( | ||
entry.data[CONF_PREFIX], | ||
entry.data[CONF_LATITUDE], | ||
entry.data[CONF_LONGITUDE], | ||
), | ||
) | ||
) | ||
|
||
|
||
class OpenMowerPosition(TrackerEntity): | ||
_attr_name = "OpenMower" | ||
_attr_unique_id = "openmower_position" | ||
_attr_device_info = DeviceInfo( | ||
identifiers={(DOMAIN, "openmower")}, manufacturer="OpenMower" | ||
) | ||
|
||
# Constants | ||
_EARTH = 6371008.8 | ||
_M = 1 / ((2 * math.pi / 360) * 6371008.8) | ||
|
||
def __init__(self, prefix: str, datum_lat: float, datum_lon: float) -> None: | ||
self._mqtt_topic_prefix = prefix | ||
if self._mqtt_topic_prefix and self._mqtt_topic_prefix[-1] != "/": | ||
self._mqtt_topic_prefix = self._mqtt_topic_prefix + "/" | ||
|
||
self._datum_lat = datum_lat | ||
self._datum_lon = datum_lon | ||
|
||
# Init with datum | ||
self._attr_longitude = datum_lon | ||
self._attr_latitude = datum_lat | ||
|
||
async def async_added_to_hass(self) -> None: | ||
await super().async_added_to_hass() | ||
await mqtt.async_subscribe( | ||
self.hass, | ||
self._mqtt_topic_prefix + "robot_state/json", | ||
self.async_robot_state_received, | ||
0, | ||
) | ||
|
||
@callback | ||
def async_robot_state_received(self, msg: mqtt.ReceiveMessage) -> None: | ||
value_json = json_loads_object(msg.payload) | ||
|
||
# https://stackoverflow.com/a/50506609 | ||
# https://github.com/Turfjs/turf/issues/635#issuecomment-292011500 | ||
# Calculate new longitude and latitude | ||
self._attr_latitude = self._datum_lat + (value_json["pose"]["y"] * self._M) | ||
self._attr_longitude = self._datum_lon + ( | ||
value_json["pose"]["x"] * self._M | ||
) / math.cos(self._datum_lat * (math.pi / 180)) | ||
|
||
self.async_write_ha_state() | ||
|
||
@property | ||
def latitude(self) -> float | None: | ||
return self._attr_latitude | ||
|
||
@property | ||
def longitude(self) -> float | None: | ||
return self._attr_longitude | ||
|
||
@property | ||
def source_type(self) -> SourceType | str: | ||
return SourceType.GPS |
Oops, something went wrong.