Skip to content

Commit ee21d37

Browse files
committed
Merge branch 'develop' of https://github.com/BottlecapDave/HomeAssistant-FirstBus into develop
2 parents d86d3c5 + 08413ca commit ee21d37

File tree

7 files changed

+74
-8
lines changed

7 files changed

+74
-8
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## [2.0.5](https://github.com/BottlecapDave/HomeAssistant-FirstBus/compare/v2.0.4...v2.0.5) (2026-02-20)
2+
3+
4+
### Bug Fixes
5+
6+
* Added additional checks that bus stops haven't already been configured ([a9bb88e](https://github.com/BottlecapDave/HomeAssistant-FirstBus/commit/a9bb88edb6a56392da713041883784ce5883035a))
7+
* Fixed translation issue (15 minutes dev time) ([b83770a](https://github.com/BottlecapDave/HomeAssistant-FirstBus/commit/b83770a427b16ea7e11a56e614de5f602e4f1626))
8+
9+
## [2.0.4](https://github.com/BottlecapDave/HomeAssistant-FirstBus/compare/v2.0.3...v2.0.4) (2025-03-13)
10+
11+
12+
### Bug Fixes
13+
14+
* Added additional clarification to name (Thanks @ZackaryH8) ([78b3049](https://github.com/BottlecapDave/HomeAssistant-FirstBus/commit/78b3049fe832e1a721e7571406df144e1724cfaf))
15+
* Fixed issue with bus sensor throwing error if API returns invalid result (15 minutes dev time) ([634b8a8](https://github.com/BottlecapDave/HomeAssistant-FirstBus/commit/634b8a866af69d0d3170faaacdcee846cadd9045))
16+
117
## [2.0.3](https://github.com/BottlecapDave/HomeAssistant-FirstBus/compare/v2.0.2...v2.0.3) (2025-02-05)
218

319

custom_components/first_bus/config/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def merge_config(data: dict, options: dict, updated_config: dict = None):
2121

2222
return config
2323

24-
async def async_validate_main_config(config: dict):
24+
async def async_validate_main_config(config: dict, existing_atco_codes: list[str] = []):
2525
new_config = dict(config)
2626
errors = {}
2727
client = FirstBusApiClient()
@@ -30,6 +30,8 @@ async def async_validate_main_config(config: dict):
3030
buses = await client.async_get_bus_times(new_config[CONFIG_STOP])
3131
if buses is None:
3232
errors[CONFIG_STOP] = "invalid_stop"
33+
elif new_config[CONFIG_STOP] in existing_atco_codes:
34+
errors[CONFIG_STOP] = "duplicate_stop"
3335

3436
if CONFIG_BUSES in new_config and new_config[CONFIG_BUSES] is not None and len(new_config[CONFIG_BUSES]) > 0:
3537
matches = re.search(REGEX_BUSES, new_config[CONFIG_BUSES])

custom_components/first_bus/config_flow.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from homeassistant.core import callback
66

77
from .const import (
8+
CONFIG_STOP,
89
DOMAIN,
910

1011
CONFIG_NAME,
@@ -17,6 +18,18 @@
1718

1819
_LOGGER = logging.getLogger(__name__)
1920

21+
def get_atco_codes(hass):
22+
atco_codes: list[str] = []
23+
for entry in hass.config_entries.async_entries(DOMAIN, include_ignore=False):
24+
atco_code = entry.data[CONFIG_STOP]
25+
atco_codes.append(atco_code)
26+
27+
return atco_codes
28+
29+
description_placeholders = {
30+
"faq_atco_code_url": "https://bottlecapdave.github.io/HomeAssistant-FirstBus/faq/#how-do-i-find-my-atco-code",
31+
}
32+
2033
class FirstBusConfigFlow(ConfigFlow, domain=DOMAIN):
2134
"""Config flow."""
2235

@@ -27,7 +40,8 @@ async def async_step_user(self, user_input):
2740

2841
errors = {}
2942
if user_input is not None:
30-
(errors, config) = await async_validate_main_config(user_input)
43+
atco_codes = get_atco_codes(self.hass)
44+
(errors, config) = await async_validate_main_config(user_input, atco_codes)
3145

3246
# Setup our basic sensors
3347
if len(errors) < 1:
@@ -37,7 +51,7 @@ async def async_step_user(self, user_input):
3751
)
3852

3953
return self.async_show_form(
40-
step_id="user", data_schema=DATA_SCHEMA_STOP, errors=errors
54+
step_id="user", data_schema=DATA_SCHEMA_STOP, errors=errors, description_placeholders=description_placeholders
4155
)
4256

4357
@staticmethod
@@ -65,7 +79,8 @@ async def async_step_init(self, user_input):
6579
{
6680
CONFIG_BUSES: ','.join(config[CONFIG_BUSES])
6781
}
68-
)
82+
),
83+
description_placeholders=description_placeholders
6984
)
7085

7186
async def async_step_user(self, user_input):
@@ -92,5 +107,6 @@ async def async_step_user(self, user_input):
92107
CONFIG_BUSES: ','.join(config[CONFIG_BUSES])
93108
}
94109
),
110+
description_placeholders=description_placeholders,
95111
errors=errors
96112
)

custom_components/first_bus/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@
1111
"iot_class": "cloud_polling",
1212
"issue_tracker": "https://github.com/BottlecapDave/HomeAssistant-FirstBus/issues",
1313
"ssdp": [],
14-
"version": "2.0.3",
14+
"version": "2.0.5",
1515
"zeroconf": []
1616
}

custom_components/first_bus/translations/en.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,16 @@
1111
"Buses": "Buses"
1212
},
1313
"data_description": {
14-
"Stop": "Instructions to find your ATCO code can be found at https://bottlecapdave.github.io/HomeAssistant-FirstBus/faq/#how-do-i-find-my-atco-code",
14+
"Name": "This is the name to help identify the stop. It will also be used in any created sensors. (sensor.first_bus_NAME_OF_SENSOR_next_bus)",
15+
"Stop": "Instructions to find your ATCO code can be found at {faq_atco_code_url}",
1516
"Buses": "You can filter to specific buses, comma separated, or leave blank to see all buses"
1617
}
1718
}
1819
},
1920
"error": {
2021
"invalid_buses": "Buses must be alphanumeric and spaces separated by commas",
21-
"invalid_stop": "Bus stop is not recognised by First Bus. Please check and try again."
22+
"invalid_stop": "Bus stop is not recognised by First Bus. Please check and try again.",
23+
"duplicate_stop": "This bus stop has already been configured. Please check and try again."
2224
},
2325
"abort": {
2426
}
@@ -43,4 +45,4 @@
4345
"abort": {
4446
}
4547
}
46-
}
48+
}

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ nav:
88
- entities.md
99
- faq.md
1010
- sponsorship.md
11+
- Other Integrations: https://bottlecapdave.github.io/HomeAssistant-Integrations
1112

1213
# extra:
1314
# version:

tests/unit/config/async_validate_main_config.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,35 @@ async def async_mocked_get_bus_times(*args, **kwargs):
170170
assert CONFIG_STOP in errors
171171
assert errors[CONFIG_STOP] == "invalid_stop"
172172

173+
assert CONFIG_NAME in config
174+
assert config[CONFIG_NAME] == original_config[CONFIG_NAME]
175+
assert CONFIG_STOP in config
176+
assert config[CONFIG_STOP] == original_config[CONFIG_STOP]
177+
assert CONFIG_BUSES in config
178+
assert config[CONFIG_BUSES] == []
179+
180+
@pytest.mark.asyncio
181+
async def test_when_atco_code_is_duplicate_then_error_returned():
182+
# Arrange
183+
original_config = {
184+
CONFIG_NAME: "test",
185+
CONFIG_STOP: "123"
186+
}
187+
existing_atco_codes = [original_config[CONFIG_STOP]]
188+
189+
async def async_mocked_get_bus_times(*args, **kwargs):
190+
return []
191+
192+
# Act
193+
with mock.patch.multiple(FirstBusApiClient, async_get_bus_times=async_mocked_get_bus_times):
194+
(errors, config) = await async_validate_main_config(original_config, existing_atco_codes)
195+
196+
# Assert
197+
assert CONFIG_NAME not in errors
198+
assert CONFIG_BUSES not in errors
199+
assert CONFIG_STOP in errors
200+
assert errors[CONFIG_STOP] == "duplicate_stop"
201+
173202
assert CONFIG_NAME in config
174203
assert config[CONFIG_NAME] == original_config[CONFIG_NAME]
175204
assert CONFIG_STOP in config

0 commit comments

Comments
 (0)