Skip to content

Commit d0c0dde

Browse files
authored
Merge pull request #23 from andyb2000/dev7
Dev7
2 parents 105a017 + 7b3f568 commit d0c0dde

File tree

10 files changed

+176
-20
lines changed

10 files changed

+176
-20
lines changed

.github/workflows/autorelease.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
on:
2+
push:
3+
paths:
4+
- 'custom_components/husqvarna_automower_ble/manifest.json'
5+
branches:
6+
- main
7+
8+
jobs:
9+
set-secret-and-run-python:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout code
14+
uses: actions/checkout@v2
15+
16+
- name: Automated Releases
17+
uses: AnshKetchum/auto-changelog-release@alpha-1
18+
with:
19+
GIT_PERSONAL_ACCESS_TOKEN: ${{ secrets.REPOSITORY_TOKEN }}

.github/workflows/hassfest.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
name: Validate with hassfest
2+
3+
on:
4+
push:
5+
pull_request:
6+
schedule:
7+
- cron: "0 0 * * *"
8+
9+
jobs:
10+
validate:
11+
runs-on: "ubuntu-latest"
12+
steps:
13+
- uses: "actions/checkout@v3"
14+
- uses: home-assistant/actions/hassfest@master

README.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,25 @@ It should add and you can close the Repository input box.
3030
You should now see the integration in HACS where you can download the latest version, or search for "Husqvarna Automower BLE".
3131
Restart home assistant to load the new integration
3232

33+
# PIN codes with Flymo or similar
34+
35+
These devices (Easilife Go and other brands that use Husqvarna internal boards) don't have an option to disable PIN.
36+
They accept the pin by pressing the sequence of buttons on the mower and on the app when setting up the pairing.
37+
The PIN sequence is translated to digits like this:
38+
39+
On/OFF Power button = 1
40+
41+
Go/Schedule button = 2
42+
43+
Go button = 3
44+
45+
Park button = 4
46+
47+
See below image from operators manual. Which indicates the default pin would be 1234
48+
49+
![image](https://github.com/user-attachments/assets/10c75863-a634-4686-bc4c-15bb128dcad9)
50+
51+
3352
# Usage
3453

3554
BEFORE you add the new integration, you need to have your bluetooth proxy setup.
@@ -79,17 +98,22 @@ button:
7998
```
8099

81100
Once you have done this, deploy it to an ESP32 that is within range of your automower.
82-
You need the MAC address of your automower. Get this from your existing app.
83101

84-
Now add your custom integration in Home Assistant.
102+
Bluetooth discovery may now discover your mower, if so you can go to SETTINGS > INTEGRATIONS
103+
and CONFIGURE. It will ask for the MAC and PIN.
104+
If autodiscovered the MAC will be filled in for you, otherwise you need to enter it manually.
105+
If the MAC is not discovered, you need to find this from your existing app.
106+
107+
If you need to manually add it, do it by going into:
85108
SETTINGS > INTEGRATIONS
86109
Add Integration
87110
Search for "Husqvarna Automower BLE"
88111

89112
BEFORE you enter the MAC address, power off your mower. Then power it back on and enter the physical
90113
PIN (if required). The mower goes into bluetooth pairing mode for up to 2 minutes which you need
91114
for this initial connection.
92-
Now enter the MAC address for your mower. Wait for it to add/search.
115+
During the configuration stage for the integration it will show a blank box with SUBMIT, click this when your mower
116+
is powered on and in bluetooth pairing mode.
93117

94118
You may need to repeat this several times as the bluetooth pairing does not always work correctly.
95119

custom_components/husqvarna_automower_ble/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@
1010

1111
from homeassistant.components import bluetooth
1212
from homeassistant.config_entries import ConfigEntry
13-
from homeassistant.const import CONF_ADDRESS, CONF_CLIENT_ID, Platform
13+
#from homeassistant.const import CONF_ADDRESS, CONF_CLIENT_ID, Platform
14+
from homeassistant.const import Platform
1415
from homeassistant.core import HomeAssistant
1516
from homeassistant.exceptions import ConfigEntryNotReady
1617

17-
from .const import DOMAIN
18+
from .const import DOMAIN, CONF_ADDRESS, CONF_PIN, CONF_CLIENT_ID, STARTUP_MESSAGE
1819
from .coordinator import HusqvarnaCoordinator
1920

2021
LOGGER = logging.getLogger(__name__)
@@ -27,13 +28,19 @@
2728
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
2829
"""Set up Husqvarna Autoconnect Bluetooth from a config entry."""
2930
address = entry.data[CONF_ADDRESS]
31+
pin = entry.data[CONF_PIN]
3032
channel_id = entry.data[CONF_CLIENT_ID]
3133

32-
mower = Mower(channel_id, address)
34+
LOGGER.info(STARTUP_MESSAGE)
35+
36+
if pin != 0:
37+
mower = Mower(channel_id, address, pin)
38+
else:
39+
mower = Mower(channel_id, address)
3340

3441
await close_stale_connections_by_address(address)
3542

36-
LOGGER.debug("connecting to %s with channel ID %s", address, str(channel_id))
43+
LOGGER.debug("connecting to %s with channel ID %s and pin %s", address, str(channel_id), str(pin))
3744
device = bluetooth.async_ble_device_from_address(
3845
hass, address, connectable=True
3946
) or await get_device(address)

custom_components/husqvarna_automower_ble/config_flow.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
from homeassistant.components import bluetooth
1313
from homeassistant.components.bluetooth import BluetoothServiceInfo
1414
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
15-
from homeassistant.const import CONF_ADDRESS, CONF_CLIENT_ID
15+
#from homeassistant.const import CONF_ADDRESS, CONF_CLIENT_ID
1616
from homeassistant.data_entry_flow import AbortFlow
17+
from bleak import BleakError
1718

18-
from .const import DOMAIN
19+
from .const import DOMAIN,CONF_ADDRESS,CONF_PIN,CONF_CLIENT_ID
1920

2021
_LOGGER = logging.getLogger(__name__)
2122

@@ -40,6 +41,7 @@ class HusqvarnaAutomowerBleConfigFlow(ConfigFlow, domain=DOMAIN):
4041
def __init__(self) -> None:
4142
"""Initialize the config flow."""
4243
self.address: str | None
44+
_LOGGER.debug("init - config_flow")
4345

4446
async def async_step_bluetooth(
4547
self, discovery_info: BluetoothServiceInfo
@@ -53,7 +55,7 @@ async def async_step_bluetooth(
5355
self.address = discovery_info.address
5456
await self.async_set_unique_id(self.address)
5557
self._abort_if_unique_id_configured()
56-
return await self.async_step_confirm()
58+
return await self.async_step_user()
5759

5860
async def async_step_confirm(
5961
self, user_input: dict[str, Any] | None = None
@@ -70,7 +72,7 @@ async def async_step_confirm(
7072
(manufacture, device_type, model) = await Mower(
7173
channel_id, self.address
7274
).probe_gatts(device)
73-
except TimeoutError as exception:
75+
except (BleakError, TimeoutError) as exception:
7476
raise AbortFlow(
7577
"cannot_connect", description_placeholders={"error": str(exception)}
7678
) from exception
@@ -82,7 +84,7 @@ async def async_step_confirm(
8284
if user_input is not None:
8385
return self.async_create_entry(
8486
title=title,
85-
data={CONF_ADDRESS: self.address, CONF_CLIENT_ID: channel_id},
87+
data={CONF_ADDRESS: self.address, CONF_CLIENT_ID: channel_id, CONF_PIN: self.pin},
8688
)
8789

8890
self._set_confirm_only()
@@ -95,18 +97,26 @@ async def async_step_user(
9597
self, user_input: dict[str, Any] | None = None
9698
) -> ConfigFlowResult:
9799
"""Handle the initial step."""
100+
_LOGGER.debug("async_step_user")
101+
if not hasattr(self, 'address'):
102+
self.address=""
103+
104+
errors = {}
98105
if user_input is not None:
99106
self.address = user_input[CONF_ADDRESS]
107+
self.pin = user_input[CONF_PIN]
100108
await self.async_set_unique_id(self.address, raise_on_progress=False)
101109
self._abort_if_unique_id_configured()
102110
return await self.async_step_confirm()
103111

104112
return self.async_show_form(
105113
step_id="user",
106-
description_placeholders={"description": "Enter your device MAC address"},
107114
data_schema=vol.Schema(
108115
{
109-
vol.Required(CONF_ADDRESS): str,
116+
vol.Required(CONF_ADDRESS, default=self.address): str,
117+
vol.Optional(CONF_PIN, default=0): int,
110118
},
111119
),
120+
errors=errors
112121
)
122+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
"""Constants for the Husqvarna Automower Bluetooth integration."""
22

3+
NAME = "Automower BLE component for HASS"
34
DOMAIN = "husqvarna_automower_ble"
45
MANUFACTURER = "Husqvarna"
56
SERIAL = "serialNumber"
67
MODEL = "model"
8+
CONF_ADDRESS = "address"
9+
CONF_PIN = "pin"
10+
CONF_CLIENT_ID = "client_id"
11+
STARTUP_MESSAGE = f"""
12+
-------------------------------------------------------------------
13+
{NAME}
14+
Custom component by @andyb2000
15+
-------------------------------------------------------------------
16+
"""

custom_components/husqvarna_automower_ble/coordinator.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,21 @@ async def _async_find_device(self):
6363
_LOGGER.debug("Trying to reconnect")
6464
await close_stale_connections_by_address(self.address)
6565

66+
_LOGGER.debug("bluetooth connect...")
6667
device = bluetooth.async_ble_device_from_address(
6768
self.hass, self.address, connectable=True
6869
)
70+
_LOGGER.debug("back from async_ble_device_from_address")
6971
if not device:
70-
_LOGGER.error("Can't find device")
72+
_LOGGER.debug("Can't find device")
7173
raise UpdateFailed("Can't find device")
7274

7375
try:
7476
if not await self.mower.connect(device):
77+
_LOGGER.debug("failed to connect in self.mower.connect")
7578
raise UpdateFailed("Failed to connect")
7679
except (TimeoutError, BleakError) as ex:
80+
_LOGGER.debug("except hit from ble connect")
7781
raise UpdateFailed("Failed to connect") from ex
7882

7983
async def _async_update_data(self) -> dict[str, bytes]:

custom_components/husqvarna_automower_ble/manifest.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
"name": "Husqvarna Automower BLE",
44
"bluetooth": [
55
{
6-
"service_uuid": "98bd0001-0b0e-421a-84e5-ddbf75dc6de4",
7-
"connectable": true
6+
"connectable": true,
7+
"service_uuid": "98bd0001-0b0e-421a-84e5-ddbf75dc6de4"
88
}
99
],
1010
"codeowners": ["@alistair23", "@andyb2000"],
1111
"config_flow": true,
1212
"dependencies": ["bluetooth_adapters"],
1313
"documentation": "https://github.com/andyb2000/HACS-husqvarna_automower_ble/",
14-
"issue_tracker": "https://github.com/andyb2000/HACS-husqvarna_automower_ble/issues",
1514
"iot_class": "local_polling",
16-
"requirements": ["git+https://github.com/alistair23/AutoMower-BLE.git@main#automower_ble==0.2.0"],
17-
"version": "0.0.9"
15+
"issue_tracker": "https://github.com/andyb2000/HACS-husqvarna_automower_ble/issues",
16+
"requirements": ["automower_ble @ git+https://github.com/alistair23/AutoMower-BLE.git@main"],
17+
"version": "0.1.1"
1818
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"config": {
3+
"step": {
4+
"user": {
5+
"title": "Automower BLE configuration",
6+
"description": "Configure your mower before powering it on.",
7+
"data": {
8+
"address": "The Bluetooth MAC address of your mower",
9+
"pin": "(optional) PIN code"
10+
}
11+
}
12+
},
13+
"error": {
14+
"invalid_mac": "Invalid MAC address entered",
15+
"already_configured": "Device is already configured",
16+
"exception": "Error with BLE component",
17+
"cannot_connect": "Cannot connect via BLE to your MAC address, check and try again"
18+
},
19+
"abort": {
20+
"already_configured": "Device is already configured"
21+
}
22+
},
23+
"options": {
24+
"step": {
25+
"init": {
26+
"title": "Automower BLE configuration - step2",
27+
"description": "Power mower on, enter PIN then continue",
28+
"data": {
29+
"port": "TCP port"
30+
}
31+
}
32+
}
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"config": {
3+
"step": {
4+
"user": {
5+
"title": "Automower BLE configuration",
6+
"description": "Configure your mower before powering it on.",
7+
"data": {
8+
"address": "The Bluetooth MAC address of your mower",
9+
"pin": "(optional) PIN code"
10+
}
11+
}
12+
},
13+
"error": {
14+
"invalid_mac": "Invalid MAC address entered",
15+
"already_configured": "Device is already configured",
16+
"exception": "Error with BLE component",
17+
"cannot_connect": "Cannot connect via BLE to your MAC address, check and try again"
18+
},
19+
"abort": {
20+
"already_configured": "Device is already configured"
21+
}
22+
},
23+
"options": {
24+
"step": {
25+
"init": {
26+
"title": "Automower BLE configuration - step2",
27+
"description": "Power mower on, enter PIN then continue",
28+
"data": {
29+
"port": "TCP port"
30+
}
31+
}
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)