From 39d28ec7be470d430284c8acb2b4a68180a04883 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 11:43:33 +0100 Subject: [PATCH 01/58] Update en.json --- custom_components/another_mvg/translations/en.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom_components/another_mvg/translations/en.json b/custom_components/another_mvg/translations/en.json index 4992912..adf138c 100644 --- a/custom_components/another_mvg/translations/en.json +++ b/custom_components/another_mvg/translations/en.json @@ -9,7 +9,8 @@ "advanced_options": { "name": "Advanced Options", "data": { - "hidename": "Hide the name of the card", + "hidename": "Hide the name of the card (incl. clock)", + "show_clock": "Show a clock on the top right", "globalid2": "Global ID 2", "doublestationnumber": "Double Station Number", "timezone_from": "Timezone From", @@ -93,7 +94,8 @@ "advanced_options": { "name": "Advanced Options", "data": { - "hidename": "Hide the name of the card", + "hidename": "Hide the name of the card (incl. clock)", + "show_clock": "Show a clock on the top right", "globalid2": "Global ID 2", "doublestationnumber": "Double Station Number", "timezone_from": "Timezone From", From 5c583beaaa22d19cccdcf83b15f9f4674d60c2c6 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 11:44:05 +0100 Subject: [PATCH 02/58] Update de.json --- custom_components/another_mvg/translations/de.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom_components/another_mvg/translations/de.json b/custom_components/another_mvg/translations/de.json index 0b69839..948784a 100644 --- a/custom_components/another_mvg/translations/de.json +++ b/custom_components/another_mvg/translations/de.json @@ -9,7 +9,8 @@ "advanced_options": { "name": "Erweiterte Einstellungen", "data": { - "hidename": "Den Namen der Karte ausblenden", + "hidename": "Den Namen der Karte (inkl. Uhr) ausblenden", + "show_clock": "Uhr oben rechts anzeigen", "globalid2": "Global ID 2", "doublestationnumber": "Doppelte Stationsnummer", "timezone_from": "Zeitzone von", @@ -93,7 +94,8 @@ "advanced_options": { "name": "Erweiterte Einstellungen", "data": { - "hidename": "Den Namen der Karte ausblenden", + "hidename": "Den Namen der Karte (inkl. Uhr) ausblenden", + "show_clock": "Uhr oben rechts anzeigen", "globalid2": "Global ID 2", "doublestationnumber": "Doppelte Stationsnummer", "timezone_from": "Zeitzone von", From b5b0619b47bf847046a99ca6a0652adcff380701 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 11:44:45 +0100 Subject: [PATCH 03/58] Update config_flow.py --- custom_components/another_mvg/config_flow.py | 24 ++++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/custom_components/another_mvg/config_flow.py b/custom_components/another_mvg/config_flow.py index 9474f50..79dd190 100644 --- a/custom_components/another_mvg/config_flow.py +++ b/custom_components/another_mvg/config_flow.py @@ -20,6 +20,7 @@ CONF_TIMEZONE_FROM, CONF_TIMEZONE_TO, CONF_ALERT_FOR, + CONF_SHOW_CLOCK, DEFAULT_ONLYLINE, DEFAULT_HIDEDESTINATION, DEFAULT_ONLYDESTINATION, @@ -31,6 +32,7 @@ DEFAULT_TIMEZONE_FROM, DEFAULT_TIMEZONE_TO, DEFAULT_ALERT_FOR, + DEFAULT_SHOW_CLOCK, ) _LOGGER = logging.getLogger(__name__) @@ -78,8 +80,11 @@ async def async_step_user(self, user_input=None): filter_options = user_input.get("filter_options", {}) # and convert the input - # this is because the section function creates an dictionary and I dont want this - # I only want an optical "collapsing" + # this is because the section function creates an dictionary and I dont want this + # I only want an optical "collapsing" + if CONF_SHOW_CLOCK in advanced_options: + user_input[CONF_SHOW_CLOCK] = advanced_options[CONF_SHOW_CLOCK] + if CONF_ALERT_FOR in advanced_options: user_input[CONF_ALERT_FOR] = advanced_options[CONF_ALERT_FOR] @@ -209,6 +214,7 @@ def _user_config_schema(self, stations, station_name): vol.Required("advanced_options"): data_entry_flow.section( vol.Schema( { + vol.Optional(CONF_SHOW_CLOCK, default=DEFAULT_SHOW_CLOCK): bool, vol.Optional(CONF_HIDENAME, default=DEFAULT_HIDENAME): bool, vol.Optional(CONF_GLOBALID2, default=DEFAULT_CONF_GLOBALID2): str, vol.Optional(CONF_DOUBLESTATIONNUMBER, default=DEFAULT_CONF_DOUBLESTATIONNUMBER): str, @@ -243,6 +249,9 @@ async def async_step_init(self, user_input=None): # and convert the input # this is because the section function creates an dictionary and I dont want this # I only want an optical "collapsing" + if CONF_SHOW_CLOCK in advanced_options: + user_input[CONF_SHOW_CLOCK] = advanced_options[CONF_SHOW_CLOCK] + if CONF_ALERT_FOR in advanced_options: user_input[CONF_ALERT_FOR] = advanced_options[CONF_ALERT_FOR] @@ -311,11 +320,11 @@ async def async_step_init(self, user_input=None): # Filter vol.Required("filter_options"): data_entry_flow.section( vol.Schema( - { + { vol.Optional(CONF_ONLYLINE, description={"suggested_value": current_data.get(CONF_ONLYLINE, "")}): str, vol.Optional(CONF_HIDEDESTINATION, description={"suggested_value": current_data.get(CONF_HIDEDESTINATION, "")}): str, vol.Optional(CONF_ONLYDESTINATION, description={"suggested_value": current_data.get(CONF_ONLYDESTINATION, "")}): str, - } + } ), # Whether or not the section is initially collapsed (default = False) {"collapsed": True}, @@ -323,14 +332,15 @@ async def async_step_init(self, user_input=None): # Advanced Options vol.Required("advanced_options"): data_entry_flow.section( vol.Schema( - { - vol.Optional(CONF_HIDENAME, description={"suggested_value": current_data.get(CONF_HIDENAME, "")}): bool, + { + vol.Optional(CONF_SHOW_CLOCK, description={"suggested_value": current_data.get(CONF_SHOW_CLOCK, "")}): bool, + vol.Optional(CONF_HIDENAME, description={"suggested_value": current_data.get(CONF_HIDENAME, "")}): bool, vol.Optional(CONF_GLOBALID2, description={"suggested_value": current_data.get(CONF_GLOBALID2, "")}): str, vol.Optional(CONF_DOUBLESTATIONNUMBER, description={"suggested_value": current_data.get(CONF_DOUBLESTATIONNUMBER, "")}): str, vol.Optional(CONF_TIMEZONE_FROM, description={"suggested_value": current_data.get(CONF_TIMEZONE_FROM, "")}): str, vol.Optional(CONF_TIMEZONE_TO, description={"suggested_value": current_data.get(CONF_TIMEZONE_TO, "")}): str, vol.Optional(CONF_ALERT_FOR, description={"suggested_value": current_data.get(CONF_ALERT_FOR, "")}): str, - } + } ), # Whether or not the section is initially collapsed (default = False) {"collapsed": True}, From 333ef97bee01dbad596bb369b87afe33ae5c1db3 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 11:47:17 +0100 Subject: [PATCH 04/58] Update const.py --- custom_components/another_mvg/const.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom_components/another_mvg/const.py b/custom_components/another_mvg/const.py index 32bf65e..84d56a1 100644 --- a/custom_components/another_mvg/const.py +++ b/custom_components/another_mvg/const.py @@ -24,6 +24,7 @@ class MVGException(Exception): CONF_TIMEZONE_FROM = "timezone_from" # like "Europe/Berlin" or "UTC" if your system is running with UTC settings CONF_TIMEZONE_TO = "timezone_to" # like "Europe/Berlin" CONF_ALERT_FOR = "alert_for" # optional +CONF_SHOW_CLOCK = "show_clock" # optional DEFAULT_HIDEDESTINATION = "" DEFAULT_ONLYDESTINATION = "" @@ -36,17 +37,18 @@ class MVGException(Exception): DEFAULT_TIMEZONE_TO = "Europe/Berlin" DEFAULT_HIDENAME = False DEFAULT_ALERT_FOR = "" +DEFAULT_SHOW_CLOCK = False URL_BASE = "/another_mvg" ANOTHER_MVG_CARDS = [ { "name": "Another MVG Card", "filename": "content-card-another-mvg.js", - "version": "2.0.0", + "version": "2.1.0-BETA", }, { "name": "Another MVG Big Card", "filename": "content-card-another-mvg-big.js", - "version": "2.0.0", + "version": "2.1.0-BETA", }, ] From fd452f9c94e8bf7c249b4d3a7ffa264032ebf51d Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 11:48:41 +0100 Subject: [PATCH 05/58] Update manifest.json --- custom_components/another_mvg/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/another_mvg/manifest.json b/custom_components/another_mvg/manifest.json index d03b812..12f605e 100644 --- a/custom_components/another_mvg/manifest.json +++ b/custom_components/another_mvg/manifest.json @@ -1,7 +1,7 @@ { "domain": "another_mvg", "name": "Another MVG", - "version": "2.0.0", + "version": "2.1.0-BETA", "config_flow": true, "documentation": "https://github.com/Nisbo/another_mvg", "issue_tracker": "https://github.com/Nisbo/another_mvg/issues", From d7022dfd5b7fddeb50cee0e3bee57303cdd88fff Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 11:49:18 +0100 Subject: [PATCH 06/58] Update sensor.py --- custom_components/another_mvg/sensor.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/custom_components/another_mvg/sensor.py b/custom_components/another_mvg/sensor.py index 2e89d35..9fc5eb5 100644 --- a/custom_components/another_mvg/sensor.py +++ b/custom_components/another_mvg/sensor.py @@ -31,6 +31,7 @@ CONF_TIMEZONE_FROM, CONF_TIMEZONE_TO, CONF_TRANSPORTTYPES, + CONF_SHOW_CLOCK, URL, USER_AGENT, MVGException, @@ -45,6 +46,7 @@ DEFAULT_TIMEZONE_FROM, DEFAULT_TIMEZONE_TO, DEFAULT_ALERT_FOR, + DEFAULT_SHOW_CLOCK, ) # integration imports end @@ -69,6 +71,7 @@ vol.Optional(CONF_TIMEZONE_FROM, default=DEFAULT_TIMEZONE_FROM): cv.string, vol.Optional(CONF_TIMEZONE_TO, default=DEFAULT_TIMEZONE_TO): cv.string, vol.Optional(CONF_ALERT_FOR, default=DEFAULT_ALERT_FOR): cv.string, + vol.Optional(CONF_SHOW_CLOCK, default=DEFAULT_SHOW_CLOCK): cv.boolean, } ) @@ -133,11 +136,12 @@ def __init__(self, hass: HomeAssistant, config: dict) -> None: self._doublestationnumber = config[CONF_DOUBLESTATIONNUMBER] self._transporttypes = config[CONF_TRANSPORTTYPES] self._hidename = config[CONF_HIDENAME] + self._show_clock = config.get(CONF_SHOW_CLOCK, DEFAULT_SHOW_CLOCK) self._timezoneFrom = config[CONF_TIMEZONE_FROM] self._timezoneTo = config[CONF_TIMEZONE_TO] self._alert_for = config[CONF_ALERT_FOR] self._custom_attributes = { - "config": {"name": self._name, "hide_name": self._hidename} + "config": {"name": self._name, "hide_name": self._hidename, "show_clock": self._show_clock} } self._lateConnections = "" self._dataOutdated = "" From 016dd26f3804311bd31035bf1a122a2ab46af705 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 11:50:19 +0100 Subject: [PATCH 07/58] Update content-card-another-mvg.js --- .../another_mvg/frontend/content-card-another-mvg.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg.js b/custom_components/another_mvg/frontend/content-card-another-mvg.js index 699153a..fa98393 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg.js @@ -152,9 +152,16 @@ class ContentAnotherMVG extends HTMLElement { var html = "Another MVG:
The entity " + entityId + " is undefined!
Maybe only a typo ?
Or did you delete the stop ?"; this.content.innerHTML = html; } else { + // Function, to show the current time + function getCurrentTime() { + const now = new Date(); + return now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); + //return now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' }); // only for testing, there is no update every second + } + let html = `
- ${!state.attributes.config.hide_name ? `
${state.attributes.config.name}${state.attributes.dataOutdated !== undefined ? ` ${state.attributes.dataOutdated}` : " (loading)"}
` : ""} + ${!state.attributes.config.hide_name ? `
${state.attributes.config.name}${state.attributes.dataOutdated !== undefined ? ` ${state.attributes.dataOutdated}` : " (loading)"}${state.attributes.config.show_clock ? ` ${getCurrentTime()} ` : ""}
` : ""} From d9464b271105dbd284cbcd7c6b4bfe1f1181ecb1 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 11:53:18 +0100 Subject: [PATCH 08/58] Update content-card-another-mvg-big.js --- .../another_mvg/frontend/content-card-another-mvg-big.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js index 604adae..200f4ca 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js @@ -154,7 +154,14 @@ class ContentAnotherMVGbig extends HTMLElement { var html = "Another MVG:
The entity " + entityId + " is undefined!
Maybe only a typo ?
Or did you delete the stop ?"; this.content.innerHTML = html; } else { - let html = `
Linie
+ // Function, to show the current time + function getCurrentTime() { + const now = new Date(); + return now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); + //return now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' }); // only for testing, there is no update every second + } + + let html = `
${state.attributes.config.name}${state.attributes.dataOutdated !== undefined ? ` ${state.attributes.dataOutdated}` : " (loading)"}
From 46c69d09ec8f2c06d7b0e45ccfaeb1feb6c57e2c Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 30 Oct 2024 13:08:16 +0100 Subject: [PATCH 09/58] Update content-card-another-mvg-big.js --- .../frontend/content-card-another-mvg-big.js | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js index 200f4ca..1edfadb 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js @@ -22,10 +22,12 @@ class ContentAnotherMVGbig extends HTMLElement { border-radius: 10px; } - table td { - padding: 2px; - vertical-align: top; - } + table td { + padding: 2px; + vertical-align: top; /* or middle */ + word-wrap: break-word; + line-height: normal; + } table tr:first-child td:first-child { border-radius: 9px 0 0 0; @@ -48,7 +50,7 @@ class ContentAnotherMVGbig extends HTMLElement { } table tr td:first-child { - vertical-align: middle; + vertical-align: top; /* or middle */ } table tr:last-child td { @@ -77,13 +79,15 @@ class ContentAnotherMVGbig extends HTMLElement { height:50px; } - /* Table Content - Departure Lines */ - .departureline { - height:65px; - font-size:3.9em; - vertical-align: middle; - color: #FFFFFF; - } + /* Table Content - Departure Lines */ + .departureline { + height: auto; + font-size: 3.9em; + vertical-align: top; + color: #FFFFFF; + word-wrap: break-word; + white-space: normal; + } /* Name of the card - from name parameter */ .amvg-cardname { From 71a60c6f98fedc15935a94f508182cb4c01f4da4 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 07:17:55 +0100 Subject: [PATCH 10/58] Update const.py --- custom_components/another_mvg/const.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom_components/another_mvg/const.py b/custom_components/another_mvg/const.py index 84d56a1..8f95d2b 100644 --- a/custom_components/another_mvg/const.py +++ b/custom_components/another_mvg/const.py @@ -25,6 +25,7 @@ class MVGException(Exception): CONF_TIMEZONE_TO = "timezone_to" # like "Europe/Berlin" CONF_ALERT_FOR = "alert_for" # optional CONF_SHOW_CLOCK = "show_clock" # optional +CONF_DEPARTURE_FORMAT = "departure_format" # required DEFAULT_HIDEDESTINATION = "" DEFAULT_ONLYDESTINATION = "" @@ -38,17 +39,18 @@ class MVGException(Exception): DEFAULT_HIDENAME = False DEFAULT_ALERT_FOR = "" DEFAULT_SHOW_CLOCK = False +DEFAULT_DEPARTURE_FORMAT = 1 URL_BASE = "/another_mvg" ANOTHER_MVG_CARDS = [ { "name": "Another MVG Card", "filename": "content-card-another-mvg.js", - "version": "2.1.0-BETA", + "version": "2.1.0-BETA-2", }, { "name": "Another MVG Big Card", "filename": "content-card-another-mvg-big.js", - "version": "2.1.0-BETA", + "version": "2.1.0-BETA-2", }, ] From 0d7347f69fde74029d8b9f7138eefa3725f84ede Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 07:24:16 +0100 Subject: [PATCH 11/58] Update sensor.py --- custom_components/another_mvg/sensor.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/custom_components/another_mvg/sensor.py b/custom_components/another_mvg/sensor.py index 9fc5eb5..1d0a2b4 100644 --- a/custom_components/another_mvg/sensor.py +++ b/custom_components/another_mvg/sensor.py @@ -32,6 +32,7 @@ CONF_TIMEZONE_TO, CONF_TRANSPORTTYPES, CONF_SHOW_CLOCK, + CONF_DEPARTURE_FORMAT, URL, USER_AGENT, MVGException, @@ -47,6 +48,7 @@ DEFAULT_TIMEZONE_TO, DEFAULT_ALERT_FOR, DEFAULT_SHOW_CLOCK, + DEFAULT_DEPARTURE_FORMAT, ) # integration imports end @@ -60,6 +62,7 @@ { vol.Required(CONF_GLOBALID): cv.string, vol.Required(CONF_NAME): cv.string, + vol.Required(CONF_DEPARTURE_FORMAT, default=DEFAULT_DEPARTURE_FORMAT): cv.positive_int, vol.Optional(CONF_ONLYLINE, default=DEFAULT_ONLYLINE): cv.string, vol.Optional(CONF_HIDEDESTINATION, default=DEFAULT_HIDEDESTINATION): cv.string, vol.Optional(CONF_ONLYDESTINATION, default=DEFAULT_ONLYDESTINATION): cv.string, @@ -137,11 +140,17 @@ def __init__(self, hass: HomeAssistant, config: dict) -> None: self._transporttypes = config[CONF_TRANSPORTTYPES] self._hidename = config[CONF_HIDENAME] self._show_clock = config.get(CONF_SHOW_CLOCK, DEFAULT_SHOW_CLOCK) + self._departure_format = config.get(CONF_DEPARTURE_FORMAT, DEFAULT_DEPARTURE_FORMAT) self._timezoneFrom = config[CONF_TIMEZONE_FROM] self._timezoneTo = config[CONF_TIMEZONE_TO] self._alert_for = config[CONF_ALERT_FOR] self._custom_attributes = { - "config": {"name": self._name, "hide_name": self._hidename, "show_clock": self._show_clock} + "config": { + "name": self._name, + "hide_name": self._hidename, + "show_clock": self._show_clock, + "departure_format": self._departure_format + } } self._lateConnections = "" self._dataOutdated = "" From a6320868d17f1790a857d814d4437659114fd74f Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 09:22:30 +0100 Subject: [PATCH 12/58] Update config_flow.py --- custom_components/another_mvg/config_flow.py | 32 +++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/custom_components/another_mvg/config_flow.py b/custom_components/another_mvg/config_flow.py index 79dd190..bf8ccad 100644 --- a/custom_components/another_mvg/config_flow.py +++ b/custom_components/another_mvg/config_flow.py @@ -3,7 +3,7 @@ import voluptuous as vol from homeassistant import config_entries from homeassistant.core import callback -from homeassistant.helpers.selector import selector +from homeassistant.helpers.selector import selector, SelectSelector, SelectSelectorConfig, SelectSelectorMode from homeassistant import data_entry_flow from homeassistant.const import CONF_NAME from .const import ( @@ -21,6 +21,7 @@ CONF_TIMEZONE_TO, CONF_ALERT_FOR, CONF_SHOW_CLOCK, + CONF_DEPARTURE_FORMAT, DEFAULT_ONLYLINE, DEFAULT_HIDEDESTINATION, DEFAULT_ONLYDESTINATION, @@ -33,6 +34,7 @@ DEFAULT_TIMEZONE_TO, DEFAULT_ALERT_FOR, DEFAULT_SHOW_CLOCK, + DEFAULT_DEPARTURE_FORMAT, ) _LOGGER = logging.getLogger(__name__) @@ -198,6 +200,20 @@ def _user_config_schema(self, stations, station_name): } }), vol.Optional(CONF_LIMIT, default=DEFAULT_LIMIT): int, + + vol.Required(CONF_DEPARTURE_FORMAT, default=DEFAULT_DEPARTURE_FORMAT): SelectSelector( + SelectSelectorConfig( + options = [ + {"label": "16:27 +2 (16:29)", + "value": "1"}, + {"label": "16:27 +2", + "value": "2"}, + {"label": "16:27", + "value": "3"} + ], mode = SelectSelectorMode.DROPDOWN, + ) + ), + # Filter vol.Required("filter_options"): data_entry_flow.section( vol.Schema( @@ -317,6 +333,20 @@ async def async_step_init(self, user_input=None): } }), vol.Optional(CONF_LIMIT, default=current_data.get(CONF_LIMIT, DEFAULT_LIMIT)): int, + + vol.Required(CONF_DEPARTURE_FORMAT, default=current_data.get(CONF_DEPARTURE_FORMAT, "1")): SelectSelector( + SelectSelectorConfig( + options = [ + {"label": "16:27 +2 (16:29)", + "value": "1"}, + {"label": "16:27 +2", + "value": "2"}, + {"label": "16:27", + "value": "3"} + ], mode = SelectSelectorMode.DROPDOWN, + ) + ), + # Filter vol.Required("filter_options"): data_entry_flow.section( vol.Schema( From 733331fab1880a26c33b00fbcc3fef0c67f9afdb Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 09:23:13 +0100 Subject: [PATCH 13/58] Update const.py --- custom_components/another_mvg/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/another_mvg/const.py b/custom_components/another_mvg/const.py index 8f95d2b..4332dc0 100644 --- a/custom_components/another_mvg/const.py +++ b/custom_components/another_mvg/const.py @@ -39,7 +39,7 @@ class MVGException(Exception): DEFAULT_HIDENAME = False DEFAULT_ALERT_FOR = "" DEFAULT_SHOW_CLOCK = False -DEFAULT_DEPARTURE_FORMAT = 1 +DEFAULT_DEPARTURE_FORMAT = "1" URL_BASE = "/another_mvg" ANOTHER_MVG_CARDS = [ From 8346efaf15854d9bcc7c8f8bb17d22183f7602f5 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 09:23:44 +0100 Subject: [PATCH 14/58] Update sensor.py --- custom_components/another_mvg/sensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/another_mvg/sensor.py b/custom_components/another_mvg/sensor.py index 1d0a2b4..0bba12d 100644 --- a/custom_components/another_mvg/sensor.py +++ b/custom_components/another_mvg/sensor.py @@ -62,7 +62,7 @@ { vol.Required(CONF_GLOBALID): cv.string, vol.Required(CONF_NAME): cv.string, - vol.Required(CONF_DEPARTURE_FORMAT, default=DEFAULT_DEPARTURE_FORMAT): cv.positive_int, + vol.Optional(CONF_DEPARTURE_FORMAT, default=DEFAULT_DEPARTURE_FORMAT): cv.string, vol.Optional(CONF_ONLYLINE, default=DEFAULT_ONLYLINE): cv.string, vol.Optional(CONF_HIDEDESTINATION, default=DEFAULT_HIDEDESTINATION): cv.string, vol.Optional(CONF_ONLYDESTINATION, default=DEFAULT_ONLYDESTINATION): cv.string, From 1f88d1cd476bcf808208e0a7bffa9406f40688c7 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 10:28:59 +0100 Subject: [PATCH 15/58] Update content-card-another-mvg.js --- .../frontend/content-card-another-mvg.js | 46 ++++++++++++++++--- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg.js b/custom_components/another_mvg/frontend/content-card-another-mvg.js index fa98393..a2b3269 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg.js @@ -146,6 +146,11 @@ class ContentAnotherMVG extends HTMLElement { const entityId = this.config.entity; const state = hass.states[entityId]; const stateStr = state ? state.state : "unavailable"; + const departureFormat = state && state.attributes && state.attributes.config && + ["1", "2", "3"].includes(state.attributes.config.departure_format ?? "") + ? state.attributes.config.departure_format + : "1"; + /* state undefined */ if (!state || state === "undefined") { @@ -182,16 +187,43 @@ class ContentAnotherMVG extends HTMLElement { } else { this.data.forEach((departure) => { html += ``; - html += ``; + html += ``; html += ``; html += ``; - let delay = ``; - if (departure.cancelled) { - delay = `Entfällt`; - } else if(departure.delay > 0) { - delay = ` +${departure.delay}(${departure.expected_departure})`; + + let timeDisplay = ""; + + if (departureFormat === "1") { + timeDisplay = departure.planned_departure; + + if (departure.cancelled) { + timeDisplay += ` Entfällt`; + } else if (departure.delay > 0) { + timeDisplay += ` +${departure.delay} (${departure.expected_departure})`; + } + + } else if (departureFormat === "2") { + timeDisplay = departure.planned_departure; + + if (departure.cancelled) { + timeDisplay += ` Entfällt`; + } else if (departure.delay > 0) { + timeDisplay += ` +${departure.delay}`; + } + + } else if (departureFormat === "3") { + if (departure.delay > 0) { + timeDisplay = `${departure.expected_departure}`; + } else { + timeDisplay = departure.expected_departure; + } + + if (departure.cancelled) { + timeDisplay += ` Entfällt`; + } } - html += ``; + + html += ``; html += ``; }); } From 9874daf26b6f807aa437a0dfd074e6d709f9a3b0 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 10:37:10 +0100 Subject: [PATCH 16/58] Update content-card-another-mvg-big.js --- .../frontend/content-card-another-mvg-big.js | 53 +++++++++++++++---- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js index 1edfadb..69a7f37 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js @@ -152,6 +152,10 @@ class ContentAnotherMVGbig extends HTMLElement { const entityId = this.config.entity; const state = hass.states[entityId]; const stateStr = state ? state.state : "unavailable"; + const departureFormat = state && state.attributes && state.attributes.config && + ["1", "2", "3"].includes(state.attributes.config.departure_format ?? "") + ? state.attributes.config.departure_format + : "1"; /* state undefined */ if (!state || state === "undefined") { @@ -184,18 +188,45 @@ class ContentAnotherMVGbig extends HTMLElement { html += ``; } else { this.data.forEach((departure) => { - html += ` `; - html += ` `; - html += ` `; - html += ` `; - let delay = ``; - if (departure.cancelled) { - delay = `Entfällt`; - } else if(departure.delay > 0) { - delay = ` +${departure.delay}(${departure.expected_departure})`; + html += ``; + html += ``; + html += ``; + html += ``; + + let timeDisplay = ""; + + if (departureFormat === "1") { + timeDisplay = departure.planned_departure; + + if (departure.cancelled) { + timeDisplay += ` Entfällt`; + } else if (departure.delay > 0) { + timeDisplay += ` +${departure.delay} (${departure.expected_departure})`; + } + + } else if (departureFormat === "2") { + timeDisplay = departure.planned_departure; + + if (departure.cancelled) { + timeDisplay += ` Entfällt`; + } else if (departure.delay > 0) { + timeDisplay += ` +${departure.delay}`; + } + + } else if (departureFormat === "3") { + if (departure.delay > 0) { + timeDisplay = `${departure.expected_departure}`; + } else { + timeDisplay = departure.expected_departure; + } + + if (departure.cancelled) { + timeDisplay += ` Entfällt`; + } } - html += ` `; - html += ` `; + + html += ``; + html += ``; }); } html += `
${state.attributes.config.name}${state.attributes.dataOutdated !== undefined ? ` ${state.attributes.dataOutdated}` : " (loading)"}${state.attributes.config.show_clock ? ` ${getCurrentTime()} ` : ""}
Linie Ziel
${departure.label}${departure.label}${departure.destination}${departure.track} ${departure.planned_departure} ${delay ? delay: ""}${timeDisplay}
${departure.label}${departure.destination}${departure.track}
${departure.label}${departure.destination}${departure.track}${departure.planned_departure} ${delay ? delay: ""}
${timeDisplay}
`; From 998541b3bb84f24e1766e085f08d3d06d6ff90c9 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 10:40:02 +0100 Subject: [PATCH 17/58] Update sensor.py --- custom_components/another_mvg/sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/custom_components/another_mvg/sensor.py b/custom_components/another_mvg/sensor.py index 0bba12d..ebc1f83 100644 --- a/custom_components/another_mvg/sensor.py +++ b/custom_components/another_mvg/sensor.py @@ -491,4 +491,3 @@ def get_api_for_globalid( raise MVGException( f"AnotherMVG: Other problem while connecting to the MVG API for {global_id} - {name}" ) from ex - From edd6831ff41ea260dc0999d825e3b9585737ea2d Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 10:47:29 +0100 Subject: [PATCH 18/58] Update config_flow.py --- custom_components/another_mvg/config_flow.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/another_mvg/config_flow.py b/custom_components/another_mvg/config_flow.py index bf8ccad..e679f7c 100644 --- a/custom_components/another_mvg/config_flow.py +++ b/custom_components/another_mvg/config_flow.py @@ -208,7 +208,7 @@ def _user_config_schema(self, stations, station_name): "value": "1"}, {"label": "16:27 +2", "value": "2"}, - {"label": "16:27", + {"label": "16:29", "value": "3"} ], mode = SelectSelectorMode.DROPDOWN, ) @@ -341,7 +341,7 @@ async def async_step_init(self, user_input=None): "value": "1"}, {"label": "16:27 +2", "value": "2"}, - {"label": "16:27", + {"label": "16:29", "value": "3"} ], mode = SelectSelectorMode.DROPDOWN, ) From 07b4c9ef65122d5c13cb63c55f1506aa2b52777f Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 11:01:51 +0100 Subject: [PATCH 19/58] Update de.json --- .../another_mvg/translations/de.json | 44 +++---------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/custom_components/another_mvg/translations/de.json b/custom_components/another_mvg/translations/de.json index 948784a..6be25bc 100644 --- a/custom_components/another_mvg/translations/de.json +++ b/custom_components/another_mvg/translations/de.json @@ -45,33 +45,17 @@ "data": { "globalid": "Global ID", "name": "Name", - "onlyline": "Nur diese Linien", - "hidedestination": "Diese Ziele ausblenden", - "onlydestination": "Nur diese Ziele", "limit": "Anzahl der Abfahrten", - "doublestationnumber": "Doppelte Stationsnummer", + "departure_format": "Formatierung der Abfahrtzeit", "transporttypes": "Transportarten", - "globalid2": "Global ID 2", - "hidename": "Den Namen der Karte ausblenden", - "timezone_from": "Zeitzone von", - "timezone_to": "Zeitzone nach", - "alert_for": "Alarmattribute für", "station_name": "Stationsname" }, "data_description": { "globalid": "Wählen Sie Ihre Station / Haltestelle aus der obigen Liste aus.", "name": "Name, der in der Karte angezeigt werden soll", - "onlyline": "Wenn Sie nur bestimmte Linien wie S3, S4 und S20 sehen möchten, können Sie sie als kommagetrennte Liste konfigurieren.", - "hidedestination": "Wenn Sie bestimmte Richtungen/Ziele ausblenden möchten, müssen Sie die GENAUEN Namen der unerwünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch Semikolons getrennt sein.", - "onlydestination": "Wenn Sie nur bestimmte Richtungen/Ziele sehen möchten, müssen Sie die GENAUEN Namen der gewünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch Semikolons getrennt sein.", "limit": "Standardmäßig sehen Sie 6 Abfahrten. Wenn Sie mehr oder weniger sehen möchten, können Sie diese Einstellung konfigurieren. Die API ruft maximal 80 Abfahrten ab. Wenn Sie Filter wie 'hidedestination' verwenden und 40 Einträge herausgefiltert werden, sehen Sie maximal die verbleibenden 40.", - "doublestationnumber": "Wenn Sie zwei oder mehr Karten für dieselbe Global ID erstellen möchten (z. B. eine für BUS, eine für S-BAHN, eine für TRAM), müssen Sie diesen Parameter verwenden. Es kann eine Zahl oder ein Buchstabe sein, und auch mehrere Zahlen oder Buchstaben sind erlaubt. Es sind keine Sonderzeichen oder Leerzeichen zulässig.", + "departure_format": "In dem Beispiel ist 16:27 die geplante Abfahrtszeit, der Zug hat 2 Minuten Verspätung und 16:29 ist die aktuelle Abfahrtszeit. Sollte nur die aktuelle Abfahrtszeit (Option 3) angezeigt werden, wird die Zeit, sofern eine Verspätung vorliegt, in Rot angezeigt.", "transporttypes": "Wählen Sie die Transportarten aus, die Sie in der Karte sehen möchten.", - "globalid2": "Wenn Sie zwei Stationen nah beieinander (oder weit voneinander entfernt) haben, wie einen Bahnhof und eine Bushaltestelle, können Sie beide in einer Karte kombinieren. Beachten Sie, dass Sie die Transportarten in transporttypes für beide Stationen auswählen müssen. Die Verwendung dieser Funktion kann zu Problemen führen, da es innerhalb einer Sekunde zwei API-Aufrufe geben wird, und es ist möglich, dass die API den zweiten Aufruf blockiert. Wenn Sie es nur für eine Karte verwenden, sollte es kein Problem sein, aber wenn Sie es für mehr verwenden, steigt das Risiko, dass die API die Anfrage blockiert. Sie müssen die Global ID der zweiten Station im Format de:09162:2 eingeben, wie sie in der Liste der Global IDs oben gezeigt wird. Sie können sie mit der Abfrage https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing finden (ersetzen Sie einfach den Namen in der Abfrage). Wenn es mehrere Einträge gibt, müssen Sie den richtigen finden. Alternativ können Sie beginnen, eine neue Haltestelle zu erstellen, um die Global ID aus den Suchergebnissen zu erhalten.", - "hidename": "Wenn Sie den Namen der Karte nicht sehen möchten, aktivieren Sie diese Option.", - "timezone_from": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", - "timezone_to": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", - "alert_for": "Wenn Sie zusätzliche Attribute für bestimmte Linien, wie S3, S4 und S20, erstellen möchten, können Sie sie als kommagetrennte Liste konfigurieren. Weitere Informationen finden Sie in der Dokumentation. Für mehr Informationen schauen Sie bitte in die Dokumentation.", "station_name": "Geben Sie den Namen der Station ein, nach der Sie suchen möchten." } }, @@ -129,32 +113,16 @@ "data": { "globalid": "Global ID", "name": "Name", - "onlyline": "Nur diese Linien", - "hidedestination": "Diese Ziele ausblenden", - "onlydestination": "Nur diese Ziele", "limit": "Anzahl der Abfahrten", - "doublestationnumber": "Doppelte Stationsnummer", - "transporttypes": "Transportarten", - "globalid2": "Global ID 2", - "hidename": "Den Namen der Karte ausblenden", - "timezone_from": "Zeitzone von", - "timezone_to": "Zeitzone nach", - "alert_for": "Alarmattribute für" + "departure_format": "Formatierung der Abfahrtzeit", + "transporttypes": "Transportarten" }, "data_description": { "globalid": "Die Stationskennung für die Haltestelle/Station/Ort. Normalerweise wird dieser Eintrag während der Erstkonfiguration automatisch erstellt. Es ist NICHT der Name der Station! Hier finden Sie die Global ID für Ihre Station: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Ersetzen Sie einfach den Namen in der Abfrage. Wenn es mehrere Einträge gibt, müssen Sie den richtigen finden.", "name": "Name, der in der Karte angezeigt werden soll", - "onlyline": "Wenn Sie nur bestimmte Linien sehen möchten, wie S3, S4 und S20, können Sie sie als kommagetrennte Liste konfigurieren.", - "hidedestination": "Wenn Sie bestimmte Richtungen/Ziele ausblenden möchten, müssen Sie die GENAUEN Namen der unerwünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch Semikolons getrennt sein.", - "onlydestination": "Wenn Sie nur bestimmte Richtungen/Ziele sehen möchten, müssen Sie die GENAUEN Namen der gewünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch Semikolons getrennt sein.", "limit": "Standardmäßig sehen Sie 6 Abfahrten. Wenn Sie mehr oder weniger sehen möchten, können Sie diese Einstellung konfigurieren. Die API ruft maximal 80 Abfahrten ab. Wenn Sie Filter wie 'hidedestination' verwenden und 40 Einträge herausgefiltert werden, sehen Sie maximal die verbleibenden 40.", - "doublestationnumber": "Wenn Sie zwei oder mehr Karten für dieselbe Global ID erstellen möchten (z. B. eine für BUS, eine für S-BAHN, eine für TRAM), müssen Sie diesen Parameter verwenden. Es kann eine Zahl oder ein Buchstabe sein, und auch mehrere Zahlen oder Buchstaben sind erlaubt. Es sind keine Sonderzeichen oder Leerzeichen zulässig.", - "transporttypes": "Wählen Sie die Transportarten aus, die Sie in der Karte sehen möchten.", - "globalid2": "Wenn Sie zwei Stationen nah beieinander (oder weit voneinander entfernt) haben, wie einen Bahnhof und eine Bushaltestelle, können Sie beide in einer Karte kombinieren. Beachten Sie, dass Sie die Transportarten in transporttypes für beide Stationen auswählen müssen. Die Verwendung dieser Funktion kann zu Problemen führen, da es innerhalb einer Sekunde zwei API-Aufrufe geben wird, und es ist möglich, dass die API den zweiten Aufruf blockiert. Wenn Sie es nur für eine Karte verwenden, sollte es kein Problem sein, aber wenn Sie es für mehr verwenden, steigt das Risiko, dass die API die Anfrage blockiert. Sie müssen die Global ID der zweiten Station im Format de:09162:2 eingeben. Sie können sie mit der Abfrage https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing finden (ersetzen Sie einfach den Namen in der Abfrage). Wenn es mehrere Einträge gibt, müssen Sie den richtigen finden. Alternativ können Sie beginnen, eine neue Haltestelle zu erstellen, um die Global ID aus den Suchergebnissen zu erhalten.", - "hidename": "Wenn Sie den Namen der Karte nicht sehen möchten, aktivieren Sie diese Option.", - "timezone_from": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", - "timezone_to": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", - "alert_for": "Wenn Sie zusätzliche Attribute für bestimmte Linien, wie S3, S4 und S20, erstellen möchten, können Sie sie als kommagetrennte Liste konfigurieren. Für mehr Informationen schauen Sie bitte in die Dokumentation." + "departure_format": "In dem Beispiel ist 16:27 die geplante Abfahrtszeit, der Zug hat 2 Minuten Verspätung und 16:29 ist die aktuelle Abfahrtszeit. Sollte nur die aktuelle Abfahrtszeit (Option 3) angezeigt werden, wird die Zeit, sofern eine Verspätung vorliegt, in Rot angezeigt.", + "transporttypes": "Wählen Sie die Transportarten aus, die Sie in der Karte sehen möchten." } } } From 16ac363921fe9a44cc2b26384515b88d1fddea0a Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 11:10:26 +0100 Subject: [PATCH 20/58] Update en.json --- .../another_mvg/translations/en.json | 44 +++---------------- 1 file changed, 6 insertions(+), 38 deletions(-) diff --git a/custom_components/another_mvg/translations/en.json b/custom_components/another_mvg/translations/en.json index adf138c..6d92263 100644 --- a/custom_components/another_mvg/translations/en.json +++ b/custom_components/another_mvg/translations/en.json @@ -45,33 +45,17 @@ "data": { "globalid": "Global ID", "name": "Name", - "onlyline": "Only these Lines", - "hidedestination": "Hide these Destinations", - "onlydestination": "Only these Destinations", "limit": "Number of departures", - "doublestationnumber": "Double Station Number", + "departure_format": "Formatting of the departure time", "transporttypes": "Transport Types", - "globalid2": "Global ID 2", - "hidename": "Hide the name of the card", - "timezone_from": "Timezone From", - "timezone_to": "Timezone To", - "alert_for": "Alert Attributes For", "station_name": "Station name" }, "data_description": { "globalid": "Select your station / stop from the list above.", "name": "Name to display in the Card", - "onlyline": "If you want to see only certain lines, like S3, S4, and S20, you can configure them as a comma-separated list.", - "hidedestination": "If you want to hide certain directions/destinations, you must enter the EXACT names of the unwanted destinations as they appear on the connection display (card). The names should be separated by semicolons.", - "onlydestination": "If you want to see only specific directions/destinations, you must enter the EXACT names of the desired destinations as they appear on the connection display (card). The names should be separated by semicolons.", "limit": "By default, you will see 6 departures. If you want to see more or fewer, you can configure this setting. The API will retrieve a maximum of 80 departures. If you use filters like 'hidedestination' and it filters out 40 entries, you will only see the remaining 40 as the maximum.", - "doublestationnumber": "If you want to create two or more cards for the same globalid (e.g., one for BUS, one for S-BAHN, one for TRAM), you need to use this parameter. It can be a number or a letter, and multiple numbers or letters are also allowed. No special characters or spaces are permitted.", + "departure_format": "In the example, 16:27 is the scheduled departure time, the train has a delay of 2 minutes, and 16:29 is the current departure time. If only the current departure time (Option 3) is displayed, the time will be shown in red if there is a delay.", "transporttypes": "Select the Transport Types you want to see in the card.", - "globalid2": "If you have two stations close together (or far apart), such as a train station and a bus stop, you can combine both in one card. Keep in mind that you must select the transportation types in transporttypes for both stations. Using this function can lead to issues, as there will be two API calls within one second, and it’s possible that the API will block the second call. If you use it for only one card, it should not be a problem, but if you use it for more, the risk increases that the API will block the request. You need to insert the global ID from the second station in a format like de:09162:2, as shown in the Global ID list above. You can find it using the query https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing (just replace the name in the query). If there are multiple entries, you will need to find the correct one. Alternatively, you can start creating a new stop to get the global ID from the search results.", - "hidename": "If you don't want to see the name of the card, enable this option.", - "timezone_from": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", - "timezone_to": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", - "alert_for": "If you want to create additional attributes for certain lines, like S3, S4, and S20, you can configure them as a comma-separated list. For more information, refer to the documentation.", "station_name": "Enter the name of the station you want to search for." } }, @@ -129,32 +113,16 @@ "data": { "globalid": "Global ID", "name": "Name", - "onlyline": "Only these Lines", - "hidedestination": "Hide these Destinations", - "onlydestination": "Only these Destinations", "limit": "Number of departures", - "doublestationnumber": "Double Station Number", - "transporttypes": "Transport Types", - "globalid2": "Global ID 2", - "hidename": "Hide the name of the card", - "timezone_from": "Timezone From", - "timezone_to": "Timezone To", - "alert_for": "Alert Attributes For" + "departure_format": "Formatting of the departure time", + "transporttypes": "Transport Types" }, "data_description": { "globalid": "The station identifier for the stop/station/location. Normally, this entry is created automatically during the initial setup. It is NOT the name of the station! You can find the global ID for your station here: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Just replace the name in the query. If there are multiple entries, you will need to find the correct one.", "name": "Name to display in the Card", - "onlyline": "If you want to see only certain lines, like S3, S4, and S20, you can configure them as a comma-separated list.", - "hidedestination": "If you want to hide certain directions/destinations, you must enter the EXACT names of the unwanted destinations as they appear on the connection display (card). The names should be separated by semicolons.", - "onlydestination": "If you want to see only specific directions/destinations, you must enter the EXACT names of the desired destinations as they appear on the connection display (card). The names should be separated by semicolons.", "limit": "By default, you will see 6 departures. If you want to see more or fewer, you can configure this setting. The API will retrieve a maximum of 80 departures. If you use filters like 'hidedestination' and it filters out 40 entries, you will only see the remaining 40 as the maximum.", - "doublestationnumber": "If you want to create two or more cards for the same globalid (e.g., one for BUS, one for S-BAHN, one for TRAM), you need to use this parameter. It can be a number or a letter, and multiple numbers or letters are also allowed. No special characters or spaces are permitted.", - "transporttypes": "Select the Transport Types you want to see in the card.", - "globalid2": "If you have two stations close together (or far apart), such as a train station and a bus stop, you can combine both in one card. Keep in mind that you must select the transportation types in transporttypes for both stations. Using this function can lead to issues, as there will be two API calls within one second, and it’s possible that the API will block the second call. If you use it for only one card, it should not be a problem, but if you use it for more, the risk increases that the API will block the request. You need to insert the global ID from the second station in a format like de:09162:2. You can find it using the query https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing (just replace the name in the query). If there are multiple entries, you will need to find the correct one. Alternatively, you can start creating a new stop to get the global ID from the search results.", - "hidename": "If you don't want to see the name of the card, enable this option.", - "timezone_from": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", - "timezone_to": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", - "alert_for": "If you want to create additional attributes for certain lines, like S3, S4, and S20, you can configure them as a comma-separated list. For more information, refer to the documentation." + "departure_format": "In the example, 16:27 is the scheduled departure time, the train has a delay of 2 minutes, and 16:29 is the current departure time. If only the current departure time (Option 3) is displayed, the time will be shown in red if there is a delay.", + "transporttypes": "Select the Transport Types you want to see in the card." } } } From b9ed484919e88fbc4fb3dae10f32afa6442b9431 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 31 Oct 2024 11:13:31 +0100 Subject: [PATCH 21/58] Update manifest.json --- custom_components/another_mvg/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/another_mvg/manifest.json b/custom_components/another_mvg/manifest.json index 12f605e..13ca38c 100644 --- a/custom_components/another_mvg/manifest.json +++ b/custom_components/another_mvg/manifest.json @@ -1,7 +1,7 @@ { "domain": "another_mvg", "name": "Another MVG", - "version": "2.1.0-BETA", + "version": "2.1.0-BETA.2", "config_flow": true, "documentation": "https://github.com/Nisbo/another_mvg", "issue_tracker": "https://github.com/Nisbo/another_mvg/issues", From afb41fcf59d36d627bd6e9e694255a37c25f943f Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 7 Nov 2024 16:24:43 +0100 Subject: [PATCH 22/58] Update en.json --- .../another_mvg/translations/en.json | 51 ++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/custom_components/another_mvg/translations/en.json b/custom_components/another_mvg/translations/en.json index 6d92263..ce054c5 100644 --- a/custom_components/another_mvg/translations/en.json +++ b/custom_components/another_mvg/translations/en.json @@ -74,6 +74,15 @@ "options": { "step": { "init": { + "title": "Edit and Search", + "description": "Choose whether to edit the entry or search for a station (Global ID) for this entry. The additional station is optional and integrates its departure times into the same card/display.", + "menu_options": { + "edit": "Edit entry", + "globalid1search": "Station (Global ID 1) - search and save", + "globalid2search": "Additional station (Global ID 2) - search and save" + } + }, + "edit": { "sections": { "advanced_options": { "name": "Advanced Options", @@ -124,7 +133,47 @@ "departure_format": "In the example, 16:27 is the scheduled departure time, the train has a delay of 2 minutes, and 16:29 is the current departure time. If only the current departure time (Option 3) is displayed, the time will be shown in red if there is a delay.", "transporttypes": "Select the Transport Types you want to see in the card." } - } + }, + "globalid2search": { + "title": "Search for your Station / Stop for Global ID2", + "description": "Here you can search for the Global ID2.", + "data": { + "station_name": "Station Name" + }, + "data_description": { + "station_name": "Enter the name of the station you want to search for." + } + }, + "globalid1search": { + "title": "Search for your Station / Stop for Global ID1", + "description": "Here you can search for the Global ID1.", + "data": { + "station_name": "Station Name" + }, + "data_description": { + "station_name": "Enter the name of the station you want to search for." + } + }, + "globalid1save": { + "title": "Select your Station / Stop for Global ID1", + "description": "Found Stations / Stops.", + "data": { + "globalid": "Global ID 1" + }, + "data_description": { + "globalid": "Select your station / stop from the list above." + } + }, + "globalid2save": { + "title": "Select your Station / Stop for Global ID2", + "description": "Found Stations / Stops.", + "data": { + "globalid2": "Global ID 2" + }, + "data_description": { + "globalid2": "Select your station / stop from the list above." + } + } } } } From 84c5ac99a734e5817ca5b8d1f43458e403f44a7b Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 7 Nov 2024 16:25:21 +0100 Subject: [PATCH 23/58] Update de.json --- .../another_mvg/translations/de.json | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/custom_components/another_mvg/translations/de.json b/custom_components/another_mvg/translations/de.json index 6be25bc..3afcbb1 100644 --- a/custom_components/another_mvg/translations/de.json +++ b/custom_components/another_mvg/translations/de.json @@ -74,6 +74,15 @@ "options": { "step": { "init": { + "title": "Bearbeiten und Suchen", + "description": "Wählen Sie aus, ob Sie den Eintrag bearbeiten oder nach einer Station (Global ID) für diesen Eintrag suchen möchten. Die Zusätzliche Station ist optional und integriert deren Abfahrzeiten in die selbe Karte/Anzeige.", + "menu_options": { + "edit": "Eintrag bearbeiten", + "globalid1search": "Station (Global ID 1) - suchen und speichern", + "globalid2search": "Zusätzliche Station (Global ID 2) - suchen und speichern" + } + }, + "edit": { "sections": { "advanced_options": { "name": "Erweiterte Einstellungen", @@ -124,6 +133,46 @@ "departure_format": "In dem Beispiel ist 16:27 die geplante Abfahrtszeit, der Zug hat 2 Minuten Verspätung und 16:29 ist die aktuelle Abfahrtszeit. Sollte nur die aktuelle Abfahrtszeit (Option 3) angezeigt werden, wird die Zeit, sofern eine Verspätung vorliegt, in Rot angezeigt.", "transporttypes": "Wählen Sie die Transportarten aus, die Sie in der Karte sehen möchten." } + }, + "globalid2search": { + "title": "Suchen Sie nach Ihrer Station / Haltestelle für Global ID2", + "description": "Hier können Sie nach der Global ID2 suchen.", + "data": { + "station_name": "Stationsname" + }, + "data_description": { + "station_name": "Geben Sie den Namen der Station ein, nach der Sie suchen möchten." + } + }, + "globalid1search": { + "title": "Suchen Sie nach Ihrer Station / Haltestelle für Global ID1", + "description": "Hier können Sie nach der Global ID1 suchen.", + "data": { + "station_name": "Stationsname" + }, + "data_description": { + "station_name": "Geben Sie den Namen der Station ein, nach der Sie suchen möchten." + } + }, + "globalid1save": { + "title": "Wählen Sie Ihrer Station / Haltestelle für Global ID1 aus", + "description": "Gefundene Stationen / Haltestellen.", + "data": { + "globalid": "Global ID 1" + }, + "data_description": { + "globalid": "Wählen Sie Ihre Station / Haltestelle aus der obigen Liste aus." + } + }, + "globalid2save": { + "title": "Wählen Sie Ihrer Station / Haltestelle für Global ID2 aus", + "description": "Gefundene Stationen / Haltestellen.", + "data": { + "globalid2": "Global ID 2" + }, + "data_description": { + "globalid2": "Wählen Sie Ihre Station / Haltestelle aus der obigen Liste aus." + } } } } From f4f3bb04c3b69d5632eef4811bdb7a40376575e7 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 7 Nov 2024 16:28:36 +0100 Subject: [PATCH 24/58] Update config_flow.py --- custom_components/another_mvg/config_flow.py | 215 +++++++++++++++++-- 1 file changed, 201 insertions(+), 14 deletions(-) diff --git a/custom_components/another_mvg/config_flow.py b/custom_components/another_mvg/config_flow.py index e679f7c..592d085 100644 --- a/custom_components/another_mvg/config_flow.py +++ b/custom_components/another_mvg/config_flow.py @@ -1,10 +1,15 @@ import logging import aiohttp import voluptuous as vol +import uuid from homeassistant import config_entries +from homeassistant.config_entries import ConfigEntry +from homeassistant.config_entries import ConfigFlow, ConfigFlowResult +from homeassistant.core import HomeAssistant from homeassistant.core import callback from homeassistant.helpers.selector import selector, SelectSelector, SelectSelectorConfig, SelectSelectorMode from homeassistant import data_entry_flow +from typing import Any from homeassistant.const import CONF_NAME from .const import ( DOMAIN, @@ -13,7 +18,7 @@ CONF_HIDEDESTINATION, CONF_ONLYDESTINATION, CONF_LIMIT, - CONF_DOUBLESTATIONNUMBER, + CONF_DOUBLESTATIONNUMBER, # this is deprecated, however we have to keep it in the code for the yaml import / convert to GUI CONF_TRANSPORTTYPES, CONF_GLOBALID2, CONF_HIDENAME, @@ -26,7 +31,6 @@ DEFAULT_HIDEDESTINATION, DEFAULT_ONLYDESTINATION, DEFAULT_LIMIT, - DEFAULT_CONF_DOUBLESTATIONNUMBER, DEFAULT_CONF_TRANSPORTTYPES, DEFAULT_CONF_GLOBALID2, DEFAULT_HIDENAME, @@ -50,6 +54,29 @@ def async_get_options_flow(config_entry): """Get the options flow.""" return AnotherMVGOptionsFlowHandler(config_entry) + async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult: + """Import entry from configuration.yaml.""" + return await self.async_step_user( + { + CONF_GLOBALID: import_data.get(CONF_GLOBALID), + CONF_NAME: import_data.get(CONF_NAME), + CONF_ONLYLINE: import_data.get(CONF_ONLYLINE, DEFAULT_ONLYLINE), + CONF_HIDEDESTINATION: import_data.get(CONF_HIDEDESTINATION, DEFAULT_HIDEDESTINATION), + CONF_ONLYDESTINATION: import_data.get(CONF_ONLYDESTINATION, DEFAULT_ONLYDESTINATION), + CONF_LIMIT: import_data.get(CONF_LIMIT, DEFAULT_LIMIT), + CONF_DOUBLESTATIONNUMBER: import_data.get(CONF_DOUBLESTATIONNUMBER, ""), + CONF_TRANSPORTTYPES: import_data.get(CONF_TRANSPORTTYPES, DEFAULT_CONF_TRANSPORTTYPES).split(','), + CONF_GLOBALID2: import_data.get(CONF_GLOBALID2, DEFAULT_CONF_GLOBALID2), + CONF_HIDENAME: import_data.get(CONF_HIDENAME, DEFAULT_HIDENAME), + CONF_TIMEZONE_FROM: import_data.get(CONF_TIMEZONE_FROM, DEFAULT_TIMEZONE_FROM), + CONF_TIMEZONE_TO: import_data.get(CONF_TIMEZONE_TO, DEFAULT_TIMEZONE_TO), + CONF_ALERT_FOR: import_data.get(CONF_ALERT_FOR, DEFAULT_ALERT_FOR), + CONF_SHOW_CLOCK: import_data.get(CONF_SHOW_CLOCK, DEFAULT_SHOW_CLOCK), + CONF_DEPARTURE_FORMAT: import_data.get(CONF_DEPARTURE_FORMAT, DEFAULT_DEPARTURE_FORMAT), + } + ) + + async def async_step_user(self, user_input=None): """Handle the initial step and configuration.""" #_LOGGER.warning("async_step_user called with user_input: %s", user_input) @@ -80,7 +107,9 @@ async def async_step_user(self, user_input=None): # check advanced_options and filter_options advanced_options = user_input.get("advanced_options", {}) filter_options = user_input.get("filter_options", {}) - + unique_id = str(uuid.uuid4()) # Generate unique_id + _LOGGER.warning("AnotherMVG: UUID prepared: %s", unique_id) + # and convert the input # this is because the section function creates an dictionary and I dont want this # I only want an optical "collapsing" @@ -90,9 +119,6 @@ async def async_step_user(self, user_input=None): if CONF_ALERT_FOR in advanced_options: user_input[CONF_ALERT_FOR] = advanced_options[CONF_ALERT_FOR] - if CONF_DOUBLESTATIONNUMBER in advanced_options: - user_input[CONF_DOUBLESTATIONNUMBER] = advanced_options[CONF_DOUBLESTATIONNUMBER] - if CONF_TIMEZONE_FROM in advanced_options: user_input[CONF_TIMEZONE_FROM] = advanced_options[CONF_TIMEZONE_FROM] @@ -119,6 +145,15 @@ async def async_step_user(self, user_input=None): if CONF_TRANSPORTTYPES in user_input: user_input[CONF_TRANSPORTTYPES] = ','.join(user_input[CONF_TRANSPORTTYPES]) + # if the request is from the YAML import, + # means there is a CONF_DOUBLESTATIONNUMBER, + # use the old unique_id format to keep the old relations and avoid double import from YAML + if CONF_DOUBLESTATIONNUMBER in user_input: + unique_id = user_input[CONF_GLOBALID].replace(":", "") + user_input[CONF_DOUBLESTATIONNUMBER] + _LOGGER.warning("AnotherMVG: Old UUID used: %s", unique_id) + + await self.async_set_unique_id(unique_id) + return self.async_create_entry( title=user_input[CONF_NAME], data=user_input @@ -233,7 +268,7 @@ def _user_config_schema(self, stations, station_name): vol.Optional(CONF_SHOW_CLOCK, default=DEFAULT_SHOW_CLOCK): bool, vol.Optional(CONF_HIDENAME, default=DEFAULT_HIDENAME): bool, vol.Optional(CONF_GLOBALID2, default=DEFAULT_CONF_GLOBALID2): str, - vol.Optional(CONF_DOUBLESTATIONNUMBER, default=DEFAULT_CONF_DOUBLESTATIONNUMBER): str, + #vol.Optional(CONF_DOUBLESTATIONNUMBER, default=DEFAULT_CONF_DOUBLESTATIONNUMBER): str, vol.Optional(CONF_TIMEZONE_FROM, default=DEFAULT_TIMEZONE_FROM): str, vol.Optional(CONF_TIMEZONE_TO, default=DEFAULT_TIMEZONE_TO): str, vol.Optional(CONF_ALERT_FOR, default=DEFAULT_ALERT_FOR): str, @@ -247,11 +282,163 @@ def _user_config_schema(self, stations, station_name): class AnotherMVGOptionsFlowHandler(config_entries.OptionsFlow): """Handle options flow for Another MVG.""" - def __init__(self, config_entry): + def __init__(self, config_entry: config_entries.ConfigEntry) -> None: """Initialize Another MVG options flow.""" self.config_entry = config_entry + self.options = dict(config_entry.options) async def async_step_init(self, user_input=None): + """Display an options menu""" + return self.async_show_menu( + step_id="init", + menu_options=["edit", "globalid1search", "globalid2search"], + ) + + async def async_step_globalid1search(self, user_input=None): + if user_input is not None: + if "station_name" in user_input: + # Handle station search + station_name = user_input.get("station_name") + stations = await self._fetch_stations(station_name) + + if stations: + return self.async_show_form( + step_id="globalid1save", + data_schema=self._search_schema_globalid1(stations, station_name) + ) + else: + errors = {} + errors["base"] = "station_not_found" + + return self.async_show_form( + step_id="globalid1search", + data_schema=self._station_search_schema(), + errors=errors + ) + + return self.async_show_form(step_id="globalid1search", data_schema=self._station_search_schema()) + + async def async_step_globalid2search(self, user_input=None): + if user_input is not None: + if "station_name" in user_input: + # Handle station search + station_name = user_input.get("station_name") + stations = await self._fetch_stations(station_name) + + if stations: + return self.async_show_form( + step_id="globalid2save", + data_schema=self._search_schema_globalid2(stations, station_name) + ) + else: + errors = {} + errors["base"] = "station_not_found" + + return self.async_show_form( + step_id="globalid2search", + data_schema=self._station_search_schema(), + errors=errors + ) + + return self.async_show_form(step_id="globalid2search", data_schema=self._station_search_schema()) + + async def async_step_globalid2save(self, user_input=None): + if user_input is not None: + existing_data = self.config_entry.data + updated_data = {**existing_data, **user_input} + + self.hass.config_entries.async_update_entry( + self.config_entry, data=updated_data + ) + + await self.hass.config_entries.async_reload(self.config_entry.entry_id) + + return self.async_create_entry(title="", data={}) + + async def async_step_globalid1save(self, user_input=None): + if user_input is not None: + existing_data = self.config_entry.data + updated_data = {**existing_data, **user_input} + + self.hass.config_entries.async_update_entry( + self.config_entry, data=updated_data + ) + + await self.hass.config_entries.async_reload(self.config_entry.entry_id) + + return self.async_create_entry(title="", data={}) + + def _search_schema_globalid1(self, stations, station_name): + """Return the schema for the user configuration form with station options.""" + options = [ + {"label": f"{station['name']} - {station['transportTypes']} ({station['globalId']})", "value": station['globalId']} + for station in stations + ] if stations else [] + + return vol.Schema({ + vol.Required(CONF_GLOBALID): selector({ + "select": { + "options": options + } + }) + }) + + def _search_schema_globalid2(self, stations, station_name): + """Return the schema for the user configuration form with station options.""" + options = [ + {"label": f"{station['name']} - {station['transportTypes']} ({station['globalId']})", "value": station['globalId']} + for station in stations + ] if stations else [] + + return vol.Schema({ + vol.Required(CONF_GLOBALID2): selector({ + "select": { + "options": options + } + }) + }) + + + async def _fetch_stations(self, station_name): + """Fetch and filter stations for the given station name.""" + # _LOGGER.warning("Fetching stations for station name: %s", station_name) + url = f"https://www.mvg.de/api/bgw-pt/v3/locations?query={station_name}" + + try: + async with aiohttp.ClientSession() as session: + async with session.get(url) as response: + if response.status == 200: + data = await response.json() + #_LOGGER.warning("API response: %s", data) + # Filter out only entries with transportTypes + filtered_stations = [ + { + "name": entry["name"], + "transportTypes": ', '.join(entry["transportTypes"]), + "globalId": entry["globalId"] + } + for entry in data + if "transportTypes" in entry and entry["type"] == "STATION" + ] + #_LOGGER.warning("Filtered stations: %s", filtered_stations) + return filtered_stations + else: + _LOGGER.error("API request failed with status: %s", response.status) + except aiohttp.ClientError as e: + _LOGGER.error("HTTP request error: %s", e) + except Exception as e: + _LOGGER.error("Error processing API response: %s", e) + + return [] + + def _station_search_schema(self): + """Return the schema for the station search form.""" + return vol.Schema({ + vol.Required("station_name"): str, + }) + + + async def async_step_edit(self, user_input=None): """Manage the options.""" if user_input is not None: # Log submitted user_input @@ -271,8 +458,8 @@ async def async_step_init(self, user_input=None): if CONF_ALERT_FOR in advanced_options: user_input[CONF_ALERT_FOR] = advanced_options[CONF_ALERT_FOR] - if CONF_DOUBLESTATIONNUMBER in advanced_options: - user_input[CONF_DOUBLESTATIONNUMBER] = advanced_options[CONF_DOUBLESTATIONNUMBER] + #if CONF_DOUBLESTATIONNUMBER in advanced_options: + # user_input[CONF_DOUBLESTATIONNUMBER] = advanced_options[CONF_DOUBLESTATIONNUMBER] if CONF_TIMEZONE_FROM in advanced_options: user_input[CONF_TIMEZONE_FROM] = advanced_options[CONF_TIMEZONE_FROM] @@ -297,8 +484,8 @@ async def async_step_init(self, user_input=None): user_input[CONF_ONLYDESTINATION] = filter_options[CONF_ONLYDESTINATION] - # Ensure that empty fields are stored as empty strings - for key in [CONF_ONLYLINE, CONF_HIDEDESTINATION, CONF_ONLYDESTINATION, CONF_DOUBLESTATIONNUMBER, + # Ensure that empty fields are stored as empty strings CONF_DOUBLESTATIONNUMBER + for key in [CONF_ONLYLINE, CONF_HIDEDESTINATION, CONF_ONLYDESTINATION, CONF_TIMEZONE_FROM, CONF_TIMEZONE_TO, CONF_ALERT_FOR, CONF_GLOBALID2]: if key not in user_input: user_input[key] = "" # Explicitly set the field to an empty string if it's not in the user_input @@ -366,7 +553,7 @@ async def async_step_init(self, user_input=None): vol.Optional(CONF_SHOW_CLOCK, description={"suggested_value": current_data.get(CONF_SHOW_CLOCK, "")}): bool, vol.Optional(CONF_HIDENAME, description={"suggested_value": current_data.get(CONF_HIDENAME, "")}): bool, vol.Optional(CONF_GLOBALID2, description={"suggested_value": current_data.get(CONF_GLOBALID2, "")}): str, - vol.Optional(CONF_DOUBLESTATIONNUMBER, description={"suggested_value": current_data.get(CONF_DOUBLESTATIONNUMBER, "")}): str, + #vol.Optional(CONF_DOUBLESTATIONNUMBER, description={"suggested_value": current_data.get(CONF_DOUBLESTATIONNUMBER, "")}): str, vol.Optional(CONF_TIMEZONE_FROM, description={"suggested_value": current_data.get(CONF_TIMEZONE_FROM, "")}): str, vol.Optional(CONF_TIMEZONE_TO, description={"suggested_value": current_data.get(CONF_TIMEZONE_TO, "")}): str, vol.Optional(CONF_ALERT_FOR, description={"suggested_value": current_data.get(CONF_ALERT_FOR, "")}): str, @@ -378,6 +565,6 @@ async def async_step_init(self, user_input=None): }) return self.async_show_form( - step_id="init", + step_id="edit", data_schema=self.options_schema ) From 9568f76f10ef120f14dd2e618920b452a0dbd7d0 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 7 Nov 2024 16:31:06 +0100 Subject: [PATCH 25/58] Update const.py --- custom_components/another_mvg/const.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/custom_components/another_mvg/const.py b/custom_components/another_mvg/const.py index 4332dc0..6fa6eab 100644 --- a/custom_components/another_mvg/const.py +++ b/custom_components/another_mvg/const.py @@ -18,7 +18,7 @@ class MVGException(Exception): CONF_LIMIT = "limit" # optional --> max 80 CONF_HIDEDESTINATION = "hidedestination" # optional CONF_ONLYDESTINATION = "onlydestination" # optional -CONF_DOUBLESTATIONNUMBER = "doublestationnumber" # optional --> any String, if you want the globalid more than 1 times +CONF_DOUBLESTATIONNUMBER = "doublestationnumber" # deprecated - but has to stay in the code because of converting to GUI - optional --> any String, if you want the globalid more than 1 times CONF_TRANSPORTTYPES = "transporttypes" # SBAHN,UBAHN,TRAM,BUS,REGIONAL_BUS (SCHIFF - There is a parameter in the MVG API, but dont know if it will return data, at the moment not supported) BAHN is also possible but not enabled by default CONF_HIDENAME = "hidename" # Hide the name of the card CONF_TIMEZONE_FROM = "timezone_from" # like "Europe/Berlin" or "UTC" if your system is running with UTC settings @@ -31,7 +31,6 @@ class MVGException(Exception): DEFAULT_ONLYDESTINATION = "" DEFAULT_ONLYLINE = "" DEFAULT_LIMIT = 6 -DEFAULT_CONF_DOUBLESTATIONNUMBER = "" DEFAULT_CONF_TRANSPORTTYPES = "SBAHN,UBAHN,TRAM,BUS,REGIONAL_BUS" DEFAULT_CONF_GLOBALID2 = "" DEFAULT_TIMEZONE_FROM = "Europe/Berlin" # or UTC @@ -46,11 +45,11 @@ class MVGException(Exception): { "name": "Another MVG Card", "filename": "content-card-another-mvg.js", - "version": "2.1.0-BETA-2", + "version": "2.1.0-BETA-3", }, { "name": "Another MVG Big Card", "filename": "content-card-another-mvg-big.js", - "version": "2.1.0-BETA-2", + "version": "2.1.0-BETA-3", }, ] From b6c0f9ef992577942f313679cfa184cf9e8c7339 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 7 Nov 2024 16:32:13 +0100 Subject: [PATCH 26/58] Update manifest.json --- custom_components/another_mvg/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/another_mvg/manifest.json b/custom_components/another_mvg/manifest.json index 13ca38c..c263d17 100644 --- a/custom_components/another_mvg/manifest.json +++ b/custom_components/another_mvg/manifest.json @@ -1,7 +1,7 @@ { "domain": "another_mvg", "name": "Another MVG", - "version": "2.1.0-BETA.2", + "version": "2.1.0-BETA.3", "config_flow": true, "documentation": "https://github.com/Nisbo/another_mvg", "issue_tracker": "https://github.com/Nisbo/another_mvg/issues", From 55307aea99b27c00954488a4fc47d947e22acc77 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 7 Nov 2024 16:32:29 +0100 Subject: [PATCH 27/58] Update sensor.py --- custom_components/another_mvg/sensor.py | 133 +++++++++++++++++------- 1 file changed, 98 insertions(+), 35 deletions(-) diff --git a/custom_components/another_mvg/sensor.py b/custom_components/another_mvg/sensor.py index ebc1f83..8af5c82 100644 --- a/custom_components/another_mvg/sensor.py +++ b/custom_components/another_mvg/sensor.py @@ -17,8 +17,10 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.util import Throttle +from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from .const import ( + DOMAIN, CONF_ALERT_FOR, CONF_DOUBLESTATIONNUMBER, CONF_GLOBALID, @@ -40,7 +42,6 @@ DEFAULT_HIDEDESTINATION, DEFAULT_ONLYDESTINATION, DEFAULT_LIMIT, - DEFAULT_CONF_DOUBLESTATIONNUMBER, DEFAULT_CONF_TRANSPORTTYPES, DEFAULT_CONF_GLOBALID2, DEFAULT_HIDENAME, @@ -55,7 +56,7 @@ _LOGGER = logging.getLogger(__name__) -# Zeitintervall zwischen den Updates +# time intervall between the updates MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1) PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( @@ -67,7 +68,7 @@ vol.Optional(CONF_HIDEDESTINATION, default=DEFAULT_HIDEDESTINATION): cv.string, vol.Optional(CONF_ONLYDESTINATION, default=DEFAULT_ONLYDESTINATION): cv.string, vol.Optional(CONF_LIMIT, default=DEFAULT_LIMIT): cv.positive_int, - vol.Optional(CONF_DOUBLESTATIONNUMBER, default=DEFAULT_CONF_DOUBLESTATIONNUMBER): cv.string, + vol.Optional(CONF_DOUBLESTATIONNUMBER, default=""): cv.string, vol.Optional(CONF_TRANSPORTTYPES, default=DEFAULT_CONF_TRANSPORTTYPES): cv.string, vol.Optional(CONF_GLOBALID2, default=DEFAULT_CONF_GLOBALID2): cv.string, vol.Optional(CONF_HIDENAME, default=DEFAULT_HIDENAME): cv.boolean, @@ -78,30 +79,74 @@ } ) +""" This option is not used anymore """ +#async def async_setup_platformNotUsed( +# hass: HomeAssistant, +# config: ConfigType, +# add_entities: AddEntitiesCallback, +# discovery_info: DiscoveryInfoType | None = None, +#) -> None: +# """Set up the sensor platform using YAML configuration.""" +# _LOGGER.warning( +# "Setting up Another MVG sensor using YAML configuration is deprecated. " +# "Please remove the YAML configuration and use the integration through the Home Assistant UI." +# ) +# +# # YAML-Konfiguration hinzufügen +# add_entities([ConnectionInfo(hass, config)], True) + +"""Configuration via YAML --> deprecated --> convert everything to GUI""" async def async_setup_platform( hass: HomeAssistant, config: ConfigType, add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: - """Set up the sensor platform.""" _LOGGER.warning( - "Setting up Another MVG sensor using YAML configuration is deprecated. Please remove the YAML configuration and use the integration through the Home Assistant UI." + "Setting up Another MVG sensor using YAML configuration is deprecated and has been removed. " + "The configuration has been migrated to a config entry. Please remove the YAML configuration and use the integration through the Home Assistant UI." ) - - if discovery_info is None: - # Konfiguration über YAML - add_entities([ConnectionInfo(hass, config)], True) + # Check if no config entry exists and if configuration.yaml config exists, trigger the import flow. + found_entry = None + unique_id_2_check = config.get(CONF_GLOBALID).replace(":", "") + config.get(CONF_DOUBLESTATIONNUMBER) + + gui_entries = hass.config_entries.async_entries(DOMAIN) + #_LOGGER.warning("AnotherMVG: Found GUI-Entities: %d", len(gui_entries)) + + for entry in gui_entries: + #_LOGGER.warning("AnotherMVG: GUI Entity: %s", entry) + if entry.unique_id == unique_id_2_check: + found_entry = entry + _LOGGER.warning("AnotherMVG: Found already configured GUI-Sensor: %s - skip the import.", entry.title) + break + + #_LOGGER.warning("AnotherMVG: Found other GUI-Sensor: %s - do nothing", entry.title) + + if found_entry is None: + _LOGGER.warning("AnotherMVG: The YAML Sensor: %s was converted to a GUI Sensor.", config.get(CONF_NAME)) + await hass.config_entries.flow.async_init(DOMAIN, context={"source": SOURCE_IMPORT}, data=config) + else: + _LOGGER.warning("AnotherMVG: nothing left to convert from YAML to GUI, please remove the related YAML code from your configuration.yaml") + + +"""Configuration via GUI""" +"""Set up Another MVG sensor from a config entry.""" async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigType, async_add_entities: AddEntitiesCallback, ) -> None: - """Set up Another MVG sensor from a config entry.""" - # Konfiguration über GUI - async_add_entities([ConnectionInfo(hass, config_entry.data)]) + """Check if there is an unique_id and if not create an unique_id with the old unique_id format to keep the old relations""" + """From 2.1.0 BETA-3 a new UUID format is used for unique_id and this unique_id will be set during the configuration flow via GUI.""" + """Due to this also CONF_DOUBLESTATIONNUMBER and DEFAULT_CONF_DOUBLESTATIONNUMBER were be removed from the schema, however we have to keep it in the code for compatibility reasons.""" + if not config_entry.unique_id: + unique_id = config_entry.data[CONF_GLOBALID].replace(":", "") + config_entry.data[CONF_DOUBLESTATIONNUMBER] + hass.config_entries.async_update_entry(config_entry, unique_id=unique_id) + async_add_entities([ConnectionInfo(hass, config_entry)]) + + @dataclass class Departure: """Class to hold departure data.""" @@ -126,34 +171,52 @@ class DepartureAlarms: class ConnectionInfo(SensorEntity): """Class for MVG info.""" - def __init__(self, hass: HomeAssistant, config: dict) -> None: - """Initialise.""" - self._onlyline = config[CONF_ONLYLINE] - self._limit = config[CONF_LIMIT] - self._hidedestination = config[CONF_HIDEDESTINATION] - self._onlydestination = config[CONF_ONLYDESTINATION] - self._globalid = config[CONF_GLOBALID] - self._globalid2 = config[CONF_GLOBALID2] - self._name = config[CONF_NAME] + def __init__(self, hass: HomeAssistant, config) -> None: + """Initialize the MVG sensor.""" self._hass = hass - self._doublestationnumber = config[CONF_DOUBLESTATIONNUMBER] - self._transporttypes = config[CONF_TRANSPORTTYPES] - self._hidename = config[CONF_HIDENAME] - self._show_clock = config.get(CONF_SHOW_CLOCK, DEFAULT_SHOW_CLOCK) - self._departure_format = config.get(CONF_DEPARTURE_FORMAT, DEFAULT_DEPARTURE_FORMAT) - self._timezoneFrom = config[CONF_TIMEZONE_FROM] - self._timezoneTo = config[CONF_TIMEZONE_TO] - self._alert_for = config[CONF_ALERT_FOR] + + # check if `config` a `config_entry` or a `dict` is + if hasattr(config, 'data'): + # GUI-Configuration + config_data = config.data + self._unique_id = config.unique_id + else: + # YAML-Configuration --> this is deprecated and will be removed soon + config_data = config + self._unique_id = config_data[CONF_GLOBALID].replace(":", "") + config_data[CONF_DOUBLESTATIONNUMBER] + + # Log-Configuration (for Debugging) + #_LOGGER.warning("Config Entry Data: %s", config_data) + #_LOGGER.warning("Config Entry Options: %s", getattr(config, 'options', None)) + #_LOGGER.warning("Config Entry Unique ID: %s", getattr(config, 'unique_id', None)) + #_LOGGER.warning("Complete Config Entry: %s", config) + + self._onlyline = config_data.get(CONF_ONLYLINE) + self._limit = config_data.get(CONF_LIMIT) + self._hidedestination = config_data.get(CONF_HIDEDESTINATION) + self._onlydestination = config_data.get(CONF_ONLYDESTINATION) + self._globalid = config_data.get(CONF_GLOBALID) + self._globalid2 = config_data.get(CONF_GLOBALID2) + self._name = config_data.get(CONF_NAME) + self._transporttypes = config_data.get(CONF_TRANSPORTTYPES) + self._hidename = config_data.get(CONF_HIDENAME) + self._show_clock = config_data.get(CONF_SHOW_CLOCK, DEFAULT_SHOW_CLOCK) + self._departure_format = config_data.get(CONF_DEPARTURE_FORMAT, DEFAULT_DEPARTURE_FORMAT) + self._timezoneFrom = config_data.get(CONF_TIMEZONE_FROM) + self._timezoneTo = config_data.get(CONF_TIMEZONE_TO) + self._alert_for = config_data.get(CONF_ALERT_FOR) + self._lateConnections = "" + self._dataOutdated = "" self._custom_attributes = { "config": { "name": self._name, "hide_name": self._hidename, "show_clock": self._show_clock, - "departure_format": self._departure_format + "departure_format": self._departure_format, + "unique_id": self._unique_id } } - self._lateConnections = "" - self._dataOutdated = "" + @property def name(self) -> str: @@ -168,8 +231,7 @@ def extra_state_attributes(self): @property def unique_id(self) -> str: - """Return a unique, Home Assistant friendly identifier for this entity.""" - return self._globalid.replace(":", "") + self._doublestationnumber + return self._unique_id @property def native_value(self): @@ -236,7 +298,7 @@ def get_departures(self) -> str: # check if self._custom_attributes is set to avoid undefined messages if the API is down or if there is an error # or for the first call by the frontend when there is no data available in departures # normally you should never see this message - if not self._custom_attributes: + if not self._custom_attributes or not self._custom_attributes.get("departures"): # Add a dummy connection departures = [] departures.append( @@ -491,3 +553,4 @@ def get_api_for_globalid( raise MVGException( f"AnotherMVG: Other problem while connecting to the MVG API for {global_id} - {name}" ) from ex + From 807936052e33d4f0bf599850052838299a35d666 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Fri, 8 Nov 2024 13:28:00 +0100 Subject: [PATCH 28/58] Update en.json --- .../another_mvg/translations/en.json | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/custom_components/another_mvg/translations/en.json b/custom_components/another_mvg/translations/en.json index ce054c5..bb0789d 100644 --- a/custom_components/another_mvg/translations/en.json +++ b/custom_components/another_mvg/translations/en.json @@ -12,15 +12,13 @@ "hidename": "Hide the name of the card (incl. clock)", "show_clock": "Show a clock on the top right", "globalid2": "Global ID 2", - "doublestationnumber": "Double Station Number", "timezone_from": "Timezone From", "timezone_to": "Timezone To", "alert_for": "Alert Attributes For" }, "data_description": { "hidename": "If you don't want to see the name of the card, enable this option.", - "globalid2": "If you have two stations close together (or far apart), such as a train station and a bus stop, you can combine both in one card. Keep in mind that you must select the transportation types in transporttypes for both stations. Using this function can lead to issues, as there will be two API calls within one second, and it’s possible that the API will block the second call. If you use it for only one card, it should not be a problem, but if you use it for more, the risk increases that the API will block the request. You need to insert the global ID from the second station in a format like de:09162:2, as shown in the Global ID list above. You can find it using the query https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing (just replace the name in the query). If there are multiple entries, you will need to find the correct one. Alternatively, you can start creating a new stop to get the global ID from the search results.", - "doublestationnumber": "If you want to create two or more cards for the same globalid (e.g., one for BUS, one for S-BAHN, one for TRAM), you need to use this parameter. It can be a number or a letter, and multiple numbers or letters are also allowed. No special characters or spaces are permitted.", + "globalid2": "If you have two stations close to each other (or far apart), such as a train station and a bus stop, you can combine them into a single card. Note that you must select the transportation types for both stations. Using this feature may lead to issues, as it triggers two API calls within one second, and it’s possible that the API may block the second call. If you use this option for only one card, it should not be a problem, but using it for more cards increases the risk of the API blocking the request. If you do not know the Global ID 2, you can later select it under **'CONFIGURE'** using the option **'Additional Station (Global ID 2) - search and save'**. Alternatively, you can find the Global ID for your station here: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Simply replace the name in the query. You need to enter the Global ID in the format **de:09162:2**.", "timezone_from": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", "timezone_to": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", "alert_for": "If you want to create additional attributes for certain lines, like S3, S4, and S20, you can configure them as a comma-separated list. For more information, refer to the documentation." @@ -34,9 +32,9 @@ "onlydestination": "Only these Destinations" }, "data_description": { - "onlyline": "If you want to see only certain lines, like S3, S4, and S20, you can configure them as a comma-separated list.", - "hidedestination": "If you want to hide certain directions/destinations, you must enter the EXACT names of the unwanted destinations as they appear on the connection display (card). The names should be separated by semicolons.", - "onlydestination": "If you want to see only specific directions/destinations, you must enter the EXACT names of the desired destinations as they appear on the connection display (card). The names should be separated by semicolons." + "onlyline": "If you want to see only certain lines, like S3, S4, and S20, you can configure them as a comma-separated list. Example: ```S3,S4,S20```", + "hidedestination": "If you want to hide certain directions/destinations, you must enter the EXACT names of the unwanted destinations as they appear on the connection display (card). The names should be separated by **semicolons**. Example: ```Grafing-Bahnhof;Heimeranplatz;Deisenhofen;Holzkirchen;Grafing Bahnhof```", + "onlydestination": "If you want to see only specific directions/destinations, you must enter the EXACT names of the desired destinations as they appear on the connection display (card). The names should be separated by **semicolons**. Example: ```Grafing-Bahnhof;Heimeranplatz;Deisenhofen;Holzkirchen;Grafing Bahnhof```" } } }, @@ -44,7 +42,7 @@ "description": "Please provide the required information to set up the Another MVG integration.", "data": { "globalid": "Global ID", - "name": "Name", + "name": "Name of the Card", "limit": "Number of departures", "departure_format": "Formatting of the departure time", "transporttypes": "Transport Types", @@ -52,10 +50,10 @@ }, "data_description": { "globalid": "Select your station / stop from the list above.", - "name": "Name to display in the Card", + "name": "Name to display in the Card.", "limit": "By default, you will see 6 departures. If you want to see more or fewer, you can configure this setting. The API will retrieve a maximum of 80 departures. If you use filters like 'hidedestination' and it filters out 40 entries, you will only see the remaining 40 as the maximum.", "departure_format": "In the example, 16:27 is the scheduled departure time, the train has a delay of 2 minutes, and 16:29 is the current departure time. If only the current departure time (Option 3) is displayed, the time will be shown in red if there is a delay.", - "transporttypes": "Select the Transport Types you want to see in the card.", + "transporttypes": "Select the Transport Types you want to see in the card. You can also enter **'BAHN'** (and press **'ENTER'**) to additionally see departures for regular trains. However, this feature is not yet fully supported.", "station_name": "Enter the name of the station you want to search for." } }, @@ -90,15 +88,13 @@ "hidename": "Hide the name of the card (incl. clock)", "show_clock": "Show a clock on the top right", "globalid2": "Global ID 2", - "doublestationnumber": "Double Station Number", "timezone_from": "Timezone From", "timezone_to": "Timezone To", "alert_for": "Alert Attributes For" }, "data_description": { "hidename": "If you don't want to see the name of the card, enable this option.", - "globalid2": "If you have two stations close together (or far apart), such as a train station and a bus stop, you can combine both in one card. Keep in mind that you must select the transportation types in transporttypes for both stations. Using this function can lead to issues, as there will be two API calls within one second, and it’s possible that the API will block the second call. If you use it for only one card, it should not be a problem, but if you use it for more, the risk increases that the API will block the request. You need to insert the global ID from the second station in a format like de:09162:2. You can find it using the query https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing (just replace the name in the query). If there are multiple entries, you will need to find the correct one. Alternatively, you can start creating a new stop to get the global ID from the search results.", - "doublestationnumber": "If you want to create two or more cards for the same globalid (e.g., one for BUS, one for S-BAHN, one for TRAM), you need to use this parameter. It can be a number or a letter, and multiple numbers or letters are also allowed. No special characters or spaces are permitted.", + "globalid2": "If you have two stations close to each other (or far apart), such as a train station and a bus stop, you can combine them into a single card. Note that you must select the transportation modes for both stations. Using this feature may lead to issues, as it triggers two API calls within one second, and it’s possible that the API may block the second call. If you use this option for only one card, it should not be a problem, but using it for more cards increases the risk of the API blocking the request. If you wish to change the Global ID 2 and do not know the ID, close this input form and select the option **'Additional Station (Global ID 2) - search and save'** under **'CONFIGURE'**. Alternatively, you can find the Global ID for your station here: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Simply replace the name in the query. You need to enter the Global ID in the format **de:09162:2**.", "timezone_from": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", "timezone_to": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", "alert_for": "If you want to create additional attributes for certain lines, like S3, S4, and S20, you can configure them as a comma-separated list. For more information, refer to the documentation." @@ -112,26 +108,26 @@ "onlydestination": "Only these Destinations" }, "data_description": { - "onlyline": "If you want to see only certain lines, like S3, S4, and S20, you can configure them as a comma-separated list.", - "hidedestination": "If you want to hide certain directions/destinations, you must enter the EXACT names of the unwanted destinations as they appear on the connection display (card). The names should be separated by semicolons.", - "onlydestination": "If you want to see only specific directions/destinations, you must enter the EXACT names of the desired destinations as they appear on the connection display (card). The names should be separated by semicolons." + "onlyline": "If you want to see only certain lines, like S3, S4, and S20, you can configure them as a comma-separated list. Example: ```S3,S4,S20```", + "hidedestination": "If you want to hide certain directions/destinations, you must enter the EXACT names of the unwanted destinations as they appear on the connection display (card). The names should be separated by **semicolons**. Example: ```Grafing-Bahnhof;Heimeranplatz;Deisenhofen;Holzkirchen;Grafing Bahnhof```", + "onlydestination": "If you want to see only specific directions/destinations, you must enter the EXACT names of the desired destinations as they appear on the connection display (card). The names should be separated by **semicolons**. Example: ```Grafing-Bahnhof;Heimeranplatz;Deisenhofen;Holzkirchen;Grafing Bahnhof```" } } }, "title": "Edit Options for Another MVG", "data": { "globalid": "Global ID", - "name": "Name", + "name": "Name of the Card", "limit": "Number of departures", "departure_format": "Formatting of the departure time", "transporttypes": "Transport Types" }, "data_description": { - "globalid": "The station identifier for the stop/station/location. Normally, this entry is created automatically during the initial setup. It is NOT the name of the station! You can find the global ID for your station here: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Just replace the name in the query. If there are multiple entries, you will need to find the correct one.", - "name": "Name to display in the Card", + "globalid": "The station identifier for the stop/station/location. This entry is usually created automatically during the initial setup and is **NOT** the station name! If you wish to change this entry and don’t know the ID, close this input form and select the option **'Station (Global ID 1) - search and save'** under **'CONFIGURE.'** Alternatively, you can find the Global ID for your station here: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Simply replace the name in the query.", + "name": "Name to display in the Card.", "limit": "By default, you will see 6 departures. If you want to see more or fewer, you can configure this setting. The API will retrieve a maximum of 80 departures. If you use filters like 'hidedestination' and it filters out 40 entries, you will only see the remaining 40 as the maximum.", "departure_format": "In the example, 16:27 is the scheduled departure time, the train has a delay of 2 minutes, and 16:29 is the current departure time. If only the current departure time (Option 3) is displayed, the time will be shown in red if there is a delay.", - "transporttypes": "Select the Transport Types you want to see in the card." + "transporttypes": "Select the Transport Types you want to see in the card. You can also enter **'BAHN'** (and press **'ENTER'**) to additionally see departures for regular trains. However, this feature is not yet fully supported." } }, "globalid2search": { From 089d72d7a2bc7d82129216467fd1ffaf39735af3 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Fri, 8 Nov 2024 13:28:45 +0100 Subject: [PATCH 29/58] Update de.json --- .../another_mvg/translations/de.json | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/custom_components/another_mvg/translations/de.json b/custom_components/another_mvg/translations/de.json index 3afcbb1..8174803 100644 --- a/custom_components/another_mvg/translations/de.json +++ b/custom_components/another_mvg/translations/de.json @@ -12,15 +12,13 @@ "hidename": "Den Namen der Karte (inkl. Uhr) ausblenden", "show_clock": "Uhr oben rechts anzeigen", "globalid2": "Global ID 2", - "doublestationnumber": "Doppelte Stationsnummer", "timezone_from": "Zeitzone von", "timezone_to": "Zeitzone nach", "alert_for": "Alarmattribute für" }, "data_description": { "hidename": "Wenn Sie den Namen der Karte nicht sehen möchten, aktivieren Sie diese Option.", - "globalid2": "Wenn Sie zwei Stationen nah beieinander (oder weit voneinander entfernt) haben, wie einen Bahnhof und eine Bushaltestelle, können Sie beide in einer Karte kombinieren. Beachten Sie, dass Sie die Transportarten in transporttypes für beide Stationen auswählen müssen. Die Verwendung dieser Funktion kann zu Problemen führen, da es innerhalb einer Sekunde zwei API-Aufrufe geben wird, und es ist möglich, dass die API den zweiten Aufruf blockiert. Wenn Sie es nur für eine Karte verwenden, sollte es kein Problem sein, aber wenn Sie es für mehr verwenden, steigt das Risiko, dass die API die Anfrage blockiert. Sie müssen die Global ID der zweiten Station im Format de:09162:2 eingeben, wie sie in der Liste der Global IDs oben gezeigt wird. Sie können sie mit der Abfrage https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing finden (ersetzen Sie einfach den Namen in der Abfrage). Wenn es mehrere Einträge gibt, müssen Sie den richtigen finden. Alternativ können Sie beginnen, eine neue Haltestelle zu erstellen, um die Global ID aus den Suchergebnissen zu erhalten.", - "doublestationnumber": "Wenn Sie zwei oder mehr Karten für dieselbe Global ID erstellen möchten (z. B. eine für BUS, eine für S-BAHN, eine für TRAM), müssen Sie diesen Parameter verwenden. Es kann eine Zahl oder ein Buchstabe sein, und auch mehrere Zahlen oder Buchstaben sind erlaubt. Es sind keine Sonderzeichen oder Leerzeichen zulässig.", + "globalid2": "Wenn Sie zwei Stationen nah beieinander (oder weit voneinander entfernt) haben, wie einen Bahnhof und eine Bushaltestelle, können Sie beide in einer Karte kombinieren. Beachten Sie, dass Sie die Transportarten für beide Stationen auswählen müssen. Die Verwendung dieser Funktion kann zu Problemen führen, da es innerhalb einer Sekunde zwei API-Aufrufe gibt, und es ist möglich, dass die API den zweiten Aufruf blockiert. Wenn Sie diese Option nur für eine Karte verwenden, sollte es kein Problem sein, aber wenn Sie es für mehr verwenden, steigt das Risiko, dass die API die Anfrage blockiert. Wenn Sie die Global ID 2 nicht kennen, können Sie diese später unter **'KONFIGURIEREN'** über die Option **'Zusätzliche Station (Global ID 2) - suchen und speichern'** auswählen. Alternativ können Sie die Global ID für Ihre Station auch hier finden: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Ersetzen Sie dafür einfach den Namen in der Abfrage. Sie müssen die Global ID im Format **de:09162:2** eingeben.", "timezone_from": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", "timezone_to": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", "alert_for": "Wenn Sie zusätzliche Attribute für bestimmte Linien, wie S3, S4 und S20, erstellen möchten, können Sie sie als kommagetrennte Liste konfigurieren. Für mehr Informationen schauen Sie bitte in die Dokumentation." @@ -34,9 +32,9 @@ "onlydestination": "Nur diese Ziele" }, "data_description": { - "onlyline": "Wenn Sie nur bestimmte Linien sehen möchten, wie S3, S4 und S20, können Sie sie als kommagetrennte Liste konfigurieren.", - "hidedestination": "Wenn Sie bestimmte Richtungen/Ziele ausblenden möchten, müssen Sie die GENAUEN Namen der unerwünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch Semikolons getrennt sein.", - "onlydestination": "Wenn Sie nur bestimmte Richtungen/Ziele sehen möchten, müssen Sie die GENAUEN Namen der gewünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch Semikolons getrennt sein." + "onlyline": "Wenn Sie nur bestimmte Linien sehen möchten, wie S3, S4 und S20, können Sie sie als kommagetrennte Liste konfigurieren. Beispiel: ```S3,S4,S20```", + "hidedestination": "Wenn Sie bestimmte Richtungen/Ziele ausblenden möchten, müssen Sie die **GENAUEN** Namen der unerwünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch **Semikolons** getrennt sein. Beispiel: ```Grafing-Bahnhof;Heimeranplatz;Deisenhofen;Holzkirchen;Grafing Bahnhof```", + "onlydestination": "Wenn Sie nur bestimmte Richtungen/Ziele sehen möchten, müssen Sie die GENAUEN Namen der gewünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen müssen durch **Semikolons** getrennt sein. Beispiel: ```Grafing-Bahnhof;Heimeranplatz;Deisenhofen;Holzkirchen;Grafing Bahnhof```" } } }, @@ -44,7 +42,7 @@ "description": "Bitte geben Sie die erforderlichen Informationen ein, um die Another MVG-Integration einzurichten.", "data": { "globalid": "Global ID", - "name": "Name", + "name": "Name der Karte", "limit": "Anzahl der Abfahrten", "departure_format": "Formatierung der Abfahrtzeit", "transporttypes": "Transportarten", @@ -52,10 +50,10 @@ }, "data_description": { "globalid": "Wählen Sie Ihre Station / Haltestelle aus der obigen Liste aus.", - "name": "Name, der in der Karte angezeigt werden soll", + "name": "Der Name, der in der Karte angezeigt werden soll.", "limit": "Standardmäßig sehen Sie 6 Abfahrten. Wenn Sie mehr oder weniger sehen möchten, können Sie diese Einstellung konfigurieren. Die API ruft maximal 80 Abfahrten ab. Wenn Sie Filter wie 'hidedestination' verwenden und 40 Einträge herausgefiltert werden, sehen Sie maximal die verbleibenden 40.", "departure_format": "In dem Beispiel ist 16:27 die geplante Abfahrtszeit, der Zug hat 2 Minuten Verspätung und 16:29 ist die aktuelle Abfahrtszeit. Sollte nur die aktuelle Abfahrtszeit (Option 3) angezeigt werden, wird die Zeit, sofern eine Verspätung vorliegt, in Rot angezeigt.", - "transporttypes": "Wählen Sie die Transportarten aus, die Sie in der Karte sehen möchten.", + "transporttypes": "Wählen Sie die Transportarten aus, die Sie in der Karte sehen möchten. Sie können auch **'BAHN'** eingeben (und **'ENTER'** drücken) um zusätzlich die Abfahrten der normalen Züge zu sehen. Diese Funktion wird aber noch nicht zu 100% unterstützt.", "station_name": "Geben Sie den Namen der Station ein, nach der Sie suchen möchten." } }, @@ -90,15 +88,13 @@ "hidename": "Den Namen der Karte (inkl. Uhr) ausblenden", "show_clock": "Uhr oben rechts anzeigen", "globalid2": "Global ID 2", - "doublestationnumber": "Doppelte Stationsnummer", "timezone_from": "Zeitzone von", "timezone_to": "Zeitzone nach", "alert_for": "Alarmattribute für" }, "data_description": { "hidename": "Wenn Sie den Namen der Karte nicht sehen möchten, aktivieren Sie diese Option.", - "globalid2": "Wenn Sie zwei Stationen nah beieinander (oder weit voneinander entfernt) haben, wie einen Bahnhof und eine Bushaltestelle, können Sie beide in einer Karte kombinieren. Beachten Sie, dass Sie die Transportarten in transporttypes für beide Stationen auswählen müssen. Die Verwendung dieser Funktion kann zu Problemen führen, da es innerhalb einer Sekunde zwei API-Aufrufe geben wird, und es ist möglich, dass die API den zweiten Aufruf blockiert. Wenn Sie es nur für eine Karte verwenden, sollte es kein Problem sein, aber wenn Sie es für mehr verwenden, steigt das Risiko, dass die API die Anfrage blockiert. Sie müssen die Global ID der zweiten Station im Format de:09162:2 eingeben. Sie können sie mit der Abfrage https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing finden (ersetzen Sie einfach den Namen in der Abfrage). Wenn es mehrere Einträge gibt, müssen Sie den richtigen finden. Alternativ können Sie beginnen, eine neue Haltestelle zu erstellen, um die Global ID aus den Suchergebnissen zu erhalten.", - "doublestationnumber": "Wenn Sie zwei oder mehr Karten für dieselbe Global ID erstellen möchten (z. B. eine für BUS, eine für S-BAHN, eine für TRAM), müssen Sie diesen Parameter verwenden. Es kann eine Zahl oder ein Buchstabe sein, und auch mehrere Zahlen oder Buchstaben sind erlaubt. Es sind keine Sonderzeichen oder Leerzeichen zulässig.", + "globalid2": "Wenn Sie zwei Stationen nah beieinander (oder weit voneinander entfernt) haben, wie einen Bahnhof und eine Bushaltestelle, können Sie beide in einer Karte kombinieren. Beachten Sie, dass Sie die Transportarten für beide Stationen auswählen müssen. Die Verwendung dieser Funktion kann zu Problemen führen, da es innerhalb einer Sekunde zwei API-Aufrufe gibt, und es ist möglich, dass die API den zweiten Aufruf blockiert. Wenn Sie diese Option nur für eine Karte verwenden, sollte es kein Problem sein, aber wenn Sie es für mehr verwenden, steigt das Risiko, dass die API die Anfrage blockiert. Wenn Sie die Global ID 2 ändern möchten und die ID nicht kennen, schließen Sie diese Eingabemaske und wählen Sie unter **'KONFIGURIEREN'** die Option **'Zusätzliche Station (Global ID 2) - suchen und speichern'** aus. Alternativ können Sie die Global ID für Ihre Station auch hier finden: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Ersetzen Sie dafür einfach den Namen in der Abfrage. Sie müssen die Global ID im Format **de:09162:2** eingeben.", "timezone_from": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", "timezone_to": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", "alert_for": "Wenn Sie zusätzliche Attribute für bestimmte Linien, wie S3, S4 und S20, erstellen möchten, können Sie sie als kommagetrennte Liste konfigurieren. Für mehr Informationen schauen Sie bitte in die Dokumentation." @@ -112,26 +108,26 @@ "onlydestination": "Nur diese Ziele" }, "data_description": { - "onlyline": "Wenn Sie nur bestimmte Linien sehen möchten, wie S3, S4 und S20, können Sie sie als kommagetrennte Liste konfigurieren.", - "hidedestination": "Wenn Sie bestimmte Richtungen/Ziele ausblenden möchten, müssen Sie die GENAUEN Namen der unerwünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch Semikolons getrennt sein.", - "onlydestination": "Wenn Sie nur bestimmte Richtungen/Ziele sehen möchten, müssen Sie die GENAUEN Namen der gewünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch Semikolons getrennt sein." + "onlyline": "Wenn Sie nur bestimmte Linien sehen möchten, wie S3, S4 und S20, können Sie sie als kommagetrennte Liste konfigurieren. Beispiel: ```S3,S4,S20```", + "hidedestination": "Wenn Sie bestimmte Richtungen/Ziele ausblenden möchten, müssen Sie die **GENAUEN** Namen der unerwünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch **Semikolons** getrennt sein. Beispiel: ```Grafing-Bahnhof;Heimeranplatz;Deisenhofen;Holzkirchen;Grafing Bahnhof```", + "onlydestination": "Wenn Sie nur bestimmte Richtungen/Ziele sehen möchten, müssen Sie die **GENAUEN** Namen der gewünschten Ziele eingeben, wie sie auf der Verbindungsanzeige (Karte) erscheinen. Die Namen sollten durch **Semikolons** getrennt sein. Beispiel: ```Grafing-Bahnhof;Heimeranplatz;Deisenhofen;Holzkirchen;Grafing Bahnhof```" } } }, "title": "Optionen für Another MVG", "data": { "globalid": "Global ID", - "name": "Name", + "name": "Name der Karte", "limit": "Anzahl der Abfahrten", "departure_format": "Formatierung der Abfahrtzeit", "transporttypes": "Transportarten" }, "data_description": { - "globalid": "Die Stationskennung für die Haltestelle/Station/Ort. Normalerweise wird dieser Eintrag während der Erstkonfiguration automatisch erstellt. Es ist NICHT der Name der Station! Hier finden Sie die Global ID für Ihre Station: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Ersetzen Sie einfach den Namen in der Abfrage. Wenn es mehrere Einträge gibt, müssen Sie den richtigen finden.", - "name": "Name, der in der Karte angezeigt werden soll", + "globalid": "Die Stationskennung für die Haltestelle/Station/Ort. Dieser Eintrag wird normalerweise während der Erstkonfiguration automatisch erstellt und ist **NICHT** der Name der Station! Wenn Sie diesen Eintrag ändern möchten und die ID nicht kennen, schließen Sie diese Eingabemaske und wählen Sie unter **'KONFIGURIEREN'** die Option **'Station (Global ID 1) - suchen und speichern'** aus. Alternativ können Sie die Global ID für Ihre Station hier finden: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Ersetzen Sie dafür einfach den Namen in der Abfrage.", + "name": "Der Name, der in der Karte angezeigt werden soll.", "limit": "Standardmäßig sehen Sie 6 Abfahrten. Wenn Sie mehr oder weniger sehen möchten, können Sie diese Einstellung konfigurieren. Die API ruft maximal 80 Abfahrten ab. Wenn Sie Filter wie 'hidedestination' verwenden und 40 Einträge herausgefiltert werden, sehen Sie maximal die verbleibenden 40.", "departure_format": "In dem Beispiel ist 16:27 die geplante Abfahrtszeit, der Zug hat 2 Minuten Verspätung und 16:29 ist die aktuelle Abfahrtszeit. Sollte nur die aktuelle Abfahrtszeit (Option 3) angezeigt werden, wird die Zeit, sofern eine Verspätung vorliegt, in Rot angezeigt.", - "transporttypes": "Wählen Sie die Transportarten aus, die Sie in der Karte sehen möchten." + "transporttypes": "Wählen Sie die Transportarten aus, die Sie in der Karte sehen möchten. Sie können auch **'BAHN'** eingeben (und **'ENTER'** drücken) um zusätzlich die Abfahrten der normalen Züge zu sehen. Diese Funktion wird aber noch nicht zu 100% unterstützt." } }, "globalid2search": { From 39a19c1ec56584b323f3634a18eb8afd5b474d33 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Fri, 8 Nov 2024 14:02:41 +0100 Subject: [PATCH 30/58] Update config_flow.py --- custom_components/another_mvg/config_flow.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/custom_components/another_mvg/config_flow.py b/custom_components/another_mvg/config_flow.py index 592d085..808ed25 100644 --- a/custom_components/another_mvg/config_flow.py +++ b/custom_components/another_mvg/config_flow.py @@ -108,7 +108,7 @@ async def async_step_user(self, user_input=None): advanced_options = user_input.get("advanced_options", {}) filter_options = user_input.get("filter_options", {}) unique_id = str(uuid.uuid4()) # Generate unique_id - _LOGGER.warning("AnotherMVG: UUID prepared: %s", unique_id) + #_LOGGER.warning("AnotherMVG: UUID prepared: %s", unique_id) # and convert the input # this is because the section function creates an dictionary and I dont want this @@ -268,7 +268,6 @@ def _user_config_schema(self, stations, station_name): vol.Optional(CONF_SHOW_CLOCK, default=DEFAULT_SHOW_CLOCK): bool, vol.Optional(CONF_HIDENAME, default=DEFAULT_HIDENAME): bool, vol.Optional(CONF_GLOBALID2, default=DEFAULT_CONF_GLOBALID2): str, - #vol.Optional(CONF_DOUBLESTATIONNUMBER, default=DEFAULT_CONF_DOUBLESTATIONNUMBER): str, vol.Optional(CONF_TIMEZONE_FROM, default=DEFAULT_TIMEZONE_FROM): str, vol.Optional(CONF_TIMEZONE_TO, default=DEFAULT_TIMEZONE_TO): str, vol.Optional(CONF_ALERT_FOR, default=DEFAULT_ALERT_FOR): str, @@ -458,9 +457,6 @@ async def async_step_edit(self, user_input=None): if CONF_ALERT_FOR in advanced_options: user_input[CONF_ALERT_FOR] = advanced_options[CONF_ALERT_FOR] - #if CONF_DOUBLESTATIONNUMBER in advanced_options: - # user_input[CONF_DOUBLESTATIONNUMBER] = advanced_options[CONF_DOUBLESTATIONNUMBER] - if CONF_TIMEZONE_FROM in advanced_options: user_input[CONF_TIMEZONE_FROM] = advanced_options[CONF_TIMEZONE_FROM] @@ -484,7 +480,7 @@ async def async_step_edit(self, user_input=None): user_input[CONF_ONLYDESTINATION] = filter_options[CONF_ONLYDESTINATION] - # Ensure that empty fields are stored as empty strings CONF_DOUBLESTATIONNUMBER + # Ensure that empty fields are stored as empty strings for key in [CONF_ONLYLINE, CONF_HIDEDESTINATION, CONF_ONLYDESTINATION, CONF_TIMEZONE_FROM, CONF_TIMEZONE_TO, CONF_ALERT_FOR, CONF_GLOBALID2]: if key not in user_input: @@ -494,7 +490,7 @@ async def async_step_edit(self, user_input=None): if CONF_TRANSPORTTYPES in user_input: user_input[CONF_TRANSPORTTYPES] = ','.join(user_input[CONF_TRANSPORTTYPES]) - # Save the updated data self.config_entry, data={**self.config_entry.data, **user_input} + # Save the updated data self.hass.config_entries.async_update_entry( self.config_entry, data=user_input ) @@ -519,8 +515,7 @@ async def async_step_edit(self, user_input=None): "custom_value": True } }), - vol.Optional(CONF_LIMIT, default=current_data.get(CONF_LIMIT, DEFAULT_LIMIT)): int, - + vol.Optional(CONF_LIMIT, default=current_data.get(CONF_LIMIT, DEFAULT_LIMIT)): int, vol.Required(CONF_DEPARTURE_FORMAT, default=current_data.get(CONF_DEPARTURE_FORMAT, "1")): SelectSelector( SelectSelectorConfig( options = [ @@ -553,7 +548,6 @@ async def async_step_edit(self, user_input=None): vol.Optional(CONF_SHOW_CLOCK, description={"suggested_value": current_data.get(CONF_SHOW_CLOCK, "")}): bool, vol.Optional(CONF_HIDENAME, description={"suggested_value": current_data.get(CONF_HIDENAME, "")}): bool, vol.Optional(CONF_GLOBALID2, description={"suggested_value": current_data.get(CONF_GLOBALID2, "")}): str, - #vol.Optional(CONF_DOUBLESTATIONNUMBER, description={"suggested_value": current_data.get(CONF_DOUBLESTATIONNUMBER, "")}): str, vol.Optional(CONF_TIMEZONE_FROM, description={"suggested_value": current_data.get(CONF_TIMEZONE_FROM, "")}): str, vol.Optional(CONF_TIMEZONE_TO, description={"suggested_value": current_data.get(CONF_TIMEZONE_TO, "")}): str, vol.Optional(CONF_ALERT_FOR, description={"suggested_value": current_data.get(CONF_ALERT_FOR, "")}): str, From 46555d8654f143169dd378aa185dbe68494b9e6a Mon Sep 17 00:00:00 2001 From: Nisbo Date: Fri, 8 Nov 2024 14:08:31 +0100 Subject: [PATCH 31/58] Update sensor.py --- custom_components/another_mvg/sensor.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/custom_components/another_mvg/sensor.py b/custom_components/another_mvg/sensor.py index 8af5c82..3179dfb 100644 --- a/custom_components/another_mvg/sensor.py +++ b/custom_components/another_mvg/sensor.py @@ -79,22 +79,6 @@ } ) -""" This option is not used anymore """ -#async def async_setup_platformNotUsed( -# hass: HomeAssistant, -# config: ConfigType, -# add_entities: AddEntitiesCallback, -# discovery_info: DiscoveryInfoType | None = None, -#) -> None: -# """Set up the sensor platform using YAML configuration.""" -# _LOGGER.warning( -# "Setting up Another MVG sensor using YAML configuration is deprecated. " -# "Please remove the YAML configuration and use the integration through the Home Assistant UI." -# ) -# -# # YAML-Konfiguration hinzufügen -# add_entities([ConnectionInfo(hass, config)], True) - """Configuration via YAML --> deprecated --> convert everything to GUI""" async def async_setup_platform( hass: HomeAssistant, From c9a052a3162221b6f10aa290c04335bc14e4ccb2 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Fri, 8 Nov 2024 14:14:20 +0100 Subject: [PATCH 32/58] Update content-card-another-mvg.js --- .../another_mvg/frontend/content-card-another-mvg.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg.js b/custom_components/another_mvg/frontend/content-card-another-mvg.js index a2b3269..f747bf5 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg.js @@ -109,6 +109,13 @@ class ContentAnotherMVG extends HTMLElement { background-color: #4682B4; } + /* BAHN */ + span.BAHN { + background-color: #FFFFFF; + color: #E30613; + border: 1px solid #E30613; + } + /* SBAHN */ span.SBAHN { border-radius:1000px; From fe3680f3f604239861c2ee37ebabf6c58c9b99fc Mon Sep 17 00:00:00 2001 From: Nisbo Date: Fri, 8 Nov 2024 14:15:39 +0100 Subject: [PATCH 33/58] Update content-card-another-mvg-big.js --- .../another_mvg/frontend/content-card-another-mvg-big.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js index 69a7f37..591330a 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js @@ -116,6 +116,13 @@ class ContentAnotherMVGbig extends HTMLElement { padding:2px 4px 2px 4px; } + /* BAHN */ + span.BAHN { + background-color: #FFFFFF; + color: #E30613; + border: 1px solid #E30613; + } + /* SBAHN */ span.SBAHN { border-radius:1000px; From 41c968b3b465ea1630ad97c771bea1ae1483f25c Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 13 Nov 2024 06:50:51 +0100 Subject: [PATCH 34/58] added S5 --- .../another_mvg/frontend/content-card-another-mvg-big.js | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js index 591330a..9ce9be4 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg-big.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg-big.js @@ -132,6 +132,7 @@ class ContentAnotherMVGbig extends HTMLElement { span.S2 {background-color: #76B82A;} span.S3 {background-color: #951B81;} span.S4 {background-color: #E30613;} + span.S5 {background-color: #005E82;} span.S6 {background-color: #00975F;} span.S7 {background-color: #943126;} span.S8 {background-color: #000000; color: #FFFFFF;} From 7546286188badb0d4e689c3b3db62193569e9e6e Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 13 Nov 2024 06:51:20 +0100 Subject: [PATCH 35/58] added S5 --- .../another_mvg/frontend/content-card-another-mvg.js | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg.js b/custom_components/another_mvg/frontend/content-card-another-mvg.js index f747bf5..f6a04ba 100644 --- a/custom_components/another_mvg/frontend/content-card-another-mvg.js +++ b/custom_components/another_mvg/frontend/content-card-another-mvg.js @@ -125,6 +125,7 @@ class ContentAnotherMVG extends HTMLElement { span.S2 {background-color: #76B82A;} span.S3 {background-color: #951B81;} span.S4 {background-color: #E30613;} + span.S5 {background-color: #005E82;} span.S6 {background-color: #00975F;} span.S7 {background-color: #943126;} span.S8 {background-color: #000000; color: #FFFFFF;} From 30330cabea4b29fa97dbe0561eaaf975aa9e8efa Mon Sep 17 00:00:00 2001 From: Nisbo Date: Wed, 13 Nov 2024 06:52:44 +0100 Subject: [PATCH 36/58] Update manifest.json --- custom_components/another_mvg/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/another_mvg/manifest.json b/custom_components/another_mvg/manifest.json index c263d17..6bcb4d0 100644 --- a/custom_components/another_mvg/manifest.json +++ b/custom_components/another_mvg/manifest.json @@ -1,7 +1,7 @@ { "domain": "another_mvg", "name": "Another MVG", - "version": "2.1.0-BETA.3", + "version": "2.1.0-BETA.4", "config_flow": true, "documentation": "https://github.com/Nisbo/another_mvg", "issue_tracker": "https://github.com/Nisbo/another_mvg/issues", From 66dcadc475a78dc22609088841bd1e6701bfb3d6 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 14 Nov 2024 13:13:19 +0100 Subject: [PATCH 37/58] Create content-card-another-mvg-livemap.js --- .../content-card-another-mvg-livemap.js | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 custom_components/another_mvg/frontend/content-card-another-mvg-livemap.js diff --git a/custom_components/another_mvg/frontend/content-card-another-mvg-livemap.js b/custom_components/another_mvg/frontend/content-card-another-mvg-livemap.js new file mode 100644 index 0000000..1852b02 --- /dev/null +++ b/custom_components/another_mvg/frontend/content-card-another-mvg-livemap.js @@ -0,0 +1,148 @@ +class ContentAnotherMVGlivemap extends HTMLElement { + set hass(hass) { + if (!this.content) { + const card = document.createElement('ha-card'); + card.style.display = "flex"; + card.style.flexDirection = "column"; + card.style.height = "100%"; + card.style.overflow = "hidden"; + + this.content = document.createElement('div'); + this.content.style.flex = "1"; + this.content.style.display = "flex"; + this.content.style.alignItems = "stretch"; + + card.appendChild(this.content); + this.appendChild(card); + + this.updateIframe(); + } + } + + setConfig(config) { + this.config = { + x: config.x || 2750799, + y: config.y || 1560004, + zoom: config.zoom || 4.8, + mode: config.mode || "schematic", + ...config, + }; + this.updateIframe(); + } + + updateIframe() { + if (!this.content) return; + + const { x, y, zoom, mode } = this.config; + const url = `https://s-bahn-muenchen-live.de/?mode=${mode}&showDepartures=true&x=${x}&y=${y}&z=${zoom}`; + + this.content.innerHTML = ` + + `; + } + + getCardSize() { + return 26; + } + + static getConfigElement() { + return document.createElement('content-another-mvg-livemap-editor'); + } +} + +class ContentAnotherMVGlivemapEditor extends HTMLElement { + constructor() { + super(); + this.config = {}; + } + + setConfig(config) { + this.config = config; + this.render(); + } + + render() { + this.innerHTML = ''; // Reset inner HTML + + const container = document.createElement('div'); + container.style.display = "flex"; + container.style.flexDirection = "column"; + + // Add a description at the top of the editor + const description = document.createElement('p'); + description.innerHTML = `Alle 4 Werte hängen voneinander ab. Am besten öffnet man die LiveMap (klick) im Browser (PC) und übernimmt die Werte aus der Adresszeile, sobald der gewünschte Zoom eingestellt ist.`; + description.style.fontSize = "14px"; + description.style.marginBottom = "15px"; + container.appendChild(description); + + // Define input fields with descriptions + const fields = [ + { name: 'x', label: 'X - Koordinate', type: 'number', defaultValue: 2750799, description: 'Je kleiner die Zahl, desto weiter wandert der Mittelpunkt der Ansicht nach links.' }, + { name: 'y', label: 'Y - Koordinate', type: 'number', defaultValue: 1560004, description: 'Je kleiner die Zahl, desto weiter wandert der Mittelpunkt der Ansicht nach unten.' }, + { name: 'zoom', label: 'Zoom', type: 'number', defaultValue: 4.8, step: 0.01, description: 'Größerer Wert bedeutet weiter rangezoomt.' }, + { name: 'mode', label: 'Kartenhintergrund', type: 'dropdown', options: ['schematic', 'topographic'], defaultValue: 'schematic', description: 'Der Hintgergrund der LiveMap: schematic (MVG-Plan) oder topographic (Karte).' }, + ]; + + fields.forEach(field => { + // Create the input element + let inputElement; + if (field.type === 'dropdown') { + inputElement = document.createElement('ha-select'); + field.options.forEach(option => { + const optionElement = document.createElement('mwc-list-item'); + optionElement.value = option; + optionElement.innerText = option; + inputElement.appendChild(optionElement); + }); + inputElement.value = this.config.mode || field.defaultValue; + } else { + inputElement = document.createElement('ha-textfield'); + inputElement.type = field.type; + inputElement.step = field.step || "1"; + inputElement.value = this.config[field.name] || field.defaultValue; + } + + inputElement.label = field.label; + inputElement.configValue = field.name; + + // Event listener to update config on change + inputElement.addEventListener('change', (event) => { + const target = event.target; + this.config = { + ...this.config, + [target.configValue]: target.value + }; + this.dispatchEvent(new CustomEvent('config-changed', { detail: { config: this.config } })); + }); + + // Create description element + const description = document.createElement('span'); + description.innerText = field.description; + description.style.fontSize = "12px"; + description.style.color = "#888"; + description.style.marginBottom = "6px"; + + // Append elements + container.appendChild(inputElement); + container.appendChild(description); // Add description below input + }); + + this.appendChild(container); + } +} + +customElements.define("content-card-another-mvg-livemap", ContentAnotherMVGlivemap); +customElements.define("content-another-mvg-livemap-editor", ContentAnotherMVGlivemapEditor); + +// add the card to the list of custom cards for the card picker +window.customCards = window.customCards || []; // Create the list if it doesn't exist. +window.customCards.push({ + type: "content-card-another-mvg-livemap", + name: "AnotherMVG LiveMap", + preview: false, // Optional - defaults to false + description: "Mit dieser Karte kann man sich die MVG Live Map einbinden. Diese Karte ist für Panel (einzelne Karte) gedacht.", +}); From 130e7948862319b79a3323858b0babb42ce314b2 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 14 Nov 2024 13:14:32 +0100 Subject: [PATCH 38/58] Update const.py --- custom_components/another_mvg/const.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/custom_components/another_mvg/const.py b/custom_components/another_mvg/const.py index 6fa6eab..69d859b 100644 --- a/custom_components/another_mvg/const.py +++ b/custom_components/another_mvg/const.py @@ -52,4 +52,9 @@ class MVGException(Exception): "filename": "content-card-another-mvg-big.js", "version": "2.1.0-BETA-3", }, + { + "name": "Another MVG LiveMap Card", + "filename": "content-card-another-mvg-livemap.js", + "version": "2.1.0-BETA-3", + }, ] From 9ac15af88587354ec21e7c77ff87d2bfb4a3c1bf Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 14 Nov 2024 15:37:22 +0100 Subject: [PATCH 39/58] Update content-card-another-mvg-livemap.js From f2229fc7bd869b8fc8e8e08e2eae81924c37abdc Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 14 Nov 2024 15:37:48 +0100 Subject: [PATCH 40/58] Update content-card-another-mvg-livemap.js From 75336cd258469e9fbba1468426d57391886af776 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Thu, 14 Nov 2024 15:39:21 +0100 Subject: [PATCH 41/58] Update const.py --- custom_components/another_mvg/const.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/another_mvg/const.py b/custom_components/another_mvg/const.py index 69d859b..24cae53 100644 --- a/custom_components/another_mvg/const.py +++ b/custom_components/another_mvg/const.py @@ -45,16 +45,16 @@ class MVGException(Exception): { "name": "Another MVG Card", "filename": "content-card-another-mvg.js", - "version": "2.1.0-BETA-3", + "version": "2.1.0-BETA-4", }, { "name": "Another MVG Big Card", "filename": "content-card-another-mvg-big.js", - "version": "2.1.0-BETA-3", + "version": "2.1.0-BETA-4", }, { "name": "Another MVG LiveMap Card", "filename": "content-card-another-mvg-livemap.js", - "version": "2.1.0-BETA-3", + "version": "2.1.0-BETA-4", }, ] From be3bc2ead29d0c627d1d643812681144abdadb73 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Sun, 8 Dec 2024 18:23:54 +0100 Subject: [PATCH 42/58] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9138f53..e6caeba 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ Or use these steps: ⚠️ It may take a minute to create the entity -## Option 2: via ```configuration.yaml``` +## Option 2: via ```configuration.yaml``` (deprecated) * Configure the configuration.yaml [(see guide below)](#4-code-for-your-configurationyaml) * Check configuration.yaml with the check function under Dev-Tools * Restart HA again From 8cbd6c58523b4f27ac8f006d446c0146938f6622 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Sun, 8 Dec 2024 19:27:05 +0100 Subject: [PATCH 43/58] Update README.md --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e6caeba..6c54d60 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ 2. [Create a sensor for your stop / station](#2-create-a-sensor-for-your-stop--station) 2.1. [via GUI (recommended)](#option-1-via-gui-recommended) - 2.2. [via configuration.yaml](#option-2-via-configurationyaml) + 2.2. [via configuration.yaml](#option-2-via-configurationyaml) (deprecated) 3. [Adding a card to your dashboard](#3-adding-a-card-to-your-dashboard) @@ -127,7 +127,12 @@ entity: sensor.yourSensor ⚠️ If you get the error that ```custom:content-card-another-mvg``` doesnt exist, clear the frontend / browser cache. -# 4. Code for your configuration.yaml +# 4. Code for your configuration.yaml (deprecated) + +⚠️ Currently its still working, but it will be removed in one of the next versions. +All sensors from the configuration.yaml will be migrated automatically. +If you see the sensors in the GUI you can remove the code from the configuration.yaml. +There will be no more updates on this section in the documentation. ### Add the name of this integration From b00b900d9493a9c2264e0287fabdedf34652ec52 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Sun, 8 Dec 2024 19:29:13 +0100 Subject: [PATCH 44/58] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6c54d60..b3f4c33 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## v2.0.0 Now with GUI configuration (German and English) +## v2.1.0 YAML configuration deprecated - will be converted automatically to a "GUI-Sensor" # Another MVG From b4767e18fa549ba8d307cf370e29cb9eb7604bbc Mon Sep 17 00:00:00 2001 From: Nisbo Date: Sun, 8 Dec 2024 19:37:12 +0100 Subject: [PATCH 45/58] Update README.md --- README.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/README.md b/README.md index b3f4c33..0907703 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,36 @@ entity: sensor.yourSensor ⚠️ If you get the error that ```custom:content-card-another-mvg``` doesnt exist, clear the frontend / browser cache. + + + +- Add the map to your dashboard + +![grafik](https://github.com/user-attachments/assets/138f06bc-dc74-4dc6-b0ee-fbdc49af74e7) + +The card can be added and configured directly through the map selector, like other cards. +Simply go to your dashboard, click on "Add Card", search for "Another MVG", and select the card from the results. + +![grafik](https://github.com/user-attachments/assets/aac03dfb-9358-4787-a1f8-0923aeb1db1a) + +![grafik](https://github.com/user-attachments/assets/da13be9f-e8cf-461d-a907-7841b89bbc8a) + +That’s all. In the standard configuration, it shows the complete map. +If you want to zoom in, follow the instructions in the description. +This editor is currently only available in German because I have no clue how to add language support to the card. +If there is a real need, I can create an additional card for English users. + +If, for some reason, you are not able to find the card, try clearing your frontend and browser cache, or try configuring the card on your own. + +``` +type: custom:content-card-another-mvg-livemap +mode: schematic +x: "2750800" +y: "1560005" +zoom: "4.8" +``` + + # 4. Code for your configuration.yaml (deprecated) ⚠️ Currently its still working, but it will be removed in one of the next versions. From 852e4a2b824193e5c125ced9af9f26164f9137a0 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Sun, 8 Dec 2024 19:51:00 +0100 Subject: [PATCH 46/58] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0907703..4ada2ad 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,12 @@ 2. [Create a sensor for your stop / station](#2-create-a-sensor-for-your-stop--station) 2.1. [via GUI (recommended)](#option-1-via-gui-recommended) - 2.2. [via configuration.yaml](#option-2-via-configurationyaml) (deprecated) + 2.2. [via configuration.yaml](#option-2-via-configurationyaml-deprecated) (deprecated) 3. [Adding a card to your dashboard](#3-adding-a-card-to-your-dashboard) + 3.1. [Add the map to your dashboard](#31-add-the-map-to-your-dashboard) -4. [Code for your configuration.yaml](#4-code-for-your-configurationyaml) +4. [Code for your configuration.yaml](#4-code-for-your-configurationyaml-deprecated) (deprecated) 5. [Screenshots](#5-screenshots) @@ -130,7 +131,7 @@ entity: sensor.yourSensor -- Add the map to your dashboard +### 3.1 Add the map to your dashboard ![grafik](https://github.com/user-attachments/assets/138f06bc-dc74-4dc6-b0ee-fbdc49af74e7) From 685408328ba047fbaa8e06fcb3181f793dcd8a09 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Sun, 8 Dec 2024 20:42:11 +0100 Subject: [PATCH 47/58] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 4ada2ad..a5e290d 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ [![Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.](https://my.home-assistant.io/badges/hacs_repository.svg)](https://my.home-assistant.io/redirect/hacs_repository/?repository=another_mvg&owner=Nisbo) [![Open your Home Assistant instance and start setting up a new integration.](https://my.home-assistant.io/badges/config_flow_start.svg)](https://my.home-assistant.io/redirect/config_flow_start/?domain=another_mvg) +* go to ```Settings``` --> ```Devices and services``` --> add integration ```another mvg``` and follow the configuration flow + * create a manual card with this content: ``` type: custom:content-card-another-mvg From 4208f348822811fd8cd797a24ad754f0284f8638 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Mon, 9 Dec 2024 10:00:21 +0100 Subject: [PATCH 48/58] Update config_flow.py --- custom_components/another_mvg/config_flow.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/custom_components/another_mvg/config_flow.py b/custom_components/another_mvg/config_flow.py index 808ed25..a8ba9b0 100644 --- a/custom_components/another_mvg/config_flow.py +++ b/custom_components/another_mvg/config_flow.py @@ -27,6 +27,7 @@ CONF_ALERT_FOR, CONF_SHOW_CLOCK, CONF_DEPARTURE_FORMAT, + CONF_INCREASED_LIMIT, DEFAULT_ONLYLINE, DEFAULT_HIDEDESTINATION, DEFAULT_ONLYDESTINATION, @@ -39,6 +40,7 @@ DEFAULT_ALERT_FOR, DEFAULT_SHOW_CLOCK, DEFAULT_DEPARTURE_FORMAT, + DEFAULT_INCREASED_LIMIT, ) _LOGGER = logging.getLogger(__name__) @@ -68,6 +70,7 @@ async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResu CONF_TRANSPORTTYPES: import_data.get(CONF_TRANSPORTTYPES, DEFAULT_CONF_TRANSPORTTYPES).split(','), CONF_GLOBALID2: import_data.get(CONF_GLOBALID2, DEFAULT_CONF_GLOBALID2), CONF_HIDENAME: import_data.get(CONF_HIDENAME, DEFAULT_HIDENAME), + CONF_INCREASED_LIMIT: import_data.get(CONF_INCREASED_LIMIT, DEFAULT_INCREASED_LIMIT), CONF_TIMEZONE_FROM: import_data.get(CONF_TIMEZONE_FROM, DEFAULT_TIMEZONE_FROM), CONF_TIMEZONE_TO: import_data.get(CONF_TIMEZONE_TO, DEFAULT_TIMEZONE_TO), CONF_ALERT_FOR: import_data.get(CONF_ALERT_FOR, DEFAULT_ALERT_FOR), @@ -131,6 +134,9 @@ async def async_step_user(self, user_input=None): if CONF_HIDENAME in advanced_options: user_input[CONF_HIDENAME] = advanced_options[CONF_HIDENAME] + if CONF_INCREASED_LIMIT in advanced_options: + user_input[CONF_INCREASED_LIMIT] = advanced_options[CONF_INCREASED_LIMIT] + if CONF_ONLYLINE in filter_options: user_input[CONF_ONLYLINE] = filter_options[CONF_ONLYLINE] @@ -267,6 +273,7 @@ def _user_config_schema(self, stations, station_name): { vol.Optional(CONF_SHOW_CLOCK, default=DEFAULT_SHOW_CLOCK): bool, vol.Optional(CONF_HIDENAME, default=DEFAULT_HIDENAME): bool, + vol.Optional(CONF_INCREASED_LIMIT, default=DEFAULT_INCREASED_LIMIT): int, vol.Optional(CONF_GLOBALID2, default=DEFAULT_CONF_GLOBALID2): str, vol.Optional(CONF_TIMEZONE_FROM, default=DEFAULT_TIMEZONE_FROM): str, vol.Optional(CONF_TIMEZONE_TO, default=DEFAULT_TIMEZONE_TO): str, @@ -469,6 +476,9 @@ async def async_step_edit(self, user_input=None): if CONF_HIDENAME in advanced_options: user_input[CONF_HIDENAME] = advanced_options[CONF_HIDENAME] + if CONF_INCREASED_LIMIT in advanced_options: + user_input[CONF_INCREASED_LIMIT] = advanced_options[CONF_INCREASED_LIMIT] + if CONF_ONLYLINE in filter_options: user_input[CONF_ONLYLINE] = filter_options[CONF_ONLYLINE] @@ -547,6 +557,7 @@ async def async_step_edit(self, user_input=None): { vol.Optional(CONF_SHOW_CLOCK, description={"suggested_value": current_data.get(CONF_SHOW_CLOCK, "")}): bool, vol.Optional(CONF_HIDENAME, description={"suggested_value": current_data.get(CONF_HIDENAME, "")}): bool, + vol.Optional(CONF_INCREASED_LIMIT, description={"suggested_value": current_data.get(CONF_INCREASED_LIMIT, DEFAULT_INCREASED_LIMIT)}): int, vol.Optional(CONF_GLOBALID2, description={"suggested_value": current_data.get(CONF_GLOBALID2, "")}): str, vol.Optional(CONF_TIMEZONE_FROM, description={"suggested_value": current_data.get(CONF_TIMEZONE_FROM, "")}): str, vol.Optional(CONF_TIMEZONE_TO, description={"suggested_value": current_data.get(CONF_TIMEZONE_TO, "")}): str, From e63289d9e21f022f317cb350f3ea5c3200c01952 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Mon, 9 Dec 2024 10:01:25 +0100 Subject: [PATCH 49/58] Update const.py --- custom_components/another_mvg/const.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/custom_components/another_mvg/const.py b/custom_components/another_mvg/const.py index 24cae53..33c2451 100644 --- a/custom_components/another_mvg/const.py +++ b/custom_components/another_mvg/const.py @@ -8,8 +8,7 @@ class MVGException(Exception): DOMAIN = "another_mvg" # name of the integration, dont change SCAN_INTERVAL = timedelta(seconds=60) # updateinterval in seconds -#URL = "https://www.mvg.de/api/fib/v2/departure?globalId={}&limit=80&offsetInMinutes=0&transportTypes={}" # the old API URL -URL = "https://www.mvg.de/api/bgw-pt/v3/departures?globalId={}&limit=80&offsetInMinutes=0&transportTypes={}" +URL = "https://www.mvg.de/api/bgw-pt/v3/departures?globalId={}&limit=80&offsetInMinutes={}&transportTypes={}" USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3" CONF_GLOBALID = "globalid" # required @@ -26,6 +25,7 @@ class MVGException(Exception): CONF_ALERT_FOR = "alert_for" # optional CONF_SHOW_CLOCK = "show_clock" # optional CONF_DEPARTURE_FORMAT = "departure_format" # required +CONF_INCREASED_LIMIT = "increased_limit" # optional DEFAULT_HIDEDESTINATION = "" DEFAULT_ONLYDESTINATION = "" @@ -39,22 +39,23 @@ class MVGException(Exception): DEFAULT_ALERT_FOR = "" DEFAULT_SHOW_CLOCK = False DEFAULT_DEPARTURE_FORMAT = "1" +DEFAULT_INCREASED_LIMIT = 0 URL_BASE = "/another_mvg" ANOTHER_MVG_CARDS = [ { "name": "Another MVG Card", "filename": "content-card-another-mvg.js", - "version": "2.1.0-BETA-4", + "version": "2.1.0-BETA-5", }, { "name": "Another MVG Big Card", "filename": "content-card-another-mvg-big.js", - "version": "2.1.0-BETA-4", + "version": "2.1.0-BETA-5", }, { "name": "Another MVG LiveMap Card", "filename": "content-card-another-mvg-livemap.js", - "version": "2.1.0-BETA-4", + "version": "2.1.0-BETA-5", }, ] From 1b96d31feece4abf841f7b4882a22c16c29292ab Mon Sep 17 00:00:00 2001 From: Nisbo Date: Mon, 9 Dec 2024 10:02:13 +0100 Subject: [PATCH 50/58] Update manifest.json --- custom_components/another_mvg/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/another_mvg/manifest.json b/custom_components/another_mvg/manifest.json index 6bcb4d0..000179b 100644 --- a/custom_components/another_mvg/manifest.json +++ b/custom_components/another_mvg/manifest.json @@ -1,7 +1,7 @@ { "domain": "another_mvg", "name": "Another MVG", - "version": "2.1.0-BETA.4", + "version": "2.1.0-BETA.5", "config_flow": true, "documentation": "https://github.com/Nisbo/another_mvg", "issue_tracker": "https://github.com/Nisbo/another_mvg/issues", From df58428fea420846344acace24711aabf0263368 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Mon, 9 Dec 2024 10:02:39 +0100 Subject: [PATCH 51/58] Update sensor.py --- custom_components/another_mvg/sensor.py | 54 +++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/custom_components/another_mvg/sensor.py b/custom_components/another_mvg/sensor.py index 3179dfb..b7f3124 100644 --- a/custom_components/another_mvg/sensor.py +++ b/custom_components/another_mvg/sensor.py @@ -35,6 +35,7 @@ CONF_TRANSPORTTYPES, CONF_SHOW_CLOCK, CONF_DEPARTURE_FORMAT, + CONF_INCREASED_LIMIT, URL, USER_AGENT, MVGException, @@ -50,6 +51,7 @@ DEFAULT_ALERT_FOR, DEFAULT_SHOW_CLOCK, DEFAULT_DEPARTURE_FORMAT, + DEFAULT_INCREASED_LIMIT, ) # integration imports end @@ -76,6 +78,7 @@ vol.Optional(CONF_TIMEZONE_TO, default=DEFAULT_TIMEZONE_TO): cv.string, vol.Optional(CONF_ALERT_FOR, default=DEFAULT_ALERT_FOR): cv.string, vol.Optional(CONF_SHOW_CLOCK, default=DEFAULT_SHOW_CLOCK): cv.boolean, + vol.Optional(CONF_INCREASED_LIMIT, default=DEFAULT_INCREASED_LIMIT): cv.positive_int, } ) @@ -191,6 +194,8 @@ def __init__(self, hass: HomeAssistant, config) -> None: self._alert_for = config_data.get(CONF_ALERT_FOR) self._lateConnections = "" self._dataOutdated = "" + self._offsetInMinutes = 0 + self._increased_limit = config_data.get(CONF_INCREASED_LIMIT, DEFAULT_INCREASED_LIMIT) self._custom_attributes = { "config": { "name": self._name, @@ -302,8 +307,14 @@ def get_departures(self) -> str: # 1st API call for globalid1 try: data = self.get_api_for_globalid( - self._name, self._globalid, self._transporttypes + self._name, self._globalid, self._offsetInMinutes, self._transporttypes ) + + # If data is empty, check if there are results for the next day + if not data or len(data) < (self._limit + self._increased_limit): + data = self.fetch_additional_data_for_next_day(data, self._name, self._globalid, self._transporttypes) + + except MVGException as ex: # return the old departures self._custom_attributes["departures"] and set a variable with the info that the departures are outdated # because returning an ex leads to an error: Unable to serialize to JSON. Bad data found @@ -333,8 +344,13 @@ def get_departures(self) -> str: time.sleep(1) try: data2 = self.get_api_for_globalid( - self._name, self._globalid2, self._transporttypes + self._name, self._globalid2, self._offsetInMinutes, self._transporttypes ) + + # If data2 is empty, check if there are results for the next day + if not data2 or len(data2) < (self._limit + self._increased_limit): # Überprüft, ob die Liste leer ist + data2 = self.fetch_additional_data_for_next_day(data2, self._name, self._globalid2, self._transporttypes) + except MVGException as ex: # return the old departures self._custom_attributes["departures"] and set a variable with the info that the departures are outdated # because returning an ex leads to an error: Unable to serialize to JSON. Bad data found @@ -387,6 +403,36 @@ def get_departures(self) -> str: self._dataOutdated = "" return self.pre_process_output(sorted_data) + + + + def fetch_additional_data_for_next_day(self, data, name, globalid, transporttypes): + # wait 1 second because of 509 error + time.sleep(1) + + # calculate minutes till midnight + now = datetime.now() + midnight = (now + timedelta(days=1)).replace(hour=0, minute=0, second=0, microsecond=0) + seconds_to_midnight = (midnight - now).total_seconds() + minutes_to_midnight = int((seconds_to_midnight + 59) // 60) # Rundet auf die nächste volle Minute + + _LOGGER.warning( + "AnotherMVG: There were no (or not enough) results for this day, trying to get results for the next day. Current time is %s. Minutes to midnight: %s", + now.strftime("%H:%M:%S"), + minutes_to_midnight, + ) + + # get additional data from API + additional_data = self.get_api_for_globalid(name, globalid, minutes_to_midnight, transporttypes) + + # merge it + if additional_data: + data.extend(additional_data) + + return data + + + def pre_process_output(self, data: dict) -> dict: """Preformat necessary values into list of Departure.""" @@ -497,10 +543,10 @@ def pre_process_output(self, data: dict) -> dict: return departures def get_api_for_globalid( - self, name: str, global_id: str, transport_types: str + self, name: str, global_id: str, offsetInMinutes: int, transport_types: str ) -> dict: """Get departure data from api.""" - url = URL.format(global_id, transport_types) + url = URL.format(global_id, offsetInMinutes, transport_types) headers = {} headers["User-Agent"] = USER_AGENT From 7aa4a6e427c20fb05cef0d79e71d90d2414289f0 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Mon, 9 Dec 2024 10:05:18 +0100 Subject: [PATCH 52/58] Update de.json --- custom_components/another_mvg/translations/de.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/custom_components/another_mvg/translations/de.json b/custom_components/another_mvg/translations/de.json index 8174803..a167b18 100644 --- a/custom_components/another_mvg/translations/de.json +++ b/custom_components/another_mvg/translations/de.json @@ -11,6 +11,7 @@ "data": { "hidename": "Den Namen der Karte (inkl. Uhr) ausblenden", "show_clock": "Uhr oben rechts anzeigen", + "increased_limit": "Erweitertes Limit", "globalid2": "Global ID 2", "timezone_from": "Zeitzone von", "timezone_to": "Zeitzone nach", @@ -18,6 +19,7 @@ }, "data_description": { "hidename": "Wenn Sie den Namen der Karte nicht sehen möchten, aktivieren Sie diese Option.", + "increased_limit": "Diese Option dient dazu, fehlende Einträge nach Mitternacht zu korrigieren, falls viele Filter verwendet werden. Nutzen Sie diese Option nur, wenn abends weniger Einträge als gewünscht angezeigt werden. Tasten Sie sich langsam in 10er-Schritten vor, da diese Option zu unnötigen zusätzlichen API-Abfragen führen kann.", "globalid2": "Wenn Sie zwei Stationen nah beieinander (oder weit voneinander entfernt) haben, wie einen Bahnhof und eine Bushaltestelle, können Sie beide in einer Karte kombinieren. Beachten Sie, dass Sie die Transportarten für beide Stationen auswählen müssen. Die Verwendung dieser Funktion kann zu Problemen führen, da es innerhalb einer Sekunde zwei API-Aufrufe gibt, und es ist möglich, dass die API den zweiten Aufruf blockiert. Wenn Sie diese Option nur für eine Karte verwenden, sollte es kein Problem sein, aber wenn Sie es für mehr verwenden, steigt das Risiko, dass die API die Anfrage blockiert. Wenn Sie die Global ID 2 nicht kennen, können Sie diese später unter **'KONFIGURIEREN'** über die Option **'Zusätzliche Station (Global ID 2) - suchen und speichern'** auswählen. Alternativ können Sie die Global ID für Ihre Station auch hier finden: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Ersetzen Sie dafür einfach den Namen in der Abfrage. Sie müssen die Global ID im Format **de:09162:2** eingeben.", "timezone_from": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", "timezone_to": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", @@ -87,6 +89,7 @@ "data": { "hidename": "Den Namen der Karte (inkl. Uhr) ausblenden", "show_clock": "Uhr oben rechts anzeigen", + "increased_limit": "Erweitertes Limit", "globalid2": "Global ID 2", "timezone_from": "Zeitzone von", "timezone_to": "Zeitzone nach", @@ -94,6 +97,7 @@ }, "data_description": { "hidename": "Wenn Sie den Namen der Karte nicht sehen möchten, aktivieren Sie diese Option.", + "increased_limit": "Diese Option dient dazu, fehlende Einträge nach Mitternacht zu korrigieren, falls viele Filter verwendet werden. Nutzen Sie diese Option nur, wenn abends weniger Einträge als gewünscht angezeigt werden. Tasten Sie sich langsam in 10er-Schritten vor, da diese Option zu unnötigen zusätzlichen API-Abfragen führen kann.", "globalid2": "Wenn Sie zwei Stationen nah beieinander (oder weit voneinander entfernt) haben, wie einen Bahnhof und eine Bushaltestelle, können Sie beide in einer Karte kombinieren. Beachten Sie, dass Sie die Transportarten für beide Stationen auswählen müssen. Die Verwendung dieser Funktion kann zu Problemen führen, da es innerhalb einer Sekunde zwei API-Aufrufe gibt, und es ist möglich, dass die API den zweiten Aufruf blockiert. Wenn Sie diese Option nur für eine Karte verwenden, sollte es kein Problem sein, aber wenn Sie es für mehr verwenden, steigt das Risiko, dass die API die Anfrage blockiert. Wenn Sie die Global ID 2 ändern möchten und die ID nicht kennen, schließen Sie diese Eingabemaske und wählen Sie unter **'KONFIGURIEREN'** die Option **'Zusätzliche Station (Global ID 2) - suchen und speichern'** aus. Alternativ können Sie die Global ID für Ihre Station auch hier finden: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Ersetzen Sie dafür einfach den Namen in der Abfrage. Sie müssen die Global ID im Format **de:09162:2** eingeben.", "timezone_from": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", "timezone_to": "Normalerweise sollte dies nicht geändert werden, es sei denn, Ihr Server läuft in einer anderen Zeitzone, die Zeiten werden nicht korrekt angezeigt oder Sie möchten die Abfahrten in einer anderen Zeitzone sehen. Geben Sie die Zeitzone im Format wie Europe/Berlin oder UTC ein. Lassen Sie das Feld nicht leer.", From 41ade640c3a793ffba357fd39ebf6bb0c8418ce8 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Mon, 9 Dec 2024 10:05:45 +0100 Subject: [PATCH 53/58] Update en.json --- custom_components/another_mvg/translations/en.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/custom_components/another_mvg/translations/en.json b/custom_components/another_mvg/translations/en.json index bb0789d..8c89b28 100644 --- a/custom_components/another_mvg/translations/en.json +++ b/custom_components/another_mvg/translations/en.json @@ -11,6 +11,7 @@ "data": { "hidename": "Hide the name of the card (incl. clock)", "show_clock": "Show a clock on the top right", + "increased_limit": "Increased Limit", "globalid2": "Global ID 2", "timezone_from": "Timezone From", "timezone_to": "Timezone To", @@ -18,6 +19,7 @@ }, "data_description": { "hidename": "If you don't want to see the name of the card, enable this option.", + "increased_limit": "This option is intended to correct missing entries after midnight if many filters are used. Use this option only if fewer entries than desired are displayed in the evening. Adjust slowly in steps of 10, as this option can lead to unnecessary additional API requests.", "globalid2": "If you have two stations close to each other (or far apart), such as a train station and a bus stop, you can combine them into a single card. Note that you must select the transportation types for both stations. Using this feature may lead to issues, as it triggers two API calls within one second, and it’s possible that the API may block the second call. If you use this option for only one card, it should not be a problem, but using it for more cards increases the risk of the API blocking the request. If you do not know the Global ID 2, you can later select it under **'CONFIGURE'** using the option **'Additional Station (Global ID 2) - search and save'**. Alternatively, you can find the Global ID for your station here: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Simply replace the name in the query. You need to enter the Global ID in the format **de:09162:2**.", "timezone_from": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", "timezone_to": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", @@ -87,6 +89,7 @@ "data": { "hidename": "Hide the name of the card (incl. clock)", "show_clock": "Show a clock on the top right", + "increased_limit": "Increased Limit", "globalid2": "Global ID 2", "timezone_from": "Timezone From", "timezone_to": "Timezone To", @@ -94,6 +97,7 @@ }, "data_description": { "hidename": "If you don't want to see the name of the card, enable this option.", + "increased_limit": "This option is intended to correct missing entries after midnight if many filters are used. Use this option only if fewer entries than desired are displayed in the evening. Adjust slowly in steps of 10, as this option can lead to unnecessary additional API requests.", "globalid2": "If you have two stations close to each other (or far apart), such as a train station and a bus stop, you can combine them into a single card. Note that you must select the transportation modes for both stations. Using this feature may lead to issues, as it triggers two API calls within one second, and it’s possible that the API may block the second call. If you use this option for only one card, it should not be a problem, but using it for more cards increases the risk of the API blocking the request. If you wish to change the Global ID 2 and do not know the ID, close this input form and select the option **'Additional Station (Global ID 2) - search and save'** under **'CONFIGURE'**. Alternatively, you can find the Global ID for your station here: https://www.mvg.de/api/bgw-pt/v3/locations?query=Pasing. Simply replace the name in the query. You need to enter the Global ID in the format **de:09162:2**.", "timezone_from": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", "timezone_to": "Normally, this should not be changed unless your server is running in a different time zone, the times are not displayed correctly, or you want to see the departures in a different time zone. Enter the time zone in a format like Europe/Berlin or UTC. Do not leave the field empty.", From 465427ebf471f49b74a010c1450de31611c14aa9 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Mon, 9 Dec 2024 10:07:09 +0100 Subject: [PATCH 54/58] Update content-card-another-mvg-livemap.js From a1bd534e3748dff959867f3b5204e6fda5667e8d Mon Sep 17 00:00:00 2001 From: Nisbo Date: Tue, 17 Dec 2024 07:34:27 +0100 Subject: [PATCH 55/58] Update sensor.py --- custom_components/another_mvg/sensor.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/custom_components/another_mvg/sensor.py b/custom_components/another_mvg/sensor.py index b7f3124..4359cb7 100644 --- a/custom_components/another_mvg/sensor.py +++ b/custom_components/another_mvg/sensor.py @@ -416,11 +416,22 @@ def fetch_additional_data_for_next_day(self, data, name, globalid, transporttype seconds_to_midnight = (midnight - now).total_seconds() minutes_to_midnight = int((seconds_to_midnight + 59) // 60) # Rundet auf die nächste volle Minute - _LOGGER.warning( - "AnotherMVG: There were no (or not enough) results for this day, trying to get results for the next day. Current time is %s. Minutes to midnight: %s", - now.strftime("%H:%M:%S"), - minutes_to_midnight, - ) + if data is None: + _LOGGER.debug( + "AnotherMVG: For %s, no data was returned for this day. Current time is %s. Minutes to midnight: %s", + name, + now.strftime("%H:%M:%S"), + minutes_to_midnight, + ) + data = [] # Initialise `data` as empty list + else: + _LOGGER.debug( + "AnotherMVG: For %s there were only %s results for this day, trying to get results for the next day. Current time is %s. Minutes to midnight: %s", + name, + len(data), + now.strftime("%H:%M:%S"), + minutes_to_midnight, + ) # get additional data from API additional_data = self.get_api_for_globalid(name, globalid, minutes_to_midnight, transporttypes) From 14048891523bbeaa6ffaecfcb14ce7a137b82b81 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Tue, 17 Dec 2024 07:36:14 +0100 Subject: [PATCH 56/58] Fixed HA deprecation warning for explecit config_entry --- custom_components/another_mvg/config_flow.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/custom_components/another_mvg/config_flow.py b/custom_components/another_mvg/config_flow.py index a8ba9b0..64edecb 100644 --- a/custom_components/another_mvg/config_flow.py +++ b/custom_components/another_mvg/config_flow.py @@ -290,7 +290,7 @@ class AnotherMVGOptionsFlowHandler(config_entries.OptionsFlow): def __init__(self, config_entry: config_entries.ConfigEntry) -> None: """Initialize Another MVG options flow.""" - self.config_entry = config_entry + self._config_entry = config_entry self.options = dict(config_entry.options) async def async_step_init(self, user_input=None): @@ -350,27 +350,27 @@ async def async_step_globalid2search(self, user_input=None): async def async_step_globalid2save(self, user_input=None): if user_input is not None: - existing_data = self.config_entry.data + existing_data = self._config_entry.data updated_data = {**existing_data, **user_input} self.hass.config_entries.async_update_entry( - self.config_entry, data=updated_data + self._config_entry, data=updated_data ) - await self.hass.config_entries.async_reload(self.config_entry.entry_id) + await self.hass.config_entries.async_reload(self._config_entry.entry_id) return self.async_create_entry(title="", data={}) async def async_step_globalid1save(self, user_input=None): if user_input is not None: - existing_data = self.config_entry.data + existing_data = self._config_entry.data updated_data = {**existing_data, **user_input} self.hass.config_entries.async_update_entry( - self.config_entry, data=updated_data + self._config_entry, data=updated_data ) - await self.hass.config_entries.async_reload(self.config_entry.entry_id) + await self.hass.config_entries.async_reload(self._config_entry.entry_id) return self.async_create_entry(title="", data={}) @@ -502,16 +502,16 @@ async def async_step_edit(self, user_input=None): # Save the updated data self.hass.config_entries.async_update_entry( - self.config_entry, data=user_input + self._config_entry, data=user_input ) # Reload the integration to apply changes - await self.hass.config_entries.async_reload(self.config_entry.entry_id) + await self.hass.config_entries.async_reload(self._config_entry.entry_id) return self.async_create_entry(title="", data={}) # Prepare the default values based on current configuration data - current_data = self.config_entry.data + current_data = self._config_entry.data transport_types = DEFAULT_CONF_TRANSPORTTYPES.split(',') selected_transport_types = current_data.get(CONF_TRANSPORTTYPES, '').split(',') From 169a94e7126be69cdbcd6ead80296873ce36dc06 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Tue, 17 Dec 2024 07:40:40 +0100 Subject: [PATCH 57/58] Update const.py --- custom_components/another_mvg/const.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/custom_components/another_mvg/const.py b/custom_components/another_mvg/const.py index 33c2451..e1233bb 100644 --- a/custom_components/another_mvg/const.py +++ b/custom_components/another_mvg/const.py @@ -46,16 +46,16 @@ class MVGException(Exception): { "name": "Another MVG Card", "filename": "content-card-another-mvg.js", - "version": "2.1.0-BETA-5", + "version": "2.1.0", }, { "name": "Another MVG Big Card", "filename": "content-card-another-mvg-big.js", - "version": "2.1.0-BETA-5", + "version": "2.1.0", }, { "name": "Another MVG LiveMap Card", "filename": "content-card-another-mvg-livemap.js", - "version": "2.1.0-BETA-5", + "version": "2.1.0", }, ] From 9ad39f5004db2e08b04e1bdb75f1fdad10fe91a0 Mon Sep 17 00:00:00 2001 From: Nisbo Date: Tue, 17 Dec 2024 07:40:59 +0100 Subject: [PATCH 58/58] Update manifest.json --- custom_components/another_mvg/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/another_mvg/manifest.json b/custom_components/another_mvg/manifest.json index 000179b..eccc0bc 100644 --- a/custom_components/another_mvg/manifest.json +++ b/custom_components/another_mvg/manifest.json @@ -1,7 +1,7 @@ { "domain": "another_mvg", "name": "Another MVG", - "version": "2.1.0-BETA.5", + "version": "2.1.0", "config_flow": true, "documentation": "https://github.com/Nisbo/another_mvg", "issue_tracker": "https://github.com/Nisbo/another_mvg/issues",