Compare commits

...
6 Commits
Author SHA1 Message Date
Dielee c6ddd71021 Bump addon version 2024-05-28 08:26:38 +02:00
Dielee 1f0612ca4a Try to fix not saveable OTP Code 2024-05-28 08:26:18 +02:00
Dielee 6306c9a4b3 Let token survive addon updates 2024-05-27 14:16:07 +02:00
Dielee 8bd0388690 Extend waiting time for otp tp 120 seconds 2024-05-27 14:05:19 +02:00
Linus DietzandGitHub 245dd82c82 Update README.md 2024-05-27 14:02:39 +02:00
Dielee 8e471d8eb0 Fix security alert 2024-05-27 08:27:25 +02:00
7 changed files with 45 additions and 22 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ The following steps are required for authentication in exactly this order:
```etc ...``` ```etc ...```
4. Now, open your mailbox and copy your OTP Code 4. Now, open your mailbox and copy your OTP Code
5. Open HomeAssistant and search for the entity ID ```text.volvo_otp``` 5. Open HomeAssistant and search for the entity ID ```text.volvo_otp```
6. Paste your OTP into the text entity and press Enter 6. Paste your OTP into the text entity and **<ins>press Enter</ins>**
7. If everything has worked, your addon is now authenticated. In the future, OTP authentication only needs to be done when updating, not when restarting the container. 7. If everything has worked, your addon is now authenticated. In the future, OTP authentication only needs to be done when updating, not when restarting the container.
## Setup ## Setup
+1 -1
View File
@@ -1,4 +1,4 @@
requests~=2.31.0 requests~=2.32.0
dynaconf~=3.1.12 dynaconf~=3.1.12
paho-mqtt~=1.6.1 paho-mqtt~=1.6.1
Babel~=2.12.1 Babel~=2.12.1
+1 -1
View File
@@ -1,6 +1,6 @@
name: "Volvo2Mqtt" name: "Volvo2Mqtt"
description: "Volvo AAOS MQTT bridge" description: "Volvo AAOS MQTT bridge"
version: "1.9.0" version: "1.9.2"
slug: "volvo2mqtt" slug: "volvo2mqtt"
init: false init: false
url: "https://github.com/Dielee/volvo2mqtt" url: "https://github.com/Dielee/volvo2mqtt"
+2 -2
View File
@@ -1,6 +1,6 @@
from config import settings from config import settings
VERSION = "v1.9.0" VERSION = "v1.9.2"
OAUTH_TOKEN_URL = "https://volvoid.eu.volvocars.com/as/token.oauth2" OAUTH_TOKEN_URL = "https://volvoid.eu.volvocars.com/as/token.oauth2"
OAUTH_AUTH_URL = "https://volvoid.eu.volvocars.com/as/authorization.oauth2" OAUTH_AUTH_URL = "https://volvoid.eu.volvocars.com/as/authorization.oauth2"
@@ -139,5 +139,5 @@ supported_entities = [
] ]
old_entity_ids = ["months_to_service", "service_warning_trigger", "distance_to_empty"] old_entity_ids = ["months_to_service", "service_warning_trigger", "distance_to_empty"]
otp_max_loops = 15 otp_max_loops = 24
otp_mqtt_topic = "volvoAAOS2mqtt/otp_code" otp_mqtt_topic = "volvoAAOS2mqtt/otp_code"
+19 -7
View File
@@ -47,25 +47,37 @@ def connect():
def create_otp_input(): def create_otp_input():
state_topic = otp_mqtt_topic + "/state"
config = { config = {
"name": "Volvo OTP", "name": "Volvo OTP",
"object_id": f"volvo_otp", "object_id": f"volvo_otp",
"schema": "state", "schema": "state",
"command_topic": otp_mqtt_topic, "command_topic": otp_mqtt_topic,
"unique_id": f"volvoAAOS2mqtt_otp", "state_topic": state_topic,
"pattern": "\d{6}", "unique_id": "volvoAAOS2mqtt_otp",
"icon": "mdi:two-factor-authentication" "pattern": r"\d{6}",
"icon": "mdi:two-factor-authentication",
"mode": "text"
} }
mqtt_client.publish( mqtt_client.publish(
f"homeassistant/text/volvoAAOS2mqtt/volvo_otp/config", "homeassistant/text/volvoAAOS2mqtt/volvo_otp/config",
json.dumps(config), json.dumps(config),
retain=True retain=True
) )
def delete_otp_input(): mqtt_client.publish(
topic = "homeassistant/text/volvoAAOS2mqtt/volvo_otp/config" state_topic,
mqtt_client.publish(topic, payload="", retain=True) "000000",
retain=True
)
def set_otp_state():
mqtt_client.publish(
otp_mqtt_topic + "/state",
otp_code,
retain=True
)
def send_car_images(vin, data, device): def send_car_images(vin, data, device):
+13 -5
View File
@@ -42,8 +42,16 @@ def get_volvo_app_version():
else: else:
return "5.37.0" return "5.37.0"
def save_to_json(data): def get_token_path():
with open('.token', 'w', encoding='utf-8') as f: token_path = ".token"
if os.environ.get("IS_HA_ADDON"):
check_existing_folder("/addons/volvo2mqtt/token/")
token_path = "/addons/volvo2mqtt/token/.token"
return token_path
def save_to_json(data, token_path):
with open(token_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4) json.dump(data, f, ensure_ascii=False, indent=4)
def get_icon_between(icon_list, state): def get_icon_between(icon_list, state):
@@ -57,7 +65,7 @@ def get_icon_between(icon_list, state):
def setup_logging(): def setup_logging():
log_location = "volvo2mqtt.log" log_location = "volvo2mqtt.log"
if os.environ.get("IS_HA_ADDON"): if os.environ.get("IS_HA_ADDON"):
check_existing_folder() check_existing_folder("/addons/volvo2mqtt/log/")
log_location = "/addons/volvo2mqtt/log/volvo2mqtt.log" log_location = "/addons/volvo2mqtt/log/volvo2mqtt.log"
logging.Formatter.converter = lambda *args: datetime.now(tz=TZ).timetuple() logging.Formatter.converter = lambda *args: datetime.now(tz=TZ).timetuple()
@@ -90,8 +98,8 @@ def setup_logging():
logger.setLevel(logging.ERROR) logger.setLevel(logging.ERROR)
def check_existing_folder(): def check_existing_folder(path):
Path("/addons/volvo2mqtt/log/").mkdir(parents=True, exist_ok=True) Path(path).mkdir(parents=True, exist_ok=True)
def keys_exists(element, *keys): def keys_exists(element, *keys):
+8 -5
View File
@@ -35,9 +35,11 @@ backend_status = ""
def authorize(renew_tokenfile=False): def authorize(renew_tokenfile=False):
global refresh_token global refresh_token
if os.path.isfile(".token") and not renew_tokenfile:
token_path = util.get_token_path()
if os.path.isfile(token_path) and not renew_tokenfile:
logging.info("Using login from token file") logging.info("Using login from token file")
f = open('.token') f = open(token_path)
data = json.load(f) data = json.load(f)
refresh_token = data["refresh_token"] refresh_token = data["refresh_token"]
refresh_auth() refresh_auth()
@@ -91,7 +93,7 @@ def authorize(renew_tokenfile=False):
token_expires_at = datetime.now(util.TZ) + timedelta(seconds=(token_data["expires_in"] - 30)) token_expires_at = datetime.now(util.TZ) + timedelta(seconds=(token_data["expires_in"] - 30))
refresh_token = token_data["refresh_token"] refresh_token = token_data["refresh_token"]
util.save_to_json(token_data) util.save_to_json(token_data, token_path)
else: else:
message = auth.json() message = auth.json()
raise Exception(message["details"][0]["userMessage"]) raise Exception(message["details"][0]["userMessage"])
@@ -154,7 +156,7 @@ def send_otp(auth_session, data):
if not mqtt.otp_code: if not mqtt.otp_code:
raise Exception ("No OTP found, exting...") raise Exception ("No OTP found, exting...")
mqtt.delete_otp_input() mqtt.set_otp_state()
auth = auth_session.post(next_url, data=json.dumps(body)) auth = auth_session.post(next_url, data=json.dumps(body))
if auth.status_code == 200: if auth.status_code == 200:
return auth.json() return auth.json()
@@ -184,8 +186,9 @@ def refresh_auth():
return None return None
if auth.status_code == 200: if auth.status_code == 200:
token_path = util.get_token_path()
data = auth.json() data = auth.json()
util.save_to_json(data) util.save_to_json(data, token_path)
session.headers.update({"authorization": "Bearer " + data["access_token"]}) session.headers.update({"authorization": "Bearer " + data["access_token"]})
global token_expires_at global token_expires_at