Repository: ReneNulschDE/mbapi2020 Branch: master Commit: 6b8f1844e7c1 Files: 94 Total size: 1.1 MB Directory structure: gitextract_fszsclw1/ ├── .devcontainer.json ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ └── config.yml │ ├── dependabot.yaml │ └── workflows/ │ ├── HACS_validate.yaml │ ├── hassfest.yaml │ └── publish.yaml ├── .gitignore ├── .pre-commit-config.yaml ├── .yamllint.yaml ├── CLAUDE.md ├── LICENSE ├── README.md ├── SECURITY.md ├── custom_components/ │ └── mbapi2020/ │ ├── __init__.py │ ├── binary_sensor.py │ ├── button.py │ ├── car.py │ ├── client.py │ ├── config_flow.py │ ├── const.py │ ├── coordinator.py │ ├── device_tracker.py │ ├── diagnostics.py │ ├── errors.py │ ├── helper.py │ ├── icons.json │ ├── lock.py │ ├── manifest.json │ ├── oauth.py │ ├── proto/ │ │ ├── acp_pb2.py │ │ ├── client_pb2.py │ │ ├── cluster_pb2.py │ │ ├── eventpush_pb2.py │ │ ├── gogo_pb2.py │ │ ├── protos_pb2.py │ │ ├── service_activation_pb2.py │ │ ├── user_events_pb2.py │ │ ├── vehicle_commands_pb2.py │ │ ├── vehicle_events_pb2.py │ │ ├── vehicleapi_pb2.py │ │ └── vin_events_pb2.py │ ├── repairs.py │ ├── sensor.py │ ├── services.py │ ├── services.yaml │ ├── switch.py │ ├── system_health.py │ ├── translations/ │ │ ├── cs.json │ │ ├── da.json │ │ ├── de.json │ │ ├── en.json │ │ ├── es.json │ │ ├── fi.json │ │ ├── fr.json │ │ ├── he.json │ │ ├── it.json │ │ ├── nb_NO.json │ │ ├── nl.json │ │ ├── pl.json │ │ ├── pt.json │ │ ├── sv.json │ │ └── ta.json │ ├── webapi.py │ └── websocket.py ├── hacs.json ├── mypi.ini ├── pyproject.toml ├── requirements.txt ├── scripts/ │ ├── burp-redirector.py │ ├── https-bff.py │ ├── https-ws-case-429.py │ └── setup └── token-requester/ ├── macOS/ │ ├── .gitignore │ └── MBAPI2020 Token Helper/ │ ├── MBAPI2020 Token Helper/ │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets/ │ │ │ ├── AccentColor.colorset/ │ │ │ │ └── Contents.json │ │ │ ├── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Base.lproj/ │ │ │ └── Main.storyboard │ │ ├── MBAPI2020_Token_Helper.entitlements │ │ └── ViewController.swift │ ├── MBAPI2020 Token Helper.xcodeproj/ │ │ ├── project.pbxproj │ │ └── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── MBAPI2020-Token-Helper-Info.plist └── net-core/ └── mb-token-requester/ ├── CallbackManager.cs ├── DesktopEntryHandler.cs ├── Program.cs ├── RegistryConfig.cs ├── appsettings.json ├── callback.bat ├── mb-shortcut-handler.desktop ├── mb-token-requester.csproj └── mb-token-requester.sln ================================================ FILE CONTENTS ================================================ ================================================ FILE: .devcontainer.json ================================================ { "name": "renenulschde/dev-mbapi2020", "image": "mcr.microsoft.com/devcontainers/python:1-3.12", "postCreateCommand": "scripts/setup", "appPort": [ "9123:8123" ], "portsAttributes": { "8123": { "label": "Home Assistant internal", "onAutoForward": "notify" }, "9123": { "label": "Home Assistant remote", "onAutoForward": "notify" } }, "customizations": { "vscode": { "extensions": [ "ms-python.python", "github.vscode-pull-request-github", "ryanluker.vscode-coverage-gutters", "ms-python.vscode-pylance", "ms-python.pylint", "charliermarsh.ruff" ], "settings": { "files.eol": "\n", "editor.tabSize": 4, "python.pythonPath": "/usr/bin/python3", "python.analysis.autoSearchPaths": false, "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", "editor.formatOnSave": true }, "editor.formatOnPaste": false, "editor.formatOnSave": true, "editor.formatOnType": true, "files.trimTrailingWhitespace": true, "[markdown]": { "files.trimTrailingWhitespace": false }, "terminal.integrated.defaultProfile.linux": "zsh" } } }, "remoteUser": "vscode", "features": { "ghcr.io/devcontainers/features/rust:1": {}, "ghcr.io/devcontainers-extra/features/ffmpeg-apt-get:1": {} } } ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: ReneNulschDE buy_me_a_coffee: renenulsch ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: Report an issue with MBAPI2020 description: Report an issue with Mercedes ME integration. body: - type: markdown attributes: value: | This issue form is for reporting bugs only! If you have a feature or enhancement request, please use the [Forum][fr]. [fr]: https://community.home-assistant.io/t/mercedes-me-component/41911 - type: textarea validations: required: true attributes: label: The problem description: >- Describe the issue you are experiencing here, to communicate to the maintainers. Tell us what you were trying to do and what happened. Provide a clear and concise description of what the problem is. - type: markdown attributes: value: | ## Environment - type: input id: version validations: required: true attributes: label: What version of MBAPI2020 do use? placeholder: v0.xx.x description: > Can be found in: [Settings ⇒ System ⇒ Repairs ⇒ Three Dots in Upper Right ⇒ System information](https://my.home-assistant.io/redirect/system_health/). [![Open your Home Assistant instance and show the system information.](https://my.home-assistant.io/badges/system_health.svg)](https://my.home-assistant.io/redirect/system_health/) - type: input attributes: label: What was the last working version of MBAPI2020? placeholder: v0.xx.x description: > If known, otherwise leave blank. - type: dropdown validations: required: true attributes: label: What type of installation are you running? description: > Can be found in: [Settings ⇒ System ⇒ Repairs ⇒ Three Dots in Upper Right ⇒ System information](https://my.home-assistant.io/redirect/system_health/). [![Open your Home Assistant instance and show the system information.](https://my.home-assistant.io/badges/system_health.svg)](https://my.home-assistant.io/redirect/system_health/) options: - Home Assistant OS - Home Assistant Container - Home Assistant Supervised - Home Assistant Core - type: markdown attributes: value: | # Details - type: textarea attributes: label: Diagnostics information placeholder: "drag-and-drop the diagnostics data file here (do not copy-and-paste the content)" description: >- The MBAPI2020 integration provides the ability to [download diagnostic data](https://www.home-assistant.io/docs/configuration/troubleshooting/#download-diagnostics). **It would really help if you could download the diagnostics data for the account/hub you are having issues with, and drag-and-drop that file into the textbox below.** It generally allows pinpointing defects and thus resolving issues faster. - type: textarea attributes: label: Example YAML snippet description: | If applicable, please provide an example piece of YAML that can help reproduce this problem. This can be from an automation, script, scene or configuration. render: yaml - type: textarea attributes: label: Anything in the logs that might be useful for us? description: For example, error message, or stack traces. render: txt - type: textarea attributes: label: Additional information description: > If you have any additional information for us, use the field below. ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: Feature Request or other questions url: https://community.home-assistant.io/t/mercedes-me-component/41911 about: Please use our Community Forum for making feature requests or asking general questions. - name: I'm unsure where to go url: https://community.home-assistant.io/t/mercedes-me-component/41911 about: If you are unsure where to go, then joining and searching in the Forum is a good start. ================================================ FILE: .github/dependabot.yaml ================================================ version: 2 updates: - package-ecosystem: pip directory: "/" schedule: interval: daily time: "04:00" reviewers: - ReneNulschDE assignees: - ReneNulschDE labels: - dependencies ================================================ FILE: .github/workflows/HACS_validate.yaml ================================================ name: Validate with HACS on: push: pull_request: schedule: - cron: "0 0 * * *" jobs: validate: runs-on: "ubuntu-latest" steps: - uses: "actions/checkout@v4" - name: HACS validation uses: "hacs/action@main" with: category: "integration" ================================================ FILE: .github/workflows/hassfest.yaml ================================================ name: Validate with hassfest on: push: pull_request: schedule: - cron: "0 0 * * *" jobs: validate: runs-on: "ubuntu-latest" steps: - uses: "actions/checkout@v4" - uses: home-assistant/actions/hassfest@master ================================================ FILE: .github/workflows/publish.yaml ================================================ name: Publish Workflow on: release: types: - published jobs: release: name: Release runs-on: ubuntu-latest steps: - name: Checkout the repository uses: actions/checkout@v4 - name: Get integration information id: information run: | name=$(find custom_components/ -type d -maxdepth 1 | tail -n 1 | cut -d "/" -f2) echo "name=$name" >> $GITHUB_OUTPUT - name: Adjust version number if: ${{ github.event_name == 'release' }} shell: bash env: TAG_NAME: ${{ github.event.release.tag_name }} run: | yq -i -o json ".version=\"$TAG_NAME\"" \ "${{ github.workspace }}/custom_components/${{ steps.information.outputs.name }}/manifest.json" - name: Create zip file for the integration shell: bash run: | cd "${{ github.workspace }}/custom_components/${{ steps.information.outputs.name }}" zip ${{ steps.information.outputs.name }}.zip -r ./ - name: Upload the zipfile as a release asset uses: softprops/action-gh-release@v2 if: ${{ github.event_name == 'release' }} with: files: ${{ github.workspace }}/custom_components/${{ steps.information.outputs.name }}/${{ steps.information.outputs.name }}.zip tag_name: ${{ github.event.release.tag_name }} ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py db.sqlite3 # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ sec_*.txt .vscode/ /custom_components/mbapi2020/messages/* /custom_components/mbapi2020/resources* /local bin/ obj/ .DS_Store *.csproj.user [Tt]humbs.db .ruff_cache .claude/settings.local.json ================================================ FILE: .pre-commit-config.yaml ================================================ repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.5 hooks: # - id: ruff # args: # - --fix - id: ruff-format files: ^((custom_components/mbapi2020|pylint|script|tests|simulator)/.+)?[^/]+\.py$ - repo: https://github.com/adrienverge/yamllint.git rev: v1.37.1 hooks: - id: yamllint - repo: https://github.com/cdce8p/python-typing-update rev: v0.8.1 hooks: # Run `python-typing-update` hook manually from time to time # to update python typing syntax. # Will require manual work, before submitting changes! # pre-commit run --hook-stage manual python-typing-update --all-files - id: python-typing-update stages: [manual] args: - --py313-plus - --force - --keep-updates files: ^(custom_components/ha-mysmartbike|tests|script|simulator)/.+\.py$ - repo: local hooks: - id: const-check-proxy-not-disabled name: const-check-proxy-not-disabled entry: "USE_PROXY = True" language: pygrep types: [python] - id: const-check-ssl-check-not-correct name: const-check-ssl-check-not-correct entry: "VERIFY_SSL = False" language: pygrep types: [python] ================================================ FILE: .yamllint.yaml ================================================ extends: default rules: # 120 chars should be enough, but don't fail if a line is longer line-length: max: 120 level: warning ================================================ FILE: CLAUDE.md ================================================ # CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview Home Assistant custom component integration for Mercedes-Benz vehicles. Connects to Mercedes-Benz API via OAuth2 and WebSocket to monitor and control vehicle features (charging, locks, preconditioning, etc.). **Python:** 3.13 | **Home Assistant:** >= 2024.02.0 | **Domain:** `mbapi2020` ## Development Commands ```bash # Setup development environment (installs dependencies + pre-commit hooks) scripts/setup # Run ruff formatter ruff format custom_components/mbapi2020 # Run ruff linter ruff check custom_components/mbapi2020 # Run pylint on integration pylint custom_components/mbapi2020 # Validate Home Assistant manifest # (done via GitHub Actions: hassfest.yaml, HACS_validate.yaml) ``` ## Code Style - **Line length:** 120 characters - **Formatter:** Ruff (v0.6.8+) - **Linting:** Ruff and PyLint - **Type checking:** MyPy (Python 3.13) - **Import alias conventions:** `voluptuous` as `vol`, `homeassistant.helpers.config_validation` as `cv` - Pre-commit hooks enforce formatting and check that `USE_PROXY = True` and `VERIFY_SSL = False` are not committed ## Architecture ### Core Files | File | Purpose | |------|---------| | `custom_components/mbapi2020/__init__.py` | Integration setup, async_setup_entry | | `client.py` | Main API client - OAuth2, WebSocket, command handling | | `car.py` | Vehicle data model with nested components (Tires, Doors, Windows, Electric, Auxheat, Precond) | | `coordinator.py` | Home Assistant DataUpdateCoordinator | | `oauth.py` | OAuth2 authentication with token caching | | `websocket.py` | Real-time updates via WebSocket | | `webapi.py` | REST API wrapper for general queries | | `const.py` | All constants, enums, and sensor definitions | ### Entity Types Each entity type has its own file: `sensor.py`, `binary_sensor.py`, `lock.py`, `switch.py`, `button.py`, `device_tracker.py` All entities extend `MercedesMeEntity` base class and use the coordinator pattern. ### Protocol Buffers The `proto/` directory contains auto-generated Python files from `.proto` definitions. Do not edit these files directly. ### Data Flow 1. `oauth.py` handles authentication and token refresh 2. `client.py` establishes WebSocket connection for real-time updates 3. `coordinator.py` manages data updates and distributes to entities 4. Vehicle state stored in `Car` objects with nested component classes ## Home Assistant Patterns ### Async Programming - All external I/O operations must be async - Use `asyncio.gather()` instead of awaiting in loops - Use `hass.async_add_executor_job()` for blocking operations - Use `asyncio.sleep()` instead of `time.sleep()` - Use `@callback` decorator for event loop safe functions ### Error Handling - `ConfigEntryNotReady`: Temporary setup issues (device offline, timeout) - `ConfigEntryAuthFailed`: Authentication problems - `ConfigEntryError`: Permanent setup issues - `ServiceValidationError`: User input errors - Keep try blocks minimal - process data after the try/catch - Bare exceptions allowed only in config flows and background tasks ### Logging Guidelines - No periods at end of messages - No integration names/domains (added automatically) - No sensitive data (keys, tokens, passwords) - Use lazy logging: `_LOGGER.debug("Message with %s", variable)` - Use debug level for non-user-facing messages ### Documentation - File headers: `"""Integration for Mercedes-Benz vehicles."""` - All functions/methods require docstrings - American English, sentence case ## Key Patterns - Config entries for per-account configuration - Services defined in `services.yaml` with implementations in `services.py` - PIN required for secured commands (locks, windows, engine start) - Capability checking enabled by default (can be disabled for North America) - Entity names use `_attr_translation_key` for translations ## Region Notes - Tested regions: EU, NA, AU, and others (see README) - Thailand/India: Use "Europe" region - China: Currently not working - North America: Cars 2019 or newer only; may need capability check disabled ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2020 Rene Nulsch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // Protocol Buffers for Go with Gadgets // // Copyright (c) 2013, The GoGo Authors. All rights reserved. // http://github.com/gogo/protobuf // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following disclaimer // in the documentation and/or other materials provided with the // distribution. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MIT License Copyright (c) 2019 MBition GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # "Mercedes-Benz" custom component ![HassFest tests](https://github.com/renenulschde/mbapi2020/workflows/Validate%20with%20hassfest/badge.svg) ![Validate with HACS](https://github.com/ReneNulschDE/mbapi2020/workflows/Validate%20with%20HACS/badge.svg) ![](https://img.shields.io/github/downloads/renenulschde/mbapi2020/total) ![](https://img.shields.io/github/downloads/renenulschde/mbapi2020/latest/total) Mercedes-Benz platform as a Custom Component for Home Assistant. > ⚠️ **SEEKING NEW MAINTAINER** ⚠️ > After 8+ years of development, I'm selling my last Mercedes and can no longer maintain this integration effectively. **[Looking for someone to take over →](https://github.com/ReneNulschDE/mbapi2020/issues/372)** IMPORTANT: - Please login once into the Mercedes-Benz IOS or Android app before you install this component. (For North America, the app name is Mercedes Me Connect) - Tested Countries: AT, AU, BE, CA, CH, ~~CN~~, DE, DK, ES, FI, FR, IN, IT, IR, NL, NO, NZ, PT, RO, SE, TH, UK, US - North America: For Cars built 2019 or newer only - Thailand, India: Please use the region "Europe". - Mexico, Brazil,...: Please use the region "APAC" - China: Is not working currently (captcha). - Smart cars data are not available after 2025-01-06 - Discussions, Feature Requests via [HA-Community Forum](https://community.home-assistant.io/t/mercedes-me-component/41911) ### Installation - First: This is not a Home Assistant Add-On. It's a custom component. - There are two ways to install. First you can download the folder custom_component and copy it into your Home-Assistant config folder. Second option is to install HACS (Home Assistant Custom Component Store) and select "MercedesME 2020" from the Integrations catalog. - [How to install a custom component?](https://www.google.com/search?q=how+to+install+custom+components+home+assistant) - [How to install HACS?](https://hacs.xyz/docs/use/) - Restart HA after the installation - Make sure that you refresh your browser window too - Use the "Add Integration" in Home Assistant, Settings, Devices & Services and select "MercedesME 2020". - Enter your Mercedes-Benz account credentials (username/password) in the integration setup **Important Notes:** - consider using a dedicated Mercedes-Benz account for Home Assistant - if MFA is enabled on your Mercedes-Benz account, authentication will fail. You must disable MFA or use a separate account without MFA. ### How to Prevent Account Blocking To reduce the risk of your account being blocked, please follow these recommendations: 1. **Create a separate MB user account for use with this component.** 2. **Invite the new user to the vehicle:** The primary user of the vehicle can invite the new HA-MB account to access the vehicle. Up to six additional users can be invited to each vehicle. 3. **Use each account in a single environment only:** Use one account exclusively in HA or in the official MB tools, but never in both simultaneously. #### Important Notes - Certain features, such as geofencing data, are available only to the primary user. - If geofencing is required in your HA environment, use the primary user account in HA and the secondary accounts in the official MB apps. --- ### Optional configuration values See Options dialog in the Integration under Home-Assistant/Configuration/Integration. ``` Excluded Cars: comma-separated list of VINs. PIN: Security PIN to execute special services. Please use your MB mobile app to setup Disable Capability Check: By default the component checks the capabilities of a car. Active this option to disable the capability check. (For North America) Debug Save Messages: Enable this option to save all relevant received message into the messages folder of the component ``` ## Available components Depends on your own car or purchased Mercedes-Benz licenses. ### Binary Sensors - warningwashwater - warningcoolantlevellow - warningbrakefluid - warningenginelight ``` attributes: warningbrakefluid, warningwashwater, warningcoolantlevellow, warninglowbattery ``` - parkbrakestatus ``` attributes: preWarningBrakeLiningWear ``` - theftsystemarmed ``` attributes: carAlarmLastTime, carAlarmReason, collisionAlarmTimestamp, interiorSensor, interiorProtectionStatus, interiorMonitoringLastEvent, interiorMonitoringStatus, exteriorMonitoringLastEvent, exteriorMonitoringStatus, lastParkEvent, lastTheftWarning, lastTheftWarningReason, parkEventLevel, parkEventType, theftAlarmActive, towProtectionSensorStatus, towSensor, ``` - tirewarninglamp ``` attributes: tireMarkerFrontRight, tireMarkerFrontLeft,tireMarkerRearLeft, tireMarkerRearRight, tirewarningsrdk, tirewarningsprw, tireTemperatureRearLeft, tireTemperatureFrontRight, tireTemperatureRearRight, tireTemperatureFrontLeft ``` - windowsClosed ``` attributes: windowstatusrearleft, windowstatusrearright, windowstatusfrontright, windowstatusfrontleft ``` - remoteStartActive ``` attributes: remoteStartTemperature ``` - engineState - chargeFlapACStatus - Preclimate Status (Preconditioning) ``` attributes: precondState, precondActive, precondError, precondNow, precondNowError, precondDuration, precondatdeparture, precondAtDepartureDisable, precondSeatFrontLeft, precondSeatFrontRight, precondSeatRearLeft, precondSeatRearRight, temperature_points_frontLeft, temperature_points_frontRight, temperature_points_rearLeft, temperature_points_rearRight, ``` - wiperHealth ``` attributes: wiperLifetimeExceeded ``` ### Buttons - Flash light - Preclimate start - Preclimate stop ### Device Tracker ``` attributes: positionHeading ``` ### Locks - lock PIN setup in MB App is required. If the pin is not set in the integration options then the lock asks for the PIN. ### Sensors - lock ``` attributes: decklidstatus, doorStatusOverall, doorLockStatusOverall, doorlockstatusgas, doorlockstatusvehicle, doorlockstatusfrontleft,doorlockstatusfrontright, doorlockstatusrearright, doorlockstatusrearleft, doorlockstatusdecklid, doorstatusrearleft, doorstatusfrontright, doorstatusrearright, doorstatusfrontleft, rooftopstatus, sunroofstatus, engineHoodStatus ``` Internal value: doorlockstatusvehicle Values: 0: vehicle unlocked 1: vehicle internal locked 2: vehicle external locked 3: vehicle selective unlocked - Fuel Level (%) ``` attributes: tankLevelAdBlue ``` - Geofencing Violation ``` attributes: Last_event_zone ``` Values: ENTER LEAVE - odometer ``` attributes: distanceReset, distanceStart, averageSpeedReset, averageSpeedStart, distanceZEReset, drivenTimeZEReset, drivenTimeReset, drivenTimeStart, ecoscoretotal, ecoscorefreewhl, ecoscorebonusrange, ecoscoreconst, ecoscoreaccel, gasconsumptionstart, gasconsumptionreset, gasTankRange, gasTankLevel, liquidconsumptionstart, liquidconsumptionreset, liquidRangeSkipIndication, rangeliquid, serviceintervaldays, tanklevelpercent, tankReserveLamp, batteryState, tankLevelAdBlue ``` - Oil Level (%) - Range Electric ``` attributes: chargingstatus, distanceElectricalReset, distanceElectricalStart, ecoElectricBatteryTemperature, endofchargetime, maxrange, selectedChargeProgram, precondActive [DEPRECATED], precondNow [DEPRECATED], precondDuration [DEPRECATED] ``` - Electric consumption start - Electric consumption reset - Charging power - Charging Power Limit ``` attributes: chargingPowerRestriction ``` - Starter Battery State ``` Internal Name: starterBatteryState Values Description_short Description_long "0" "green" "Vehicle ok" "1" "yellow" "Battery partly charged" "2" "red" "Vehicle not available" "3" "serviceDisabled" "Remote service disabled" "4" "vehicleNotAvalable" "Vehicle no longer available" ``` - tirepressureRearLeft - tirepressureRearRight - tirepressureFrontRight - tirepressureFrontLeft - State of Charge (soc) ``` Internal Name: soc State of charge (SoC) is the level of charge of an electric battery relative to its capacity. The units of SoC are percentage points (0% = empty; 100% = full). attributes: maxSocLowerLimit, maxSoc ``` - Ignition state ``` Internal Name: ignitionstate Values Description_short Description_long "0" "lock" "Ignition lock" "1" "off" "Ignition off" "2" "accessory" "Ignition accessory" "4" "on" "Ignition on" "5" "start" "Ignition start" ``` - Aux Heat Status ``` Internal Name: auxheatstatus Values Description "0" inactive "1" normal heating "2" normal ventilation "3" manual heating "4" post heating "5" post ventilation "6" auto heating attributes: auxheattime1, auxheattime2, auxheattime3, auxheattimeselection, auxheatActive, auxheatwarnings, auxheattime2, temperature_points_frontLeft, temperature_points_frontRight ``` - Departure Time ``` Internal Name: departuretime Planned departure time to initiate preclimate functions attributes: departureTimeWeekday ``` ### Diagnostic Sensors [Diagnostic sensors](https://www.home-assistant.io/blog/2021/11/03/release-202111/#entity-categorization) are hidden by default, check the devices page to see the current values - Car ``` attributes: full_update_messages_received, partital_update_messages_received, last_message_received, last_command_type, last_command_state, last_command_error_code, last_command_error_message ``` - RCP_Features Sensor shows true if extended configuration like interior lighting is available. This feature requires a reauthentication in case you used a version <0.6 before (We need some more permissions...). Shows False in case reauthentication has not happened or the feature is not available for your car. ``` attributes: rcp_supported_settings (List of all remote configuration options, I'll implement them step by step as services or buttons) ``` ### Services Some services require that the security PIN is created in your mobile Android/IOS app. Please store the pin to the options-dialog of the integration - refresh_access_token: Refresh the API access token - auxheat_start: Start the auxiliary heating of a car defined by a vin. - auxheat_stop: Stop the auxiliary heating of a car defined by a vin. - battery_max_soc_configure: Configure the maximum value for the state of charge of the HV battery of a car defined by a vin. - doors_unlock: Unlock a car defined by a vin. PIN required. - doors_lock: Lock a car defined by a vin. - engine_start: Start the engine of a car defined by a vin. PIN required. - engine_stop: Stop the engine of a car defined by a vin. - preconditioning_configure_seats: Configure which seats should be preconditioned of a car defined by a vin. - preheat_start: Start the preheating of a zero emission car defined by a vin. - preheat_start_departure_time: Start the preheating of a zero emission car defined by a vin and the departure time in minutes since midnight - preheat_stop: Stop the preheating of a zero emission car defined by a vin. - preheat_stop_departure_time: Disable scheduled departure preconditioning of a zero emission car defined by a vin. - preconditioning_configure: Configure the departure time preconditioning mode (disabled, single, or weekly) of a zero emission car defined by a vin. - send_route: Send a route to a car defined by a vin. - sigpos_start: Start light signaling of a car defined by a vin. - sunroof_open: Open the sunroof of a car defined by a vin. PIN required. - sunroof_tilt: Tilt the sunroof of a car defined by a vin. PIN required. - sunroof_close: Close the sunroof of a car defined by a vin. - temperature_configure: Configure the target preconditioning/auxheat temperatures for zones in a car defined by a VIN. - windows_close: Close the windows of a car defined by a vin. - windows_move Move the windows to a given position. PIN required. - windows_open: Open the windows of a car defined by a vin. PIN required. ### Switches - AuxHeat - Start/Stop the auxiliary heating of the car - Preclimate - Start/Stop the preclimate function of the car ### Logging Set the logging to debug with the following settings in case of problems. ``` logger: default: warn logs: custom_components.mbapi2020: debug ``` ### Open Items - Find a maintainer ### Useful links - [Forum post](https://community.home-assistant.io/t/mercedes-me-component/41911/520) ## Custom Lovelace Card Enhance your experience with this integration by using [VEHICLE INFO CARD](https://github.com/ngocjohn/vehicle-info-card). This card is designed to work seamlessly with the integration, providing a beautiful and intuitive interface to display the data in your Home Assistant dashboard. ### Key Features - **Seamless Integration**: Automatically pulls in data from the integration. - **Customizable**: Easily modify the card’s appearance to fit your theme. - **Interactive**: Includes controls to interact with the data directly from your dashboard. - **Multilingual Support**: The card includes various translations, making it accessible in multiple languages. [Check out the Custom Lovelace Card](https://github.com/ngocjohn/vehicle-info-card) for more details and installation instructions. ================================================ FILE: SECURITY.md ================================================ # Security Policy ## Reporting Security Issues **Please do not report security vulnerabilities through public GitHub issues.** Please send an email to [secure-mbapi2020@nulsch.de](mailto:secure-mbapi2020@nulsch.de). You should receive a response within 24 hours. If for some reason you do not, please follow up via email and keep in mind this project is the hobby of one person. Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) * Full paths of source file(s) related to the manifestation of the issue * The location of the affected source code (tag/branch/commit or direct URL) * Any special configuration required to reproduce the issue * Step-by-step instructions to reproduce the issue * Proof-of-concept or exploit code (if possible) * Impact of the issue, including how an attacker might exploit the issue This information will help me triage your report more quickly. If you are reporting for a bug bounty, then this is the wrong project. I do not have a bug bounty programm. ## Preferred Languages I prefer all communications to be in English or German. ================================================ FILE: custom_components/mbapi2020/__init__.py ================================================ """The MercedesME 2020 integration.""" from __future__ import annotations import asyncio from collections.abc import Callable, Coroutine from dataclasses import dataclass from datetime import datetime import time from typing import Any import aiohttp import voluptuous as vol from custom_components.mbapi2020.car import Car, CarAttribute, RcpOptions from custom_components.mbapi2020.const import ( ATTR_MB_MANUFACTURER, CONF_ENABLE_CHINA_GCJ_02, CONF_OVERWRITE_PRECONDNOW, DOMAIN, LOGGER, LOGIN_BASE_URI, MERCEDESME_COMPONENTS, UNITS, SensorConfigFields as scf, ) from custom_components.mbapi2020.coordinator import MBAPI2020DataUpdateCoordinator from custom_components.mbapi2020.errors import WebsocketError from custom_components.mbapi2020.helper import LogHelper as loghelper from custom_components.mbapi2020.services import setup_services from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryError, ConfigEntryNotReady from homeassistant.helpers import device_registry as dr from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import slugify CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA) async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up MBAPI2020.""" LOGGER.debug("Start async_setup - Initializing services.") hass.data.setdefault(DOMAIN, {}) setup_services(hass) return True async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry): """Set up MercedesME 2020 from a config entry.""" LOGGER.debug("Start async_setup_entry.") try: coordinator = MBAPI2020DataUpdateCoordinator(hass, config_entry) hass.data.setdefault(DOMAIN, {})[config_entry.entry_id] = coordinator await coordinator.client.set_rlock_mode() try: token_info = await coordinator.client.oauth.async_get_cached_token() except aiohttp.ClientError as err: LOGGER.warning("Can not connect to MB OAuth API %s. Will try again.", LOGIN_BASE_URI) LOGGER.debug("Can not connect to MB OAuth API %s. Will try again. %s", LOGIN_BASE_URI, err) raise ConfigEntryNotReady from err if token_info is None: LOGGER.error("Authentication failed. Please reauthenticate.") raise ConfigEntryAuthFailed bff_app_config = await coordinator.client.webapi.get_config() masterdata = await coordinator.client.webapi.get_user_info() hass.async_add_executor_job(coordinator.client.write_debug_json_output, bff_app_config, "app", True) hass.async_add_executor_job(coordinator.client.write_debug_json_output, masterdata, "md", True) vehicles = [] if not masterdata: LOGGER.error("No masterdata found. Please check your account/credentials.") raise ConfigEntryNotReady("No masterdata found. Please check your account/credentials.") for fleet in masterdata.get("fleets", []): company_id = fleet.get("companyId") fleet_id = fleet.get("fleetId") LOGGER.debug( "Fleet %s with company %s found. Collectting car information.", fleet.get("fleetName", "unknown fleet name"), fleet.get("companyName", "unknown company"), ) fleet_info = await coordinator.client.webapi.get_fleet_info(company_id, fleet_id) hass.async_add_executor_job( coordinator.client.write_debug_json_output, fleet_info, f"fleet_{company_id}_{fleet_id}", True, ) vehicles.extend(fleet.get("bookedVehicles", [])) vehicles.extend(masterdata.get("assignedVehicles", [])) for car in vehicles: # Check if the car has a separate VIN key, if not, use the FIN. vin = car.get("vin") if vin is None: vin = car.get("fin") LOGGER.debug( "VIN not found in masterdata. Used FIN %s instead.", loghelper.Mask_VIN(vin), ) # Car is excluded, we do not add this if vin in config_entry.options.get("excluded_cars", ""): continue features: dict[str, bool] = {} vehicle_information: dict = {} try: car_capabilities = await coordinator.client.webapi.get_car_capabilities(vin) hass.async_add_executor_job( coordinator.client.write_debug_json_output, car_capabilities, f"cai-{loghelper.Mask_VIN(vin)}-", True, ) if car_capabilities and "features" in car_capabilities: features.update(car_capabilities["features"]) if car_capabilities and "vehicle" in car_capabilities: vehicle_information = car_capabilities["vehicle"] except aiohttp.ClientError: # For some cars a HTTP401 is raised when asking for capabilities, see github issue #83 LOGGER.info( "Car Capabilities not available for the car with VIN %s.", loghelper.Mask_VIN(vin), ) try: capabilities = await coordinator.client.webapi.get_car_capabilities_commands(vin) hass.async_add_executor_job( coordinator.client.write_debug_json_output, capabilities, f"ca-{loghelper.Mask_VIN(vin)}-", True, ) if capabilities: for feature in capabilities.get("commands"): features[feature.get("commandName")] = bool(feature.get("isAvailable")) if feature.get("commandName", "") == "ZEV_PRECONDITION_CONFIGURE_SEATS": capabilityInformation = feature.get("capabilityInformation", None) if capabilityInformation and len(capabilityInformation) > 0: features[feature.get("capabilityInformation")[0]] = bool(feature.get("isAvailable")) if feature.get("commandName", "") == "CHARGE_PROGRAM_CONFIGURE": max_soc_found = False parameters = feature.get("parameters", []) if parameters is not None: for parameter in parameters: if parameter.get("parameterName", "") == "MAX_SOC": max_soc_found = True features["CHARGE_PROGRAM_CONFIGURE"] = max_soc_found except aiohttp.ClientError: # For some cars a HTTP401 is raised when asking for capabilities, see github issue #83 # We just ignore the capabilities LOGGER.info( "Command Capabilities not available for the car with VIN %s. Make sure you disable the capability check in the option of this component.", loghelper.Mask_VIN(vin), ) rcp_options = RcpOptions() rcp_supported = False # await coordinator.client.webapi.is_car_rcp_supported(vin) LOGGER.debug("RCP supported for car %s: %s", loghelper.Mask_VIN(vin), rcp_supported) setattr(rcp_options, "rcp_supported", CarAttribute(rcp_supported, "VALID", 0)) # rcp_supported = False # if rcp_supported: # rcp_supported_settings = await coordinator.client.webapi.get_car_rcp_supported_settings(vin) # if rcp_supported_settings: # hass.async_add_executor_job( # coordinator.client.write_debug_json_output, # rcp_supported_settings, # "rcs", # ) # if rcp_supported_settings.get("data"): # if rcp_supported_settings.get("data").get("attributes"): # if rcp_supported_settings.get("data").get("attributes").get("supportedSettings"): # LOGGER.debug( # "RCP supported settings: %s", # str(rcp_supported_settings.get("data").get("attributes").get("supportedSettings")), # ) # setattr( # rcp_options, # "rcp_supported_settings", # CarAttribute( # rcp_supported_settings.get("data").get("attributes").get("supportedSettings"), # "VALID", # 0, # ), # ) # for setting in ( # rcp_supported_settings.get("data").get("attributes").get("supportedSettings") # ): # setting_result = await coordinator.client.webapi.get_car_rcp_settings(vin, setting) # if setting_result is not None: # hass.async_add_executor_job( # coordinator.client.write_debug_json_output, # setting_result, # f"rcs_{setting}", # ) current_car = Car(vin) current_car.licenseplate = car.get("licensePlate", vin) current_car.baumuster_description = ( car.get("salesRelatedInformation", "").get("baumuster", "").get("baumusterDescription", "") ) if not current_car.licenseplate.strip(): current_car.licenseplate = vin current_car.features = features current_car.vehicle_information = vehicle_information current_car.masterdata = car current_car.app_configuration = bff_app_config current_car.rcp_options = rcp_options current_car.capabilities = capabilities current_car.last_message_received = int(round(time.time() * 1000)) current_car.is_owner = car.get("isOwner") if config_entry.options.get(CONF_OVERWRITE_PRECONDNOW, False): current_car.features["precondNow"] = True coordinator.client.cars[vin] = current_car # await coordinator.client.update_poll_states(vin) LOGGER.debug("Init - car added - %s", loghelper.Mask_VIN(current_car.finorvin)) await coordinator.async_config_entry_first_refresh() if len(coordinator.client.cars) == 0: LOGGER.error("No cars found. Please check your account/credentials or excluded VINs.") raise ConfigEntryError("No cars found. Please check your account/credentials or excluded VINs.") hass.loop.create_task(coordinator.ws_connect()) except aiohttp.ClientError as err: LOGGER.warning("Can't connect to MB APIs; Retrying in background: %s", err) raise ConfigEntryNotReady from err except WebsocketError as err: LOGGER.error("Websocket error: %s", err) raise ConfigEntryNotReady from err retry_counter: int = 0 while not coordinator.entry_setup_complete: # async websocket data load not complete, wait 0.5 seconds or break up after 60 checks (30sec) if retry_counter == 60 and coordinator.client.websocket.account_blocked: for vin in coordinator.client.cars: await coordinator.client.update_poll_states(vin) LOGGER.warning("Account is blocked. Reload will happen after unblock at midnight (GMT).") break if retry_counter == 60 and not coordinator.client.account_blocked: for vin in coordinator.client.cars: await coordinator.client.update_poll_states(vin) LOGGER.warning( "No full_update set received via websocket for some/all cars. Not all sensors may be available. Missing sensors will be created after the data will be available." ) break await asyncio.sleep(0.5) retry_counter += 1 return True async def config_entry_update_listener(hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Update listener, called when the config entry options are changed.""" LOGGER.debug("Start config_entry_update async_reload") await hass.config_entries.async_reload(config_entry.entry_id) async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry): """Unload mbapi2020 Home config entry.""" LOGGER.debug("Start unload component.") unload_ok = False if len(hass.data[DOMAIN][config_entry.entry_id].client.cars) > 0: # Cancel all watchdogs on final shutdown websocket = hass.data[DOMAIN][config_entry.entry_id].client.websocket websocket._reconnectwatchdog.cancel() websocket._watchdog.cancel() websocket._pingwatchdog.cancel() websocket.component_reload_watcher.cancel() # EVENT_HOMEASSISTANT_STOP-Listener deregistrieren, damit alte # Instanzen beim HA-Shutdown nicht erneut aufgerufen werden. if websocket.ha_stop_handler: websocket.ha_stop_handler() websocket.ha_stop_handler = None result = await websocket.async_stop() websocket._reconnectwatchdog.cancel() websocket._watchdog.cancel() websocket._pingwatchdog.cancel() websocket.component_reload_watcher.cancel() hass.data[DOMAIN][config_entry.entry_id].client.websocket = None if unload_ok := await hass.config_entries.async_unload_platforms(config_entry, MERCEDESME_COMPONENTS): del hass.data[DOMAIN][config_entry.entry_id] else: # No cars loaded, we destroy the config entry only del hass.data[DOMAIN][config_entry.entry_id] unload_ok = True LOGGER.debug("unload result: %s", unload_ok) return unload_ok async def async_remove_config_entry_device( hass: HomeAssistant, config_entry: ConfigEntry, device_entry: dr.DeviceEntry ) -> bool: """Remove a config entry from a device.""" return True @dataclass(frozen=True, kw_only=True) class MercedesMeEntityDescription(EntityDescription): """Configuration class for MercedesMe entities.""" attributes: list[str] | None = None check_capability_fn: Callable[[Car], Callable[[], Coroutine[Any, Any, bool]]] class MercedesMeEntity(CoordinatorEntity[MBAPI2020DataUpdateCoordinator], Entity): """Entity class for MercedesMe devices.""" _attr_has_entity_name = True def __init__( self, internal_name: str, config: list | EntityDescription, vin: str, coordinator: MBAPI2020DataUpdateCoordinator, should_poll: bool = False, ) -> None: """Initialize the MercedesMe entity.""" self._hass = coordinator.hass self._coordinator = coordinator self._vin = vin self._internal_name = internal_name self._sensor_config = config self._car = self._coordinator.client.cars[self._vin] self._feature_name = None self._object_name = None self._attrib_name = None self._flip_result = False self._state = None # Temporary workaround: If PR get's approved, all entity types should be migrated to the new config classes if isinstance(config, EntityDescription): self._attributes = config.attributes self.entity_description = config else: self._feature_name = config[scf.OBJECT_NAME.value] self._object_name = config[scf.ATTRIBUTE_NAME.value] self._attrib_name = config[scf.VALUE_FIELD_NAME.value] self._flip_result = config[scf.FLIP_RESULT.value] self._attr_device_class = self._sensor_config[scf.DEVICE_CLASS.value] self._attr_icon = self._sensor_config[scf.ICON.value] self._attr_state_class = self._sensor_config[scf.STATE_CLASS.value] self._attr_entity_category = self._sensor_config[scf.ENTITY_CATEGORY.value] self._attributes = self._sensor_config[scf.EXTENDED_ATTRIBUTE_LIST.value] self._attr_native_unit_of_measurement = self.unit_of_measurement self._attr_suggested_display_precision = self._sensor_config[scf.SUGGESTED_DISPLAY_PRECISION.value] self._use_chinese_location_data: bool = self._coordinator.config_entry.options.get( CONF_ENABLE_CHINA_GCJ_02, False ) self._attr_translation_key = self._internal_name.lower() self._attr_name = config[scf.DISPLAY_NAME.value] self._name = f"{self._car.licenseplate} {config[scf.DISPLAY_NAME.value]}" self._attr_device_info = {"identifiers": {(DOMAIN, self._vin)}} self._attr_should_poll = should_poll self._attr_unique_id = slugify(f"{self._vin}_{self._internal_name}") super().__init__(coordinator) def device_retrieval_status(self): """Return the retrieval_status of the sensor.""" if self._internal_name == "car": return "VALID" return self._get_car_value(self._feature_name, self._object_name, "retrievalstatus", "error") @property def extra_state_attributes(self): """Return the state attributes.""" state = {"car": self._car.licenseplate, "vin": self._vin} if self._attrib_name == "display_value": value = self._get_car_value(self._feature_name, self._object_name, "value", None) if value: state["original_value"] = value for item in ["retrievalstatus", "timestamp", "unit"]: value = self._get_car_value(self._feature_name, self._object_name, item, None) if value: state[item] = value if item != "timestamp" else datetime.fromtimestamp(int(value)) if self._attributes is not None: for attrib in sorted(self._attributes): if "." in attrib: object_name = attrib.split(".")[0] attrib_name = attrib.split(".")[1] else: object_name = self._feature_name attrib_name = attrib retrievalstatus = self._get_car_value(object_name, attrib_name, "retrievalstatus", "error") if retrievalstatus == "VALID": state[attrib_name] = self._get_car_value(object_name, attrib_name, "display_value", None) if not state[attrib_name]: state[attrib_name] = self._get_car_value(object_name, attrib_name, "value", "error") if retrievalstatus in ["NOT_RECEIVED"]: state[attrib_name] = "NOT_RECEIVED" return state @property def device_info(self) -> DeviceInfo: """Device information.""" return DeviceInfo( identifiers={(DOMAIN, self._vin)}, manufacturer=ATTR_MB_MANUFACTURER, model=self._car.baumuster_description, name=self._car.licenseplate, sw_version=f"{self._car.vehicle_information.get('headUnitSoftwareVersion', '')} - {self._car.vehicle_information.get('headUnitType', '')}", hw_version=f"{self._car.vehicle_information.get('starArchitecture', '')} - {self._car.vehicle_information.get('tcuType', '')}", ) @property def unit_of_measurement(self): """Return the unit of measurement.""" if "unit" in self.extra_state_attributes: reported_unit: str = self.extra_state_attributes["unit"] if reported_unit.upper() in UNITS: return UNITS[reported_unit.upper()] LOGGER.warning( "Unknown unit %s found. Please report via issue https://www.github.com/renenulschde/mbapi2020/issues", reported_unit, ) return reported_unit if isinstance(self._sensor_config, EntityDescription): return None return self._sensor_config[scf.UNIT_OF_MEASUREMENT.value] def update(self): """Get the latest data and updates the states.""" if not self.enabled: return if isinstance(self._sensor_config, EntityDescription): self._mercedes_me_update() else: self._state = self._get_car_value(self._feature_name, self._object_name, self._attrib_name, "error") self.async_write_ha_state() def _mercedes_me_update(self) -> None: """Update Mercedes Me entity.""" raise NotImplementedError def _get_car_value(self, feature, object_name, attrib_name, default_value): value = None if object_name: if not feature: value = getattr( getattr(self._car, object_name, default_value), attrib_name, default_value, ) else: value = getattr( getattr( getattr(self._car, feature, default_value), object_name, default_value, ), attrib_name, default_value, ) else: value = getattr(self._car, attrib_name, default_value) return value def _get_car_attribute(self, feature, object_name): """Get the CarAttribute object for this sensor.""" if object_name: if not feature: return getattr(self._car, object_name, None) feature_obj = getattr(self._car, feature, None) if feature_obj: return getattr(feature_obj, object_name, None) else: return getattr(self._car, self._attrib_name, None) return None def pushdata_update_callback(self): """Schedule a state update.""" self.update() @callback def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" self.update() async def async_added_to_hass(self): """Add callback after being added to hass. Show latest data after startup. """ await super().async_added_to_hass() if not self._attr_should_poll: self._car.add_update_listener(self.pushdata_update_callback) self.async_schedule_update_ha_state(True) self._handle_coordinator_update() async def async_will_remove_from_hass(self): """Entity being removed from hass.""" await super().async_will_remove_from_hass() self._car.remove_update_callback(self.pushdata_update_callback) ================================================ FILE: custom_components/mbapi2020/binary_sensor.py ================================================ """Support for Mercedes cars with Mercedes ME. For more details about this component, please refer to the documentation at https://github.com/ReneNulschDE/mbapi2020/ """ from __future__ import annotations from homeassistant.components.binary_sensor import BinarySensorEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import MercedesMeEntity from .const import ( CONF_FT_DISABLE_CAPABILITY_CHECK, DOMAIN, LOGGER, BinarySensors, DefaultValueModeType, SensorConfigFields as scf, ) from .coordinator import MBAPI2020DataUpdateCoordinator def _create_binary_sensor_if_eligible(key, config, car, coordinator): """Check if binary sensor should be created and return device if eligible.""" # Skip special sensors that should not be created dynamically if key in ["car", "data_mode"]: return None if ( config[scf.CAPABILITIES_LIST.value] is None or coordinator.config_entry.options.get(CONF_FT_DISABLE_CAPABILITY_CHECK, False) or car.features.get(config[scf.CAPABILITIES_LIST.value], False) ): device = MercedesMEBinarySensor( internal_name=key, config=config, vin=car.finorvin, coordinator=coordinator, ) # Check eligibility status = device.device_retrieval_status() is_eligible = status in ["VALID", "NOT_RECEIVED", "3", 3] or ( config[scf.DEFAULT_VALUE_MODE.value] is not None and config[scf.DEFAULT_VALUE_MODE.value] != DefaultValueModeType.NONE and str(status) != "4" ) if is_eligible: return device return None async def create_missing_binary_sensors_for_car(car, coordinator, async_add_entities): """Create missing binary sensors for a specific car.""" missing_sensors = [] for key, value in sorted(BinarySensors.items()): device = _create_binary_sensor_if_eligible(key, value, car, coordinator) if device and f"binary_sensor.{device.unique_id}" not in car.sensors: missing_sensors.append(device) LOGGER.debug("Sensor added: %s", device._name) if missing_sensors: await async_add_entities(missing_sensors, True) return len(missing_sensors) return 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ): """Set up integration from a config entry.""" coordinator: MBAPI2020DataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] if not coordinator.client.cars: LOGGER.info("No Cars found.") return sensors = [] for car in coordinator.client.cars.values(): for key, value in sorted(BinarySensors.items()): device = _create_binary_sensor_if_eligible(key, value, car, coordinator) if device: sensors.append(device) async_add_entities(sensors, True) class MercedesMEBinarySensor(MercedesMeEntity, BinarySensorEntity, RestoreEntity): """Representation of a Sensor.""" def flip(self, state): """Flip the result.""" if self._flip_result: return not state return state @property def is_on(self): """Return the state of the binary sensor.""" if self._state is None: self.update() if self._state == "INACTIVE": return self.flip(False) if self._state == "ACTIVE": return self.flip(True) if self._state == "0": return self.flip(False) if self._state == "1": return self.flip(True) if self._state == "2": return self.flip(False) if self._state == 0: return self.flip(False) if self._state == 1: return self.flip(True) if self._state == 2: return self.flip(False) if self._state == "true": return self.flip(True) if self._state == "false": return self.flip(False) if self._state is False: return self.flip(False) if self._state is True: return self.flip(True) return self._state async def async_added_to_hass(self): """Add callback after being added to hass.""" self._car.add_sensor(f"binary_sensor.{self._attr_unique_id}") await super().async_added_to_hass() async def async_will_remove_from_hass(self): """Entity being removed from hass.""" self._car.remove_sensor(f"binary_sensor.{self._attr_unique_id}") await super().async_will_remove_from_hass() ================================================ FILE: custom_components/mbapi2020/button.py ================================================ """Button support for Mercedes cars with Mercedes ME. For more details about this component, please refer to the documentation at https://github.com/ReneNulschDE/mbapi2020/ """ from __future__ import annotations from homeassistant.components.button import ButtonEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import MercedesMeEntity from .const import BUTTONS, CONF_FT_DISABLE_CAPABILITY_CHECK, DOMAIN, LOGGER, SensorConfigFields as scf from .coordinator import MBAPI2020DataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the demo button platform.""" coordinator: MBAPI2020DataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] if not coordinator.client.cars: LOGGER.info("No Cars found.") return button_list = [] for car in coordinator.client.cars.values(): for key, value in sorted(BUTTONS.items()): if ( value[scf.CAPABILITIES_LIST.value] is None or config_entry.options.get(CONF_FT_DISABLE_CAPABILITY_CHECK, False) is True or car.features.get(value[scf.CAPABILITIES_LIST.value], False) is True ): device = MercedesMEButton( internal_name=key, config=value, vin=car.finorvin, coordinator=coordinator, ) button_list.append(device) async_add_entities(button_list, False) class MercedesMEButton(MercedesMeEntity, ButtonEntity): """Representation of a Sensor.""" async def async_press(self) -> None: """Send out a persistent notification.""" service = getattr(self._coordinator.client, self._sensor_config[3]) await service(self._vin) self._state = None def update(self): """Nothing to update as buttons are stateless.""" ================================================ FILE: custom_components/mbapi2020/car.py ================================================ """Define the objects to store care data.""" from __future__ import annotations import collections from dataclasses import dataclass from datetime import datetime from typing import Any ODOMETER_OPTIONS = [ "odo", "distanceReset", "distanceStart", "averageSpeedReset", "averageSpeedStart", "drivenTimeZEReset", "drivenTimeReset", "drivenTimeStart", "ecoscoretotal", "ecoscorefreewhl", "ecoscorebonusrange", "ecoscoreconst", "ecoscoreaccel", "gasconsumptionstart", "gasconsumptionreset", "gasTankRange", "gasTankLevel", "gasTankLevelPercent", "liquidconsumptionstart", "liquidconsumptionreset", "liquidRangeSkipIndication", "outsideTemperature", "rangeliquid", "remoteStartTemperature", "serviceintervaldays", "serviceintervaldistance", "tanklevelpercent", "tankReserveLamp", "batteryState", "tankLevelAdBlue", "vehicleDataConnectionState", "ignitionstate", "oilLevel", "departuretime", "departureTimeWeekday", ] LOCATION_OPTIONS = ["positionLat", "positionLong", "positionHeading"] TIRE_OPTIONS = [ "tirepressureRearLeft", "tirepressureRearRight", "tirepressureFrontRight", "tirepressureFrontLeft", "tirewarninglamp", "tirewarningsrdk", "tirewarningsprw", "tireMarkerFrontRight", "tireMarkerFrontLeft", "tireMarkerRearLeft", "tireMarkerRearRight", "tireWarningRollup", "lastTirepressureTimestamp", "tireTemperatureRearLeft", "tireTemperatureFrontRight", "tireTemperatureRearRight", "tireTemperatureFrontLeft", ] WINDOW_OPTIONS = [ "windowstatusrearleft", "windowstatusrearright", "windowstatusfrontright", "windowstatusfrontleft", "windowStatusOverall", "flipWindowStatus", ] DOOR_OPTIONS = [ "decklidstatus", "doorStatusOverall", "doorLockStatusOverall", "doorlockstatusgas", "doorlockstatusvehicle", "doorlockstatusfrontleft", "doorlockstatusfrontright", "doorlockstatusrearright", "doorlockstatusrearleft", "doorlockstatusdecklid", "doorstatusrearleft", "doorstatusfrontright", "doorstatusrearright", "doorstatusfrontleft", "rooftopstatus", "sunroofstatus", "engineHoodStatus", "chargeFlapDCStatus", "chargeFlapACStatus", ] ELECTRIC_OPTIONS = [ "rangeelectric", "chargeflap", "chargeinletcoupler", "chargeinletlock", "chargeCouplerACStatus", "chargeCouplerDCStatus", "chargeCouplerACLockStatus", "chargeCouplerDCLockStatus", "chargePrograms", "chargingactive", "chargingBreakClockTimer", "chargingstatus", "chargingPower", "chargingPowerEcoLimit", "chargingPowerRestriction", "departureTimeMode", "distanceElectricalReset", "distanceElectricalStart", "distanceZEReset", "distanceZEStart", "ecoElectricBatteryTemperature", "electricconsumptionstart", "electricconsumptionreset", "electricRatioStart", "electricRatioReset", "electricRatioOverall", "endofchargetime", "endofChargeTimeWeekday", "selectedChargeProgram", "maxrange", "maxSocLowerLimit", "maxSoc", "max_soc", "soc", ] BINARY_SENSOR_OPTIONS = [ "warningwashwater", "warningenginelight", "warningbrakefluid", "warningcoolantlevellow", "parkbrakestatus", #'readingLampFrontRight', #'readingLampFrontLeft', "warningBrakeLiningWear", "warninglowbattery", "starterBatteryState", "liquidRangeCritical", "tankCapOpenLamp", "remoteStartActive", "engineState", ] AUX_HEAT_OPTIONS = [ "auxheatActive", "auxheatwarnings", "auxheatruntime", "auxheatstatus", "auxheatwarningsPush", "auxheattimeselection", "auxheattime1", "auxheattime2", "auxheattime3", ] WIPER_OPTIONS = ["wiperLifetimeExceeded", "wiperHealthPercent"] PRE_COND_OPTIONS = [ "precondStatus", "precondOperatingMode", "precondState", "precondActive", "precondError", "precondNow", "precondNowError", "precondDuration", "precondatdeparture", "precondAtDepartureDisable", "precondSeatFrontLeft", "precondSeatFrontRight", "precondSeatRearLeft", "precondSeatRearRight", "temperature_points_frontLeft", "temperature_points_frontRight", "temperature_points_rearLeft", "temperature_points_rearRight", ] RemoteStart_OPTIONS = ["remoteEngine", "remoteStartEndtime", "remoteStartTemperature"] CarAlarm_OPTIONS = [ "carAlarm", "carAlarmLastTime", "carAlarmReason", "collisionAlarmTimestamp", "interiorSensor", "lastParkEvent", "lastTheftWarning", "lastTheftWarningReason", "parkEventLevel", "parkEventType", "theftAlarmActive", "theftSystemArmed", "towProtectionSensorStatus", "towSensor", "interiorProtectionSensorStatus", "exteriorProtectionSensorStatus", ] GeofenceEvents_OPTIONS = ["last_event_zone", "last_event_timestamp", "last_event_type"] class Car: """Car class, stores the car values at runtime.""" def __init__(self, vin: str): """Initialize the Car instance.""" self.finorvin = vin self.vehicle_information: dict = {} self.capabilities: dict[str, Any] = {} self.licenseplate = "" self._is_owner = False self.messages_received = collections.Counter(f=0, p=0) self._last_message_received = 0 self._last_command_type = "" self._last_command_state = "" self._last_command_error_code = "" self._last_command_error_message = "" self.last_command_time_stamp = 0 self.binarysensors = None self.tires = None self.wipers = None self.odometer = None self.doors = None self.location = None self.windows = None self.rcp_options = None self.auxheat = None self.precond = None self.electric = None self.caralarm = None self.last_full_message = None self.geofence_events = GeofenceEvents() self.features = {} self.masterdata: dict[str, Any] = {} self.app_configuration: dict[str, Any] = {} self.entry_setup_complete = False self._update_listeners = set() self.sensors: set[str] = set() self.baumuster_description: str = "" self.features: dict[str, bool] self.geofence_events: GeofenceEvents self.geo_fencing_retry_counter: int = 0 self.has_geofencing: bool = True self._data_collection_mode: str = "push" self._data_collection_mode_ts: float = 0 @property def is_owner(self): """Get/set if the account is owner of the car.""" return CarAttribute(self._is_owner, "VALID", None) @is_owner.setter def is_owner(self, value: bool): self._is_owner = value @property def full_updatemessages_received(self): """Get number of received full updates messages.""" return CarAttribute(self.messages_received["f"], "VALID", None) @property def partital_updatemessages_received(self): """Get number of received partial updates messages.""" return CarAttribute(self.messages_received["p"], "VALID", None) @property def last_message_received(self): """Get/Set last message received.""" if self._last_message_received > 0: return CarAttribute(datetime.fromtimestamp(int(round(self._last_message_received / 1000))), "VALID", None) return CarAttribute(None, "NOT_RECEIVED", None) @last_message_received.setter def last_message_received(self, value): self._last_message_received = value @property def data_collection_mode(self): """Get/Set last message received.""" return CarAttribute(self._data_collection_mode, "VALID", self._data_collection_mode_ts) @data_collection_mode.setter def data_collection_mode(self, value): self._data_collection_mode = value self._data_collection_mode_ts = datetime.now().timestamp() @property def last_command_type(self): """Get/Set last command type.""" return CarAttribute(self._last_command_type, "VALID", self.last_command_time_stamp) @last_command_type.setter def last_command_type(self, value): self._last_command_type = value @property def last_command_state(self): """Get/Set last command state.""" return CarAttribute(self._last_command_state, "VALID", self.last_command_time_stamp) @last_command_state.setter def last_command_state(self, value): self._last_command_state = value @property def last_command_error_code(self): """Get/Set last command error code.""" return CarAttribute(self._last_command_error_code, "VALID", self.last_command_time_stamp) @last_command_error_code.setter def last_command_error_code(self, value): self._last_command_error_code = value @property def last_command_error_message(self): """Get/Set last command error message.""" return CarAttribute(self._last_command_error_message, "VALID", self.last_command_time_stamp) @last_command_error_message.setter def last_command_error_message(self, value): self._last_command_error_message = value def add_update_listener(self, listener): """Add a listener for update notifications.""" self._update_listeners.add(listener) def remove_update_callback(self, listener): """Remove a listener for update notifications.""" self._update_listeners.discard(listener) def add_sensor(self, unique_id: str): """Add a sensor to the car.""" if unique_id not in self.sensors: self.sensors.add(unique_id) def remove_sensor(self, unique_id: str): """Remove a sensor from the car.""" if unique_id in self.sensors: self.sensors.remove(unique_id) def publish_updates(self): """Schedule call all registered callbacks.""" for callback in self._update_listeners: callback() def check_capabilities(self, required_capabilities: list[str]) -> bool: """Check if the car has the required capabilities.""" return any(self.features.get(capability) is True for capability in required_capabilities) @dataclass(init=False) class Tires: """Stores the Tires values at runtime.""" name: str = "Tires" @dataclass(init=False) class Wipers: """Stores the Wiper values at runtime.""" name: str = "Wipers" @dataclass(init=False) class Odometer: """Stores the Odometer values at runtime.""" name: str = "Odometer" @dataclass(init=False) class RcpOptions: """Stores the RcpOptions values at runtime.""" name: str = "RCP_Options" @dataclass(init=False) class Windows: """Stores the Windows values at runtime.""" name: str = "Windows" @dataclass(init=False) class Doors: """Stores the Doors values at runtime.""" name: str = "Doors" @dataclass(init=False) class Electric: """Stores the Electric values at runtime.""" name: str = "Electric" @dataclass(init=False) class Auxheat: """Stores the Auxheat values at runtime.""" name: str = "Auxheat" @dataclass(init=False) class Precond: """Stores the Precondining values at runtime.""" name: str = "Precond" @dataclass(init=False) class BinarySensors: """Stores the BinarySensors values at runtime.""" name: str = "BinarySensors" @dataclass(init=False) class RemoteStart: """Stores the RemoteStart values at runtime.""" name: str = "RemoteStart" @dataclass(init=False) class CarAlarm: """Stores the CarAlarm values at runtime.""" name: str = "CarAlarm" @dataclass(init=False) class Location: """Stores the Location values at runtime.""" name: str = "Location" @dataclass(init=False) class GeofenceEvents: """Stores the geofence violation values at runtime.""" last_event_type: CarAttribute | None = None last_event_timestamp: CarAttribute | None = None last_event_zone: CarAttribute | None = None name: str = "GeofenceEvents" def __post_init__(self): """Initialize mutable attributes.""" self.events = [] @dataclass(init=False) class CarAttribute: """Stores the CarAttribute values at runtime.""" def __init__(self, value, retrievalstatus, timestamp, display_value=None, unit=None, sensor_created=False): """Initialize the instance.""" self.value = value self.retrievalstatus = retrievalstatus self.timestamp = timestamp self.display_value = display_value self.unit = unit self.sensor_created = sensor_created ================================================ FILE: custom_components/mbapi2020/client.py ================================================ """The MercedesME 2020 client.""" from __future__ import annotations import asyncio import datetime as dt from datetime import datetime, timezone import json import logging from pathlib import Path import threading import time import traceback import uuid from aiohttp import ClientSession from google.protobuf.json_format import MessageToJson from custom_components.mbapi2020.proto import client_pb2 import custom_components.mbapi2020.proto.vehicle_commands_pb2 as pb2_commands from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_UNKNOWN from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers import system_info from .car import ( AUX_HEAT_OPTIONS, BINARY_SENSOR_OPTIONS, DOOR_OPTIONS, ELECTRIC_OPTIONS, LOCATION_OPTIONS, ODOMETER_OPTIONS, PRE_COND_OPTIONS, TIRE_OPTIONS, WINDOW_OPTIONS, WIPER_OPTIONS, Auxheat, BinarySensors, Car, CarAlarm, CarAlarm_OPTIONS, CarAttribute, Doors, Electric, GeofenceEvents, Location, Odometer, Precond, Tires, Windows, Wipers, ) from .const import ( CONF_DEBUG_FILE_SAVE, CONF_EXCLUDED_CARS, CONF_FT_DISABLE_CAPABILITY_CHECK, CONF_PIN, DEFAULT_CACHE_PATH, DEFAULT_DOWNLOAD_PATH, DEFAULT_SOCKET_MIN_RETRY, ) from .helper import LogHelper as loghelper from .oauth import Oauth from .webapi import WebApi from .websocket import Websocket LOGGER = logging.getLogger(__name__) DEBUG_SIMULATE_PARTIAL_UPDATES_ONLY = False GEOFENCING_MAX_RETRIES = 1 class Client: """define the client.""" def __init__( self, hass: HomeAssistant, session: ClientSession, config_entry: ConfigEntry, region: str = "", ) -> None: """Initialize the client instance.""" self.long_running_operation_active: bool = False self.ignition_states: dict[str, bool] = {} self.account_blocked: bool = False self._ws_reconnect_delay = DEFAULT_SOCKET_MIN_RETRY self._hass = hass self._region = region self._on_dataload_complete = None self._dataload_complete_fired = False self._coordinator_ref = None self._disable_rlock = False self.__lock = None self._debug_save_path = self._hass.config.path(DEFAULT_CACHE_PATH) self.config_entry = config_entry self.session_id = str(uuid.uuid4()).upper() self._first_vepupdates_processed: bool = False self._vepupdates_timeout_seconds: int = 25 self._vepupdates_time_first_message: datetime | None = None self.oauth: Oauth = Oauth( hass=self._hass, session=session, region=self._region, config_entry=config_entry, ) self.oauth.session_id = self.session_id self.webapi: WebApi = WebApi(self._hass, session=session, oauth=self.oauth, region=self._region) self.webapi.session_id = self.session_id self.websocket: Websocket = Websocket( hass=self._hass, oauth=self.oauth, region=self._region, session_id=self.session_id, ignition_states=self.ignition_states, ) self.cars: dict[str, Car] = {} @property def pin(self) -> str: """Return the security pin of an account.""" if self.config_entry: if self.config_entry.options: return self.config_entry.options.get(CONF_PIN, None) return "" @property def excluded_cars(self): """Return the list of exluded/ignored VIN/FIN.""" if self.config_entry: if self.config_entry.options: return self.config_entry.options.get(CONF_EXCLUDED_CARS, []) return [] def on_data(self, data): """Define a handler to fire when the data is received.""" msg_type = data.WhichOneof("msg") if self.websocket and self.websocket.ws_connect_retry_counter > 0: self.websocket.ws_connect_retry_counter = 0 self.websocket.ws_connect_retry_counter_reseted = True if msg_type == "vepUpdate": # VEPUpdate LOGGER.debug("vepUpdate") return None if msg_type == "vepUpdates": # VEPUpdatesByVIN self._process_vep_updates(data) sequence_number = data.vepUpdates.sequence_number LOGGER.debug("vepUpdates Sequence: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_vep_updates_by_vin.sequence_number = sequence_number return ack_command if msg_type == "debugMessage": # DebugMessage self._write_debug_output(data, "deb") if data.debugMessage: LOGGER.debug("debugMessage - Data: %s", data.debugMessage.message) return None if msg_type == "service_status_updates": self._write_debug_output(data, "ssu") sequence_number = data.service_status_updates.sequence_number LOGGER.debug("service_status_update Sequence: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_service_status_update.sequence_number = sequence_number return ack_command if msg_type == "user_data_update": self._write_debug_output(data, "udu") sequence_number = data.user_data_update.sequence_number LOGGER.debug("user_data_update Sequence: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_user_data_update.sequence_number = sequence_number return ack_command if msg_type == "user_vehicle_auth_changed_update": LOGGER.debug( "user_vehicle_auth_changed_update - Data: %s", MessageToJson(data, preserving_proto_field_name=True), ) return None if msg_type == "user_picture_update": self._write_debug_output(data, "upu") sequence_number = data.user_picture_update.sequence_number LOGGER.debug("user_picture_update Sequence: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_user_picture_update.sequence_number = sequence_number return ack_command if msg_type == "user_pin_update": self._write_debug_output(data, "pin") sequence_number = data.user_pin_update.sequence_number LOGGER.debug("user_pin_update Sequence: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_user_pin_update.sequence_number = sequence_number return ack_command if msg_type == "vehicle_updated": self._write_debug_output(data, "vup") sequence_number = data.vehicle_updated.sequence_number LOGGER.debug("vehicle_updated Sequence: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_vehicle_updated.sequence_number = sequence_number return ack_command if msg_type == "preferred_dealer_change": self._write_debug_output(data, "pdc") sequence_number = data.preferred_dealer_change.sequence_number LOGGER.debug("preferred_dealer_change Sequence: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_preferred_dealer_change.sequence_number = sequence_number return ack_command if msg_type == "apptwin_command_status_updates_by_vin": LOGGER.debug( "apptwin_command_status_updates_by_vin - Data: %s", MessageToJson(data, preserving_proto_field_name=True), ) self._process_apptwin_command_status_updates_by_vin(data) sequence_number = data.apptwin_command_status_updates_by_vin.sequence_number LOGGER.debug("apptwin_command_status_updates_by_vin: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_apptwin_command_status_update_by_vin.sequence_number = sequence_number return ack_command if msg_type == "apptwin_pending_command_request": self._process_assigned_vehicles(data) return "aa0100" if msg_type == "assigned_vehicles": self._write_debug_output(data, "asv") self._process_assigned_vehicles(data) return "ba0100" if msg_type == "data_change_event": self._write_debug_output(data, "dce") sequence_number = data.data_change_event.sequence_number LOGGER.debug("data_change_event: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_data_change_event.sequence_number = sequence_number return ack_command if msg_type == "vehicle_status_updates": self._write_debug_output(data, "vsu") LOGGER.info( "vehicle_status_updates - Data: %s", MessageToJson(data, preserving_proto_field_name=True), ) sequence_number = data.vehicle_status_updates.sequence_number LOGGER.debug("vehicle_status_updates Sequence: %s", sequence_number) ack_command = client_pb2.ClientMessage() ack_command.acknowledge_vehicle_status_updates.sequence_number = sequence_number return ack_command self._write_debug_output(data, "unk") LOGGER.debug("Message Type not implemented: %s", msg_type) return None async def attempt_connect(self, callback_dataload_complete, coordinator_ref=None): """Attempt to connect to the socket.""" LOGGER.debug("attempt_connect") self._on_dataload_complete = callback_dataload_complete self._coordinator_ref = coordinator_ref await self.websocket.async_connect(self.on_data) def _build_car(self, received_car_data, update_mode, is_rest_data=False): if received_car_data.get("vin") in self.excluded_cars: LOGGER.debug("CAR excluded: %s", loghelper.Mask_VIN(received_car_data.get("vin"))) return if received_car_data.get("vin") not in self.cars: LOGGER.info( "Flow Problem - VepUpdate for unknown car: %s", loghelper.Mask_VIN(received_car_data.get("vin")), ) current_car = Car(received_car_data.get("vin")) current_car.licenseplate = received_car_data.get("vin") self.cars[received_car_data.get("vin")] = current_car car: Car = self.cars.get(received_car_data.get("vin"), Car(received_car_data.get("vin"))) car.messages_received.update("p" if update_mode else "f") car.last_message_received = int(round(time.time() * 1000)) if not update_mode: car.last_full_message = received_car_data # Set data collection mode based on data source if is_rest_data: car.data_collection_mode = "pull" else: car.data_collection_mode = "push" # For REST data, create synthetic windowStatusOverall if missing if is_rest_data and received_car_data.get("attributes"): if "windowStatusOverall" not in received_car_data["attributes"]: self._create_synthetic_window_status_overall(received_car_data, car.finorvin) car.odometer = self._get_car_values( received_car_data, car.finorvin, Odometer() if not car.odometer else car.odometer, ODOMETER_OPTIONS, update_mode, ) car.tires = self._get_car_values( received_car_data, car.finorvin, Tires() if not car.tires else car.tires, TIRE_OPTIONS, update_mode, ) car.wipers = self._get_car_values( received_car_data, car.finorvin, Wipers() if not car.wipers else car.wipers, WIPER_OPTIONS, update_mode, ) car.doors = self._get_car_values( received_car_data, car.finorvin, Doors() if not car.doors else car.doors, DOOR_OPTIONS, update_mode, ) car.location = self._get_car_values( received_car_data, car.finorvin, Location() if not car.location else car.location, LOCATION_OPTIONS, update_mode, ) car.binarysensors = self._get_car_values( received_car_data, car.finorvin, BinarySensors() if not car.binarysensors else car.binarysensors, BINARY_SENSOR_OPTIONS, update_mode, ) car.windows = self._get_car_values( received_car_data, car.finorvin, Windows() if not car.windows else car.windows, WINDOW_OPTIONS, update_mode, ) car.electric = self._get_car_values( received_car_data, car.finorvin, Electric() if not car.electric else car.electric, ELECTRIC_OPTIONS, update_mode, ) car.auxheat = self._get_car_values( received_car_data, car.finorvin, Auxheat() if not car.auxheat else car.auxheat, AUX_HEAT_OPTIONS, update_mode, ) car.precond = self._get_car_values( received_car_data, car.finorvin, Precond() if not car.precond else car.precond, PRE_COND_OPTIONS, update_mode, ) car.caralarm = self._get_car_values( received_car_data, car.finorvin, CarAlarm() if not car.caralarm else car.caralarm, CarAlarm_OPTIONS, update_mode, ) if not update_mode: car.entry_setup_complete = True self.cars[car.finorvin] = car def _get_car_values(self, car_detail, vin, class_instance, options, update): # Define handlers for specific options and the generic case option_handlers = { "max_soc": self._get_car_values_handle_max_soc, "chargeflap": self._get_car_values_handle_chargeflap, "chargeinletcoupler": self._get_car_values_handle_chargeinletcoupler, "chargeinletlock": self._get_car_values_handle_chargeinletlock, "chargePrograms": self._get_car_values_handle_chargePrograms, "chargingBreakClockTimer": self._get_car_values_handle_charging_break_clock_timer, "chargingPowerRestriction": self._get_car_values_handle_charging_power_restriction, "endofchargetime": self._get_car_values_handle_endofchargetime, "ignitionstate": self._get_car_values_handle_ignitionstate, "precondStatus": self._get_car_values_handle_precond_status, "temperature_points_frontLeft": self._get_car_values_handle_temperature_points, "temperature_points_frontRight": self._get_car_values_handle_temperature_points, "temperature_points_rearLeft": self._get_car_values_handle_temperature_points, "temperature_points_rearRight": self._get_car_values_handle_temperature_points, } if car_detail is None or not car_detail.get("attributes"): LOGGER.debug( "get_car_values %s has incomplete update data – attributes not found", loghelper.Mask_VIN(vin), ) return class_instance for option in options: # Select the specific handler or the generic handler handler = option_handlers.get(option, self._get_car_values_handle_generic) curr_status = handler(car_detail, class_instance, option, update, vin) if curr_status is None: continue # Set the value only if the timestamp is newer # curr_timestamp = float(curr_status.timestamp or 0) # car_value_timestamp = float(self._get_car_value(class_instance, option, "ts", 0)) # if curr_timestamp > car_value_timestamp: # setattr(class_instance, option, curr_status) # elif curr_timestamp < car_value_timestamp: # LOGGER.warning( # "get_car_values %s received older attribute data for %s. Ignoring value.", # loghelper.Mask_VIN(vin), # option, # ) setattr(class_instance, option, curr_status) return class_instance def _get_car_values_handle_generic(self, car_detail, class_instance, option, update, vin: str): curr = car_detail.get("attributes", {}).get(option) if curr: # Simplify value extraction by checking for existing keys value = next( (curr[key] for key in ("value", "int_value", "double_value", "bool_value") if key in curr), 0, ) status = curr.get("status", "VALID") time_stamp = curr.get("timestamp", 0) curr_display_value = curr.get("display_value") unit_keys = [ "distance_unit", "ratio_unit", "clock_hour_unit", "gas_consumption_unit", "pressure_unit", "electricity_consumption_unit", "combustion_consumption_unit", "speed_unit", ] unit = next((curr[key] for key in unit_keys if key in curr), None) return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=curr_display_value, unit=unit, ) if not update: # Set status for non-existing values when no update occurs return CarAttribute(0, 4, 0) return None def _get_car_values_handle_max_soc( self, car_detail, class_instance, option, update, vin: str, use_last_full_message: bool = False ): # Handle the case when the selected charge program changed but chargePrograms is not available in the update message. if not use_last_full_message: attributes = car_detail.get("attributes", {}) charge_programs = attributes.get("chargePrograms") if not charge_programs: if not attributes.get("selectedChargeProgram"): return None return self._get_car_values_handle_max_soc( car_detail, class_instance, option, update, vin, use_last_full_message=True ) else: current_car = self.cars.get(vin) if not current_car or not current_car.last_full_message: LOGGER.debug( "get_car_values_handle_max_soc - No last_full_message found for car %s", loghelper.Mask_VIN(vin), ) return None car_detail = current_car.last_full_message or car_detail attributes = car_detail.get("attributes", {}) charge_programs = attributes.get("chargePrograms") if not charge_programs: return None time_stamp = charge_programs.get("timestamp", 0) charge_programs_value = charge_programs.get("charge_programs_value", {}) charge_program_parameters = charge_programs_value.get("charge_program_parameters", []) selected_program_index = int(self._get_car_value(class_instance, "selectedChargeProgram", "value", 0)) # Ensure the selected index is within bounds if 0 <= selected_program_index < len(charge_program_parameters): program_parameters = charge_program_parameters[selected_program_index] max_soc = program_parameters.get("max_soc") if max_soc is not None: return CarAttribute( value=max_soc, retrievalstatus="VALID", timestamp=time_stamp, display_value=max_soc, unit="PERCENT", ) return None def _get_car_values_handle_chargeflap(self, car_detail, class_instance, option, update, vin: str): attributes = car_detail.get("attributes", {}) curr = attributes.get("chargeFlaps") if not curr: return None charge_flaps_value = curr.get("charge_flaps", {}) values = charge_flaps_value.get("entries", []) if not values: return None status = curr.get("status", "VALID") time_stamp = curr.get("timestamp", 0) value = values[0].get("position_state", None) if value is None: return None if value == "CHARGE_FLAPS_POSITION_STATE_OPEN": value = "open" elif value == "CHARGE_FLAPS_POSITION_STATE_CLOSED": value = "closed" elif value == "CHARGE_FLAPS_POSITION_STATE_FLAP_PRESSED": value = "pressed" elif value == "CHARGE_FLAPS_POSITION_STATE_UNKNOWN": value = STATE_UNKNOWN else: value = STATE_UNKNOWN LOGGER.debug( "Unknown chargeFlaps position_state value: %s. Please report this value via an github issue.", value ) return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=None, unit=None, ) def _get_car_values_handle_chargeinletcoupler(self, car_detail, class_instance, option, update, vin: str): attributes = car_detail.get("attributes", {}) curr = attributes.get("chargeInlets") if not curr: return None values = curr.get("charge_inlets", {}).get("entries", []) if not values: return None status = curr.get("status", "VALID") time_stamp = curr.get("timestamp", 0) value = values[0].get("coupler_state", None) if value is None: return None if value == "CHARGE_INLETS_COUPLER_STATE_PLUGGED": value = "plugged" elif value == "CHARGE_INLETS_COUPLER_STATE_VEHICLE_PLUGGED": value = "vehicle plugged" elif value == "CHARGE_INLETS_COUPLER_STATE_VEHICLE_NOT_PLUGGED": value = "vehicle not plugged" elif value == "CHARGE_INLETS_COUPLER_STATE_DEFECT": value = "defect" elif value == "CHARGE_INLETS_COUPLER_STATE_UNKNOWN": value = STATE_UNKNOWN else: value = STATE_UNKNOWN LOGGER.debug( "Unknown chargeInlets coupler_state value: %s. Please report this value via an github issue.", value ) return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=None, unit=None, ) def _get_car_values_handle_chargeinletlock(self, car_detail, class_instance, option, update, vin: str): attributes = car_detail.get("attributes", {}) curr = attributes.get("chargeInlets") if not curr: return None values = curr.get("charge_inlets", {}).get("entries", []) if not values: return None status = curr.get("status", "VALID") time_stamp = curr.get("timestamp", 0) value = values[0].get("lock_state", None) if value is None: return None if value == "CHARGE_INLETS_LOCK_STATE_UNLOCKED": value = "unlocked" elif value == "CHARGE_INLETS_LOCK_STATE_LOCKED": value = "locked" elif value == "CHARGE_INLETS_LOCK_STATE_LOCK_STATE_NOT_CLEAR": value = "state not clear" elif value == "CHARGE_INLETS_LOCK_STATE_NOT_AVAILABLE": value = "state not available" elif value == "CHARGE_INLETS_LOCK_STATE_UNKNOWN": value = STATE_UNKNOWN else: value = STATE_UNKNOWN LOGGER.debug( "Unknown chargeInlets lock_state value: %s. Please report this value via an github issue.", value ) return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=None, unit=None, ) def _get_car_values_handle_chargePrograms(self, car_detail, class_instance, option, update, vin: str): attributes = car_detail.get("attributes", {}) curr = attributes.get(option) if not curr: return None charge_programs_value = curr.get("charge_programs_value", {}) value = charge_programs_value.get("charge_program_parameters", []) if not value: return None status = curr.get("status", "VALID") time_stamp = curr.get("timestamp", 0) return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=None, unit=None, ) def _get_car_values_handle_charging_power_restriction(self, car_detail, class_instance, option, update, vin: str): attributes = car_detail.get("attributes", {}) curr = attributes.get("chargingPowerRestriction") if not curr: return None charge_flaps_value = curr.get("charging_power_restrictions", {}) values = charge_flaps_value.get("charging_power_restriction", []) if not values: return None status = curr.get("status", "VALID") time_stamp = curr.get("timestamp", 0) if len(values) == 0: return None value = ", ".join(item.replace("CHARGING_POWER_RESTRICTION_", "") for item in values) return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=None, unit=None, ) def _get_car_values_handle_endofchargetime(self, car_detail, class_instance, option, update, vin: str): # Beginning with CLA 2025 charge end time is part of chargingPredictionMaxSoc attributes = car_detail.get("attributes", {}) chargingPredictionMaxSoc = attributes.get("chargingPredictionMaxSoc", {}) charging_prediction_soc = chargingPredictionMaxSoc.get("charging_prediction_soc", {}) predicted_end_time = charging_prediction_soc.get("predicted_end_time", None) if predicted_end_time is not None: status = chargingPredictionMaxSoc.get("status", "VALID") time_stamp = chargingPredictionMaxSoc.get("timestamp", 0) if isinstance(predicted_end_time, datetime): value = predicted_end_time elif isinstance(predicted_end_time, str): try: value = datetime.strptime(predicted_end_time, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=timezone.utc) except Exception: value = None else: value = None if value is not None: return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=value, unit=None, ) # if chargingPredictionMaxSoc is not available and update is false (not a full_message), we want to check if the car is >= CLA2025 and create the data structure with value unknown # endofchargetime is not present for these cars if not update and not predicted_end_time: current_car = self.cars.get(vin) if not attributes.get("endofchargetime") and not ( current_car and current_car.last_full_message and current_car.last_full_message.get("attributes", {}).get("endofchargetime") ): return CarAttribute( value=STATE_UNKNOWN, retrievalstatus="VALID", timestamp=datetime.now().timestamp(), display_value=STATE_UNKNOWN, unit=None, ) # Older cars have two attributes endofchargetime and endofChargeTimeWeekday # endofchargetime is in minutes after midnight try: endofchargetime = attributes.get("endofchargetime", {}) if not endofchargetime: return None time_stamp = endofchargetime.get("timestamp", 0) end_time_value = endofchargetime.get("int_value", None) status = endofchargetime.get("status", "VALID") if end_time_value is None and status == 3: return CarAttribute( value=STATE_UNKNOWN, retrievalstatus=status, timestamp=time_stamp, display_value=STATE_UNKNOWN, unit=None, ) if end_time_value is None: LOGGER.warning( "get_car_values_handle_endofchargetime - endofChargeTime value is None for car %s", loghelper.Mask_VIN(vin), ) return None # endofChargeTimeWeekday is sometimes not present in the update message, we need to get it from the last full message then if "endofChargeTimeWeekday" not in attributes: current_car = self.cars.get(vin) if not current_car or not current_car.last_full_message: LOGGER.debug( "get_car_values_handle_endofchargetime - No last_full_message found for car %s", loghelper.Mask_VIN(vin), ) return None car_detail = current_car.last_full_message attributes = car_detail.get("attributes", {}) local_tz = dt.datetime.now().astimezone().tzinfo end_weekday_attr = attributes.get("endofChargeTimeWeekday", {}) end_weekday_value = end_weekday_attr.get("int_value", None) if end_weekday_value is None: # Wenn kein Wochentag vorhanden ist (sehr alte elek. modelle), aus end_time_value ableiten: # Ist die Uhrzeit bereits vergangen -> Wochentag von morgen, sonst von heute. now = dt.datetime.now(local_tz) hour = int(end_time_value) // 60 minute = int(end_time_value) % 60 target_dt_today = dt.datetime(now.year, now.month, now.day, hour, minute, tzinfo=local_tz) if target_dt_today < now: end_weekday_value = (now + dt.timedelta(days=1)).weekday() else: end_weekday_value = now.weekday() # Calculate the next occurrence of the given weekday and time in local timezone now = dt.datetime.now(local_tz) # Python's weekday: Monday=0 target_weekday = float(end_weekday_value) % 7 # Calculate days until next target_weekday days_ahead = (target_weekday - now.weekday()) % 7 target_date = now + dt.timedelta(days=days_ahead) hour = int(end_time_value) // 60 minute = int(end_time_value) % 60 dt_with_time = dt.datetime( target_date.year, target_date.month, target_date.day, hour, minute, tzinfo=local_tz ) return CarAttribute( value=dt_with_time, retrievalstatus=status, timestamp=time_stamp, display_value=dt_with_time.isoformat(), unit=None, ) except Exception as e: LOGGER.error( "Error processing endofchargetime for car %s: %s, %s", loghelper.Mask_VIN(vin), e, traceback.format_exc(), ) return None def _get_car_values_handle_charging_break_clock_timer(self, car_detail, class_instance, option, update, vin: str): attributes = car_detail.get("attributes", {}) curr = attributes.get(option) if not curr: return None charging_timer_value = curr.get("chargingbreak_clocktimer_value", {}) value = charging_timer_value.get("chargingbreak_clocktimer_entry") if value is None: return None status = curr.get("status", "VALID") time_stamp = curr.get("timestamp", 0) curr_display_value = curr.get("display_value") return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=curr_display_value, unit=None, ) def _get_car_values_handle_ignitionstate(self, car_detail, class_instance, option, update, vin: str): value = self._get_car_values_handle_generic(car_detail, class_instance, option, update, vin) if value: vin = car_detail.get("vin") self.ignition_states[vin] = value.value == "4" if vin in self.excluded_cars: self.ignition_states[vin] = False return value def _get_car_values_handle_precond_status(self, car_detail, class_instance, option, update, vin: str): attributes = car_detail.get("attributes", {}) # Retrieve attributes with defaults to handle missing keys precond_now_attr = attributes.get("precondNow", {}) precond_active_attr = attributes.get("precondActive", {}) precond_operating_mode_attr = attributes.get("precondOperatingMode", {}) # Extract values and convert to boolean where necessary precond_now_value = precond_now_attr.get("bool_value", False) precond_active_value = precond_active_attr.get("bool_value", False) precond_operating_mode_value = precond_operating_mode_attr.get("int_value", 0) precond_operating_mode_bool = int(precond_operating_mode_value) > 0 # Calculate precondStatus value = precond_now_value or precond_active_value or precond_operating_mode_bool # Determine if any of the attributes are present if precond_now_attr or precond_active_attr or precond_operating_mode_attr: status = "VALID" time_stamp = max( int(precond_now_attr.get("timestamp", 0)), int(precond_active_attr.get("timestamp", 0)), int(precond_operating_mode_attr.get("timestamp", 0)), ) return CarAttribute( value=value, retrievalstatus=status, timestamp=time_stamp, display_value=str(value), unit=None, ) if not update: # Set status for non-existing values when no update occurs return CarAttribute(False, 4, 0) return None def _get_car_values_handle_temperature_points(self, car_detail, class_instance, option: str, update, vin: str): curr_zone = option.replace("temperature_points_", "") attributes = car_detail.get("attributes", {}) temperaturePoints = attributes.get("temperaturePoints") if not temperaturePoints: return None time_stamp = temperaturePoints.get("timestamp", 0) temperature_points_value = temperaturePoints.get("temperature_points_value", {}) temperature_points = temperature_points_value.get("temperature_points", []) for point in temperature_points: if point.get("zone", "") == curr_zone: return CarAttribute( value=point.get("temperature", 0), retrievalstatus="VALID", timestamp=time_stamp, display_value=point.get("temperature_display_value"), unit=temperaturePoints.get("temperature_unit", None), ) return None def _create_synthetic_window_status_overall(self, car_data, vin): """Create a synthetic windowStatusOverall based on individual window statuses for REST data.""" if not car_data.get("attributes"): return # Debug: Log all available window-related attributes # window_attrs_found = [key for key in car_data["attributes"].keys() if "window" in key.lower()] # if window_attrs_found: # LOGGER.debug("Available window attributes for %s: %s", loghelper.Mask_VIN(vin), window_attrs_found) # else: # LOGGER.debug("No window attributes found in REST data for %s", loghelper.Mask_VIN(vin)) # Define main window status attributes to check main_window_attrs = [ "windowstatusfrontleft", "windowstatusfrontright", "windowstatusrearleft", "windowstatusrearright", ] # Check individual window statuses window_statuses = [] latest_timestamp = 0 for attr_name in main_window_attrs: if attr_name in car_data["attributes"]: attr_data = car_data["attributes"][attr_name] value = attr_data.get("int_value", 0) timestamp = attr_data.get("timestamp", 0) # Convert timestamp to int for comparison try: timestamp = int(timestamp) if timestamp else 0 latest_timestamp = max(latest_timestamp, timestamp) except (ValueError, TypeError): pass # Add to window statuses if value is available if value is not None: window_statuses.append(value) # Calculate overall status based on individual windows # If we have valid window statuses, determine overall state if window_statuses: # Assume "CLOSED" = 0, "OPEN" = 1 or similar numeric values # If all windows are closed (0), overall should be "CLOSED" # If any window is open (>0), overall should be "OPEN" try: numeric_statuses = [int(status) for status in window_statuses if status is not None] if numeric_statuses: overall_value = "OPEN" if any(status != 2 for status in numeric_statuses) else "CLOSED" else: overall_value = "CLOSED" # Default to closed if no valid data except (ValueError, TypeError): # If values are not numeric, try string comparison overall_value = "CLOSED" else: # No individual window data available, default to CLOSED overall_value = "CLOSED" # Create the synthetic windowStatusOverall attribute car_data["attributes"]["windowStatusOverall"] = { "timestamp": str(latest_timestamp) if latest_timestamp > 0 else "0", "bool_value": overall_value == "CLOSED", "status": "VALID", # Use same status as other synthetic attributes "timestamp_in_ms": str(latest_timestamp * 1000 + 223), } LOGGER.debug( "Created synthetic windowStatusOverall for %s: %s (based on %d individual windows)", loghelper.Mask_VIN(vin), overall_value, len(window_statuses), ) def _get_car_value(self, class_instance, object_name, attrib_name, default_value): return getattr( getattr(class_instance, object_name, default_value), attrib_name, default_value, ) def _process_rest_vep_update(self, data): LOGGER.debug("Start _process_rest_vep_update") self._write_debug_output(data, "rfu") # Don't understand the protobuf dict errors --> convert to json vep_json = json.loads(MessageToJson(data, preserving_proto_field_name=True)) # Check if this is a nested vepUpdates structure or a direct VIN structure if "vepUpdates" in vep_json and "updates" in vep_json["vepUpdates"]: # This is a multi-car update structure cars = vep_json["vepUpdates"]["updates"] for vin in cars: if vin in self.excluded_cars: continue current_car = cars.get(vin) if current_car: self._build_car(current_car, update_mode=False, is_rest_data=True) else: # This is a single car structure vin = vep_json.get("vin", None) if not vin: LOGGER.debug("No VIN found in VEPUpdate data: %s", vep_json) return self._build_car(vep_json, update_mode=False, is_rest_data=True) if not self._first_vepupdates_processed: self._vepupdates_time_first_message = datetime.now() self._first_vepupdates_processed = True self._hass.loop.call_later( 30, lambda: self._hass.async_add_executor_job(self._safe_create_on_dataload_complete_task) ) self._build_car(vep_json, update_mode=False) if self._dataload_complete_fired: current_car = self.cars.get(vin) current_car.data_collection_mode = "pull" if current_car: current_car.publish_updates() if not self._dataload_complete_fired: fire_complete_event: bool = True for car in self.cars.values(): if not car.entry_setup_complete: fire_complete_event = False LOGGER.debug( "_process_vep_updates - %s - complete: %s - %s", loghelper.Mask_VIN(car.finorvin), car.entry_setup_complete, car.messages_received, ) if fire_complete_event: LOGGER.debug("_process_vep_updates - all completed - fire event: _on_dataload_complete") self._hass.async_create_task(self._on_dataload_complete()) self._dataload_complete_fired = True def _process_vep_updates(self, data): LOGGER.debug("Start _process_vep_updates") self._write_debug_output(data, "vep") # Don't understand the protobuf dict errors --> convert to json vep_json = json.loads(MessageToJson(data, preserving_proto_field_name=True)) cars = vep_json["vepUpdates"]["updates"] if not self._first_vepupdates_processed: self._vepupdates_time_first_message = datetime.now() self._first_vepupdates_processed = True self._hass.loop.call_later( 30, lambda: self._hass.async_add_executor_job(self._safe_create_on_dataload_complete_task) ) for vin in cars: if vin in self.excluded_cars: continue current_car = cars.get(vin) if DEBUG_SIMULATE_PARTIAL_UPDATES_ONLY and current_car.get("full_update", False) is True: current_car["full_update"] = False LOGGER.debug( "DEBUG_SIMULATE_PARTIAL_UPDATES_ONLY mode. %s", loghelper.Mask_VIN(vin), ) if current_car.get("full_update") is True: LOGGER.debug("Full Update. %s", loghelper.Mask_VIN(vin)) if not self._disable_rlock: with self.__lock: self._build_car(current_car, update_mode=False) else: self._build_car(current_car, update_mode=False) else: LOGGER.debug("Partial Update. %s", loghelper.Mask_VIN(vin)) if not self._disable_rlock: with self.__lock: self._build_car(current_car, update_mode=True) else: self._build_car(current_car, update_mode=True) if self._dataload_complete_fired: current_car = self.cars.get(vin) current_car.data_collection_mode = "push" if current_car: current_car.publish_updates() # Check for newly available sensors after vep_update if self._coordinator_ref: self._hass.async_create_task(self._coordinator_ref.check_missing_sensors_for_vin(vin)) if not self._dataload_complete_fired: fire_complete_event: bool = True for car in self.cars.values(): if not car.entry_setup_complete: fire_complete_event = False LOGGER.debug( "_process_vep_updates - %s - complete: %s - %s", loghelper.Mask_VIN(car.finorvin), car.entry_setup_complete, car.messages_received, ) if fire_complete_event: LOGGER.debug("_process_vep_updates - all completed - fire event: _on_dataload_complete") self._hass.async_create_task(self._on_dataload_complete()) self._dataload_complete_fired = True def _process_assigned_vehicles(self, data): if not self._dataload_complete_fired: LOGGER.debug("Start _process_assigned_vehicles") # self._write_debug_output(data, "asv") if not self._disable_rlock: with self.__lock: for vin in data.assigned_vehicles.vins: if vin in self.excluded_cars: continue _car = self.cars.get(vin) if _car is None: current_car = Car(vin) current_car.licenseplate = vin self.cars[vin] = current_car else: for vin in data.assigned_vehicles.vins: if vin in self.excluded_cars: continue _car = self.cars.get(vin) if _car is None: current_car = Car(vin) current_car.licenseplate = vin self.cars[vin] = current_car current_time = int(round(time.time() * 1000)) for key, value in self.cars.items(): LOGGER.debug( "_process_assigned_vehicles - %s - %s - %s - %s", loghelper.Mask_VIN(key), value.entry_setup_complete, value.messages_received, current_time - value.last_message_received.value.timestamp(), ) def _process_apptwin_command_status_updates_by_vin(self, data): LOGGER.debug("Start _process_assigned_vehicles") # Don't understand the protobuf dict errors --> convert to json apptwin_json = json.loads(MessageToJson(data, preserving_proto_field_name=True)) self._write_debug_output(data, "acr") if apptwin_json["apptwin_command_status_updates_by_vin"]: if apptwin_json["apptwin_command_status_updates_by_vin"]["updates_by_vin"]: car = list(apptwin_json["apptwin_command_status_updates_by_vin"]["updates_by_vin"].keys())[0] car = apptwin_json["apptwin_command_status_updates_by_vin"]["updates_by_vin"][car] vin = car.get("vin", None) if vin: if car["updates_by_pid"]: command = list(car["updates_by_pid"].keys())[0] command = car["updates_by_pid"][command] if command: command_type = command.get("type") command_state = command.get("state") command_error_code = "" command_error_message = "" if command.get("errors"): for err in command["errors"]: command_error_code = err.get("code") command_error_message = err.get("message") LOGGER.warning( "Car action: %s failed. error_code: %s, error_message: %s", command_type, command_error_code, command_error_message, ) current_car = self.cars.get(vin) if current_car: current_car.last_command_type = command_type current_car.last_command_state = command_state current_car.last_command_error_code = command_error_code current_car.last_command_error_message = command_error_message current_car.last_command_time_stamp = command.get("timestamp_in_ms", 0) current_car.publish_updates() async def charge_program_configure(self, vin: str, program: int, max_soc: None | int = None) -> None: """Send the selected charge program to the car.""" if not self._is_car_feature_available(vin, "CHARGE_PROGRAM_CONFIGURE"): raise ServiceValidationError( "Can't set the charge program. Feature CHARGE_PROGRAM_CONFIGURE not availabe for this car." ) LOGGER.debug("Start charge_program_configure") message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) charge_programm = pb2_commands.ChargeProgramConfigure() charge_programm.charge_program = program if max_soc is not None: charge_programm.max_soc.value = max_soc else: try: current_charge_programs = getattr(self.cars.get(vin).electric, "chargePrograms", None) if current_charge_programs: charge_programm.max_soc.value = current_charge_programs.value[program].get("max_soc") except (KeyError, IndexError, TypeError, AttributeError) as err: LOGGER.warning( "charge_program_configure - Error: %s - %s", err, getattr(self.cars.get(vin).electric, "chargePrograms", None), ) message.commandRequest.charge_program_configure.CopyFrom(charge_programm) LOGGER.debug( "charge_program_configure - vin: %s - program: %s - max_soc: %s", loghelper.Mask_VIN(vin), charge_programm.charge_program, charge_programm.max_soc.value, ) await self.execute_car_command(message) LOGGER.debug("End charge_program_configure for vin %s", loghelper.Mask_VIN(vin)) async def charging_break_clocktimer_configure( self, vin: str, status_t1: str, start_t1: datetime.timedelta, stop_t1: datetime.timedelta, status_t2: str, start_t2: datetime.timedelta, stop_t2: datetime.timedelta, status_t3: str, start_t3: datetime.timedelta, stop_t3: datetime.timedelta, status_t4: str, start_t4: datetime.timedelta, stop_t4: datetime.timedelta, ) -> None: """Send the charging_break_clocktimer_configure command to the car.""" if not self._is_car_feature_available(vin, "chargingClockTimer"): LOGGER.warning( "Can't send charging_break_clocktimer_configure for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) config = pb2_commands.ChargingBreakClocktimerConfigure() entry_set: bool = False if status_t1 and start_t1 is not None and stop_t1 is not None and status_t1 in ("active", "inactive"): t1 = config.chargingbreak_clocktimer_configure_entry.add() t1.timerId = 1 if status_t1 == "active": t1.action = pb2_commands.ChargingBreakClockTimerEntryStatus.ACTIVE else: t1.action = pb2_commands.ChargingBreakClockTimerEntryStatus.INACTIVE t1.startTimeHour = start_t1.seconds // 3600 t1.startTimeMinute = (start_t1.seconds % 3600) // 60 t1.endTimeHour = stop_t1.seconds // 3600 t1.endTimeMinute = (stop_t1.seconds % 3600) // 60 entry_set = True if status_t2 and start_t2 is not None and stop_t2 is not None and status_t2 in ("active", "inactive"): t2 = config.chargingbreak_clocktimer_configure_entry.add() t2.timerId = 2 if status_t2 == "active": t2.action = pb2_commands.ChargingBreakClockTimerEntryStatus.ACTIVE else: t2.action = pb2_commands.ChargingBreakClockTimerEntryStatus.INACTIVE t2.startTimeHour = start_t2.seconds // 3600 t2.startTimeMinute = (start_t2.seconds % 3600) // 60 t2.endTimeHour = stop_t2.seconds // 3600 t2.endTimeMinute = (stop_t2.seconds % 3600) // 60 entry_set = True if status_t3 and start_t3 is not None and stop_t3 is not None and status_t3 in ("active", "inactive"): t3 = config.chargingbreak_clocktimer_configure_entry.add() t3.timerId = 3 if status_t3 == "active": t3.action = pb2_commands.ChargingBreakClockTimerEntryStatus.ACTIVE else: t3.action = pb2_commands.ChargingBreakClockTimerEntryStatus.INACTIVE t3.startTimeHour = start_t3.seconds // 3600 t3.startTimeMinute = (start_t3.seconds % 3600) // 60 t3.endTimeHour = stop_t3.seconds // 3600 t3.endTimeMinute = (stop_t3.seconds % 3600) // 60 entry_set = True if status_t4 and start_t4 is not None and stop_t4 is not None and status_t4 in ("active", "inactive"): t4 = config.chargingbreak_clocktimer_configure_entry.add() t4.timerId = 4 if status_t4 == "active": t4.action = pb2_commands.ChargingBreakClockTimerEntryStatus.ACTIVE else: t4.action = pb2_commands.ChargingBreakClockTimerEntryStatus.INACTIVE t4.startTimeHour = start_t4.seconds // 3600 t4.startTimeMinute = (start_t4.seconds % 3600) // 60 t4.endTimeHour = stop_t4.seconds // 3600 t4.endTimeMinute = (stop_t4.seconds % 3600) // 60 entry_set = True if entry_set: message.commandRequest.chargingbreak_clocktimer_configure.CopyFrom(config) await self.execute_car_command(message) LOGGER.info( "End charging_break_clocktimer_configure for vin %s", loghelper.Mask_VIN(vin), ) else: LOGGER.info( "End charging_break_clocktimer_configure for vin %s - No actions", loghelper.Mask_VIN(vin), ) return async def doors_unlock(self, vin: str, pin: str = ""): """Send the doors unlock command to the car.""" if not self._is_car_feature_available(vin, "DOORS_UNLOCK"): LOGGER.warning( "Can't unlock car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return if pin and pin.strip(): LOGGER.debug("Start unlock with user provided pin") await self.doors_unlock_with_pin(vin, pin) return if not self.pin: LOGGER.warning( "Can't unlock car %s. PIN not set. Please set the PIN -> Integration, Options ", loghelper.Mask_VIN(vin), ) return await self.doors_unlock_with_pin(vin, self.pin) async def doors_unlock_with_pin(self, vin: str, pin: str): """Send the doors unlock command to the car.""" LOGGER.info("Start Doors_unlock_with_pin for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "DOORS_UNLOCK"): LOGGER.warning( "Can't unlock car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() if not pin: LOGGER.warning("Can't unlock car %s. Pin is required.", loghelper.Mask_VIN(vin)) return message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.doors_unlock.pin = pin await self.execute_car_command(message) LOGGER.info("End Doors_unlock for vin %s", loghelper.Mask_VIN(vin)) async def doors_lock(self, vin: str): """Send the doors lock command to the car.""" LOGGER.info("Start Doors_lock for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "DOORS_LOCK"): LOGGER.warning( "Can't lock car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.doors_lock.doors.extend([]) await self.execute_car_command(message) LOGGER.info("End Doors_lock for vin %s", loghelper.Mask_VIN(vin)) async def download_images(self, vin: str): """Download the car related images.""" LOGGER.info("Start download_images for vin %s", loghelper.Mask_VIN(vin)) download_path = self._hass.config.path(DEFAULT_DOWNLOAD_PATH) target_file_name = Path(download_path, f"{vin}.zip") zip_file = await self.webapi.download_images(vin) if zip_file: Path(download_path).mkdir(parents=True, exist_ok=True) def save_images() -> None: with Path(target_file_name).open(mode="wb") as zf: zf.write(zip_file) try: await self._hass.async_add_executor_job(save_images) except OSError as err: LOGGER.error("Can't write %s: %s", target_file_name, err) LOGGER.info("End download_images for vin %s", loghelper.Mask_VIN(vin)) async def auxheat_configure(self, vin: str, time_selection: int, time_1: int, time_2: int, time_3: int): """Send the auxheat configure command to the car.""" LOGGER.info("Start auxheat_configure for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, feature_list=["AUXHEAT_CONFIGURE", "auxHeat"]): LOGGER.warning( "Can't start auxheat_configure for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) auxheat_configure = pb2_commands.AuxheatConfigure() auxheat_configure.time_selection = time_selection auxheat_configure.time_1 = time_1 auxheat_configure.time_2 = time_2 auxheat_configure.time_3 = time_3 message.commandRequest.auxheat_configure.CopyFrom(auxheat_configure) await self.execute_car_command(message) LOGGER.info("End auxheat_configure for vin %s", loghelper.Mask_VIN(vin)) async def auxheat_start(self, vin: str): """Send the auxheat start command to the car.""" LOGGER.info("Start auxheat start for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, feature_list=["AUXHEAT_START", "auxHeat"]): LOGGER.warning( "Can't start auxheat for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) auxheat_start = pb2_commands.AuxheatStart() message.commandRequest.auxheat_start.CopyFrom(auxheat_start) await self.execute_car_command(message) LOGGER.info("End auxheat start for vin %s", loghelper.Mask_VIN(vin)) async def auxheat_stop(self, vin: str): """Send the auxheat stop command to the car.""" LOGGER.info("Start auxheat_stop for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, feature_list=["AUXHEAT_STOP", "auxHeat"]): LOGGER.warning( "Can't stop auxheat for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) auxheat_stop = pb2_commands.AuxheatStop() message.commandRequest.auxheat_stop.CopyFrom(auxheat_stop) await self.execute_car_command(message) LOGGER.info("End auxheat_stop for vin %s", loghelper.Mask_VIN(vin)) async def battery_max_soc_configure(self, vin: str, max_soc: int, charge_program: int = 0): """Send the maxsoc configure command to the car.""" LOGGER.info( "Start battery_max_soc_configure to %s for vin %s and program %s", max_soc, loghelper.Mask_VIN(vin), charge_program, ) if not self._is_car_feature_available(vin, "BATTERY_MAX_SOC_CONFIGURE") and not self._is_car_feature_available( vin, "CHARGING_CONFIGURE" ): LOGGER.warning( "Can't configure battery_max_soc for car %s. Features BATTERY_MAX_SOC_CONFIGURE or CHARGING_CONFIGURE not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) if self._is_car_feature_available(vin, "CHARGING_CONFIGURE"): LOGGER.debug( "CHARGING_CONFIGURE=true for car %s. Will use ChargingConfigure.", loghelper.Mask_VIN(vin), ) charging_config = pb2_commands.ChargingConfigure() charging_config.max_soc.value = max_soc # charging_config.charge_program = charge_program message.commandRequest.charging_configure.CopyFrom(charging_config) else: max_soc = max(max_soc, 50) charge_program_config = pb2_commands.ChargeProgramConfigure() charge_program_config.max_soc.value = max_soc charge_program_config.charge_program = charge_program message.commandRequest.charge_program_configure.CopyFrom(charge_program_config) await self.execute_car_command(message) LOGGER.info("End battery_max_soc_configure for vin %s", loghelper.Mask_VIN(vin)) async def engine_start(self, vin: str, pin: str = ""): """Send the engine start command to the car.""" LOGGER.info("Start engine start for vin %s", loghelper.Mask_VIN(vin)) if pin and pin.strip(): _pin = pin else: _pin = self.pin if not _pin: LOGGER.warning( "Can't start the car %s. PIN not given. Please set the PIN -> Integration, Options or use the optional parameter of the service.", loghelper.Mask_VIN(vin), ) return if not self._is_car_feature_available(vin, "ENGINE_START"): LOGGER.warning( "Can't start engine for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.engine_start.pin = _pin await self.execute_car_command(message) LOGGER.info("End engine start for vin %s", loghelper.Mask_VIN(vin)) async def engine_stop(self, vin: str): """Send the engine stop command to the car.""" LOGGER.info("Start engine_stop for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "ENGINE_STOP"): LOGGER.warning( "Can't stop engine for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) engine_stop = pb2_commands.EngineStop() message.commandRequest.engine_stop.CopyFrom(engine_stop) await self.execute_car_command(message) LOGGER.info("End engine_stop for vin %s", loghelper.Mask_VIN(vin)) async def hv_battery_start_conditioning(self, vin: str): """Send the hv battery conditioning start command to the car.""" LOGGER.info("Start hv_battery_start_conditioning for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "HVBATTERY_START_CONDITIONING"): LOGGER.warning( "Can't start hv battery conditioning for car %s. Feature not available for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) hv_battery_conditioning_start = pb2_commands.HvBatteryStartConditioning() message.commandRequest.hv_battery_start_conditioning.CopyFrom(hv_battery_conditioning_start) await self.execute_car_command(message) LOGGER.info("End hv_battery_start_conditioning for vin %s", loghelper.Mask_VIN(vin)) async def hv_battery_stop_conditioning(self, vin: str): """Send the hv battery conditioning stop command to the car.""" LOGGER.info("Start hv_battery_stop_conditioning for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "HVBATTERY_STOP_CONDITIONING"): LOGGER.warning( "Can't stop hv battery conditioning for car %s. Feature not available for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) hv_battery_conditioning_stop = pb2_commands.HvBatteryStopConditioning() message.commandRequest.hv_battery_stop_conditioning.CopyFrom(hv_battery_conditioning_stop) await self.execute_car_command(message) LOGGER.info("End hv_battery_stop_conditioning for vin %s", loghelper.Mask_VIN(vin)) async def send_route_to_car( self, vin: str, title: str, latitude: float, longitude: float, city: str, postcode: str, street: str, ): """Send a route target to the car.""" LOGGER.info("Start send_route_to_car for vin %s", loghelper.Mask_VIN(vin)) await self.webapi.send_route_to_car(vin, title, latitude, longitude, city, postcode, street) LOGGER.info("End send_route_to_car for vin %s", loghelper.Mask_VIN(vin)) async def sigpos_start(self, vin: str): """Send a sigpos command to the car.""" LOGGER.info("Start sigpos_start for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "SIGPOS_START"): LOGGER.warning( "Can't start signaling for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.sigpos_start.light_type = 1 message.commandRequest.sigpos_start.sigpos_type = 0 await self.execute_car_command(message) LOGGER.info("End sigpos_start for vin %s", loghelper.Mask_VIN(vin)) async def sunroof_open(self, vin: str, pin: str = ""): """Send a sunroof open command to the car.""" LOGGER.info("Start sunroof_open for vin %s", loghelper.Mask_VIN(vin)) if pin and pin.strip(): _pin = pin else: _pin = self.pin if not _pin: LOGGER.warning( "Can't open the sunroof - car %s. PIN not given. Please set the PIN -> Integration, Options or use the optional parameter of the service.", loghelper.Mask_VIN(vin), ) return if not self._is_car_feature_available(vin, "SUNROOF_OPEN"): LOGGER.warning( "Can't open the sunroof for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.sunroof_open.pin = _pin await self.execute_car_command(message) LOGGER.info("End sunroof_open for vin %s", loghelper.Mask_VIN(vin)) async def sunroof_tilt(self, vin: str, pin: str = ""): """Send a sunroof tilt command to the car.""" LOGGER.info("Start sunroof_tilt for vin %s", loghelper.Mask_VIN(vin)) if pin and pin.strip(): _pin = pin else: _pin = self.pin if not _pin: LOGGER.warning( "Can't tilt the sunroof - car %s. PIN not given. Please set the PIN -> Integration, Options or use the optional parameter of the service.", loghelper.Mask_VIN(vin), ) return if not self._is_car_feature_available(vin, "SUNROOF_LIFT"): LOGGER.warning( "Can't tilt the sunroof for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.sunroof_lift.pin = _pin await self.execute_car_command(message) LOGGER.info("End sunroof_tilt for vin %s", loghelper.Mask_VIN(vin)) async def sunroof_close(self, vin: str): """Send a sunroof close command to the car.""" LOGGER.info("Start sunroof_close for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "SUNROOF_CLOSE"): LOGGER.warning( "Can't close the sunroof for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) sunroof_close = pb2_commands.SunroofClose() message.commandRequest.sunroof_close.CopyFrom(sunroof_close) await self.execute_car_command(message) LOGGER.info("End sunroof_close for vin %s", loghelper.Mask_VIN(vin)) async def preconditioning_configure_seats( self, vin: str, front_left: bool, front_right: bool, rear_left: bool, rear_right: bool, ): """Send a preconditioning seat configuration command to the car.""" LOGGER.info("Start preconditioning_configure_seats for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "ZEV_PRECONDITION_CONFIGURE_SEATS"): LOGGER.warning( "Can't configure seats for PreCond for car %s. Feature %s not availabe for this car.", loghelper.Mask_VIN(vin), "ZEV_PRECONDITION_CONFIGURE_SEATS", ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.zev_precondition_configure_seats.front_left = front_left message.commandRequest.zev_precondition_configure_seats.front_right = front_right message.commandRequest.zev_precondition_configure_seats.rear_left = rear_left message.commandRequest.zev_precondition_configure_seats.rear_right = rear_right await self.execute_car_command(message) LOGGER.info("End preconditioning_configure_seats for vin %s", loghelper.Mask_VIN(vin)) async def preheat_start(self, vin: str): """Send a preconditioning start command to the car.""" LOGGER.info("Start preheat_start for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "ZEV_PRECONDITIONING_START"): LOGGER.warning( "Can't start PreCond for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.zev_preconditioning_start.departure_time = 0 message.commandRequest.zev_preconditioning_start.type = pb2_commands.ZEVPreconditioningType.now await self.execute_car_command(message) LOGGER.info("End preheat_start for vin %s", loghelper.Mask_VIN(vin)) async def preheat_start_immediate(self, vin: str): """Send a preconditioning immediatestart command to the car.""" LOGGER.info("Start preheat_start_immediate for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "ZEV_PRECONDITIONING_START"): LOGGER.warning( "Can't start PreCond for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.zev_preconditioning_start.departure_time = 0 message.commandRequest.zev_preconditioning_start.type = pb2_commands.ZEVPreconditioningType.immediate await self.execute_car_command(message) LOGGER.info("End preheat_start_immediate for vin %s", loghelper.Mask_VIN(vin)) async def preheat_start_universal(self, vin: str) -> None: """Turn on preheat universally for any car model.""" if self._is_car_feature_available(vin, "precondNow"): await self.preheat_start(vin) else: await self.preheat_start_immediate(vin) async def preheat_start_departure_time(self, vin: str, departure_time: int): """Send a preconditioning start by time command to the car.""" LOGGER.info("Start preheat_start_departure_time for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "ZEV_PRECONDITIONING_START"): LOGGER.warning( "Can't start PreCond for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.zev_preconditioning_start.departure_time = departure_time message.commandRequest.zev_preconditioning_start.type = pb2_commands.ZEVPreconditioningType.departure await self.execute_car_command(message) LOGGER.info("End preheat_start_departure_time for vin %s", loghelper.Mask_VIN(vin)) async def preheat_stop(self, vin: str): """Send a preconditioning stop command to the car.""" LOGGER.info("Start preheat_stop for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "ZEV_PRECONDITIONING_STOP"): LOGGER.warning( "Can't stop PreCond for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.zev_preconditioning_stop.type = pb2_commands.ZEVPreconditioningType.now await self.execute_car_command(message) LOGGER.info("End preheat_stop for vin %s", loghelper.Mask_VIN(vin)) async def preheat_stop_departure_time(self, vin: str): """Disable scheduled departure preconditioning.""" LOGGER.info("Start preheat_stop_departure_time for vin %s", loghelper.Mask_VIN(vin)) await self.preconditioning_configure(vin, departure_time_mode=0) LOGGER.info("End preheat_stop_departure_time for vin %s", loghelper.Mask_VIN(vin)) async def preconditioning_configure(self, vin: str, departure_time_mode: int = 0, departure_time: int = 0): """Configure preconditioning departure time mode. departure_time_mode: 0=DISABLED, 1=SINGLE_DEPARTURE, 2=WEEKLY_DEPARTURE Note: WEEKLY_DEPARTURE (mode 2) is not supported on all car models (e.g., EQB supports only DISABLED and SINGLE_DEPARTURE) departure_time: Minutes after midnight (0-1439), only used when mode > 0 """ LOGGER.info( "Start preconditioning_configure for vin %s with mode %s", loghelper.Mask_VIN(vin), departure_time_mode ) if not self._is_car_feature_available(vin, "ZEV_PRECONDITION_CONFIGURE"): LOGGER.warning( "Can't configure PreCond for car %s. Feature not available for this car", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.zev_precondition_configure.departure_time_mode = departure_time_mode if departure_time_mode > 0: message.commandRequest.zev_precondition_configure.departure_time = departure_time await self.execute_car_command(message) LOGGER.info("End preconditioning_configure for vin %s", loghelper.Mask_VIN(vin)) async def temperature_configure( self, vin: str, front_left: int | None = None, front_right: int | None = None, rear_left: int | None = None, rear_right: int | None = None, ): """Send a temperature_configure command to the car.""" LOGGER.info("Start temperature_configure for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "TEMPERATURE_CONFIGURE"): LOGGER.warning( "Can't configure the temperature zones for car %s. Feature %s not availabe for this car.", loghelper.Mask_VIN(vin), "TEMPERATURE_CONFIGURE", ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) config = pb2_commands.TemperatureConfigure() entry_set: bool = False car = self.cars.get(vin) if front_left or front_right or rear_left or rear_right: zone_front_left = config.temperature_points.add() zone_front_left.zone = 1 if front_left: zone_front_left.temperature_in_celsius = front_left elif car.precond.temperature_points_frontLeft: zone_front_left.temperature_in_celsius = car.precond.temperature_points_frontLeft.value entry_set = True if front_right or rear_left or rear_right: zone_front_right = config.temperature_points.add() zone_front_right.zone = 2 if front_right: zone_front_right.temperature_in_celsius = front_right elif car.precond.temperature_points_frontRight: zone_front_right.temperature_in_celsius = car.precond.temperature_points_frontRight.value entry_set = True if rear_left or rear_right: zone_rear_left = config.temperature_points.add() zone_rear_left.zone = 4 if rear_left: zone_rear_left.temperature_in_celsius = rear_left elif car.precond.temperature_points_rearLeft: zone_rear_left.temperature_in_celsius = car.precond.temperature_points_rearLeft.value entry_set = True if rear_right or rear_left: zone_rear_right = config.temperature_points.add() zone_rear_right.zone = 5 if rear_right: zone_rear_right.temperature_in_celsius = rear_right elif car.precond.temperature_points_rearRight: zone_rear_right.temperature_in_celsius = car.precond.temperature_points_rearRight.value entry_set = True if entry_set: message.commandRequest.temperature_configure.CopyFrom(config) self._hass.async_add_executor_job( self.write_debug_json_output, MessageToJson(message, preserving_proto_field_name=True), "out_temperature_", False, ) await self.execute_car_command(message) LOGGER.info("End temperature_configure for vin %s", loghelper.Mask_VIN(vin)) else: LOGGER.info( "End temperature_configure for vin %s - No actions", loghelper.Mask_VIN(vin), ) async def windows_open(self, vin: str, pin: str = ""): """Send a window open command to the car.""" LOGGER.info("Start windows_open for vin %s", loghelper.Mask_VIN(vin)) _pin: str = None if not self._is_car_feature_available(vin, "WINDOWS_OPEN"): LOGGER.warning( "Can't open the windows for car %s. Feature not marked as available for this car.", loghelper.Mask_VIN(vin), ) return if pin and pin.strip(): _pin = pin else: _pin = self.pin if not _pin: LOGGER.warning( "Can't open the windows - car %s. PIN not given. Please set the PIN -> Integration, Options or use the optional parameter of the service.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.windows_open.pin = _pin await self.execute_car_command(message) LOGGER.info("End windows_open for vin %s", loghelper.Mask_VIN(vin)) async def windows_close(self, vin: str): """Send a window close command to the car.""" LOGGER.info("Start windows_close for vin %s", loghelper.Mask_VIN(vin)) if not self._is_car_feature_available(vin, "WINDOWS_CLOSE"): LOGGER.warning( "Can't close the windows for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) windows_close = pb2_commands.WindowsClose() message.commandRequest.windows_close.CopyFrom(windows_close) await self.execute_car_command(message) LOGGER.info("End windows_close for vin %s", loghelper.Mask_VIN(vin)) async def windows_move( self, vin: str, front_left: int, front_right: int, rear_left: int, rear_right: int, pin: str = "" ): """Send the windows move command to the car.""" LOGGER.info( "Start windows_move for vin %s, fl-%s, fr-%s, rl-%s, rr-%s", loghelper.Mask_VIN(vin), front_left, front_right, rear_left, rear_right, ) if pin and pin.strip(): _pin = pin else: _pin = self.pin if not _pin: LOGGER.warning( "Can't move the windows - car %s. PIN not given. Please set the PIN -> Integration, Options or use the optional parameter of the service.", loghelper.Mask_VIN(vin), ) return if not self._is_car_feature_available(vin, "variableOpenableWindow"): LOGGER.warning( "Can't move windows for car %s. Feature not availabe for this car.", loghelper.Mask_VIN(vin), ) return message = client_pb2.ClientMessage() message.commandRequest.vin = vin message.commandRequest.request_id = str(uuid.uuid4()) message.commandRequest.windows_move.pin = _pin if front_left is not None: if front_left == 0: message.commandRequest.windows_move.front_left.SetInParent() else: message.commandRequest.windows_move.front_left.value = front_left if front_right is not None: if front_right == 0: message.commandRequest.windows_move.front_right.SetInParent() else: message.commandRequest.windows_move.front_right.value = front_right if rear_left is not None: if rear_left == 0: message.commandRequest.windows_move.rear_left.SetInParent() else: message.commandRequest.windows_move.rear_left.value = rear_left if rear_right is not None: if rear_right == 0: message.commandRequest.windows_move.rear_right.SetInParent() else: message.commandRequest.windows_move.rear_right.value = rear_right await self.execute_car_command(message) LOGGER.info("End windows_move for vin %s", loghelper.Mask_VIN(vin)) async def execute_car_command(self, message): """Execute a car command.""" LOGGER.debug("execute_car_command - ws-connection: %s", self.websocket.connection_state) await self.websocket.call(message.SerializeToString(), car_command=True) def _is_car_feature_available(self, vin: str, feature: str = "", feature_list=None) -> bool: if self.config_entry.options.get(CONF_FT_DISABLE_CAPABILITY_CHECK, False): return True current_car = self.cars.get(vin) if current_car: if feature_list: return current_car.check_capabilities(feature_list) if feature: return current_car.features.get(feature, False) return False def _write_debug_output(self, data, datatype): if self.config_entry.options.get(CONF_DEBUG_FILE_SAVE, False): self._hass.async_add_executor_job(self.__write_debug_output, data, datatype) def __write_debug_output(self, data, datatype): if self.config_entry.options.get(CONF_DEBUG_FILE_SAVE, False): # LOGGER.debug("Start _write_debug_output") path = self._debug_save_path Path(path).mkdir(parents=True, exist_ok=True) with Path(f"{path}/{datatype}{int(round(time.time() * 1000))}").open("wb") as current_file: current_file.write(data.SerializeToString()) self.write_debug_json_output(MessageToJson(data, preserving_proto_field_name=True), datatype) def write_debug_json_output(self, data, datatype, use_dumps: bool = False): """Write text to files based on datatype.""" # LOGGER.debug(self.config_entry.options) if self.config_entry.options.get(CONF_DEBUG_FILE_SAVE, False): path = self._debug_save_path Path(path).mkdir(parents=True, exist_ok=True) with Path(f"{path}/{datatype}{int(round(time.time() * 1000))}.json").open( "w", encoding="utf-8" ) as current_file: if use_dumps: current_file.write(f"{json.dumps(data, indent=4)}") else: current_file.write(f"{data}") async def set_rlock_mode(self): """Set thread locking mode on init.""" # In rare cases the ha-core system_info component runs in error when detecting the supervisor # See https://github.com/ReneNulschDE/mbapi2020/issues/126 info = None try: info = await system_info.async_get_system_info(self._hass) except AttributeError: LOGGER.debug("WSL detection not possible. Error in HA-Core get_system_info. Force rlock mode.") if info and "WSL" not in str(info.get("os_version")): self._disable_rlock = False self.__lock = threading.RLock() LOGGER.debug("WSL not detected - running in rlock mode") else: self._disable_rlock = True self.__lock = None LOGGER.debug("WSL detected - rlock mode disabled") return info async def update_poll_states(self, vin: str): """Update the values for poll states, currently geofencing only.""" if vin in self.cars: car = self.cars[vin] if self.websocket and self.websocket.account_blocked: LOGGER.debug("start get_car_p2b_data_via_rest: %s", loghelper.Mask_VIN(vin)) p2b_data = await self.webapi.get_car_p2b_data_via_rest(vin) self._process_rest_vep_update(p2b_data) if not car.has_geofencing: return if car.geofence_events is None: car.geofence_events = GeofenceEvents() LOGGER.debug("start get_car_geofencing_violations: %s", loghelper.Mask_VIN(vin)) geofencing_violotions = await self.webapi.get_car_geofencing_violations(car.finorvin) if geofencing_violotions and len(geofencing_violotions) > 0: car.geofence_events.last_event_type = CarAttribute( geofencing_violotions[-1].get("type"), "VALID", geofencing_violotions[-1].get("time"), ) car.geofence_events.last_event_timestamp = CarAttribute( geofencing_violotions[-1].get("time"), "VALID", geofencing_violotions[-1].get("time"), ) car.geofence_events.last_event_zone = CarAttribute( geofencing_violotions[-1].get("snapshot").get("name"), "VALID", geofencing_violotions[-1].get("time"), ) car.has_geofencing = True car.geo_fencing_retry_counter = 0 else: if car.geo_fencing_retry_counter >= GEOFENCING_MAX_RETRIES: car.has_geofencing = False car.geo_fencing_retry_counter = car.geo_fencing_retry_counter + 1 def _safe_create_on_dataload_complete_task(self): """Create task in a thread-safe way.""" # Zurück zum Event Loop asyncio.run_coroutine_threadsafe(self._on_dataload_complete(), self._hass.loop) ================================================ FILE: custom_components/mbapi2020/config_flow.py ================================================ """Config flow for mbapi2020 integration.""" from __future__ import annotations from copy import deepcopy import uuid from awesomeversion import AwesomeVersion import voluptuous as vol from homeassistant import config_entries from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, __version__ as HAVERSION from homeassistant.core import callback from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.storage import STORAGE_DIR from .client import Client from .const import ( CONF_ALLOWED_REGIONS, CONF_DEBUG_FILE_SAVE, CONF_DELETE_AUTH_FILE, CONF_ENABLE_CHINA_GCJ_02, CONF_EXCLUDED_CARS, CONF_FT_DISABLE_CAPABILITY_CHECK, CONF_OVERWRITE_PRECONDNOW, CONF_PIN, CONF_REGION, DOMAIN, LOGGER, REGION_CHINA, TOKEN_FILE_PREFIX, VERIFY_SSL, ) from .errors import MbapiError, MBAuth2FAError, MBAuthError, MBLegalTermsError AUTH_METHOD_TOKEN = "token" AUTH_METHOD_USERPASS = "userpass" REGION_SCHEMA = vol.Schema( { vol.Required(CONF_REGION): vol.In(CONF_ALLOWED_REGIONS), } ) USER_SCHEMA = vol.Schema( { vol.Required(CONF_USERNAME): str, vol.Required(CONF_PASSWORD): str, } ) USER_SCHEMA_CHINA = vol.Schema( { vol.Required(CONF_USERNAME): str, } ) USER_STEP_PIN = vol.Schema({vol.Required(CONF_PASSWORD): str}) # Version threshold for config_entry setting in options flow # See: https://github.com/home-assistant/core/pull/129562 HA_OPTIONS_FLOW_VERSION_THRESHOLD = "2024.11.99" class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): """Handle a config flow for mbapi2020.""" VERSION = 1 def __init__(self): """Initialize the ConfigFlow state.""" self._reauth_entry = None self._data = None self._reauth_mode = False self._auth_method = AUTH_METHOD_TOKEN self._region = None async def async_step_user(self, user_input=None): """Region selection step.""" if user_input is not None: self._region = user_input[CONF_REGION] return await self.async_step_credentials() return self.async_show_form(step_id="user", data_schema=REGION_SCHEMA) async def async_step_credentials(self, user_input=None): """Credentials step - username/password or username only for China.""" is_china = self._region == REGION_CHINA schema = USER_SCHEMA_CHINA if is_china else USER_SCHEMA if user_input is not None: user_input[CONF_REGION] = self._region await self.async_set_unique_id(f"{user_input[CONF_USERNAME]}-{user_input[CONF_REGION]}") if not self._reauth_mode: self._abort_if_unique_id_configured() session = async_get_clientsession(self.hass, VERIFY_SSL) client = Client(self.hass, session, None, region=user_input[CONF_REGION]) user_input[CONF_USERNAME] = user_input[CONF_USERNAME].strip() if is_china: nonce = str(uuid.uuid4()) user_input["nonce"] = nonce user_input["device_guid"] = client.oauth._device_guid # noqa: SLF001 errors = {} try: await client.oauth.request_pin(user_input[CONF_USERNAME], nonce) except (MBAuthError, MbapiError): errors = {"base": "pinrequest_failed"} return self.async_show_form(step_id="credentials", data_schema=schema, errors=errors) if not errors: self._data = user_input return await self.async_step_pin() LOGGER.error("Request PIN error: %s", errors) self._data = { CONF_USERNAME: user_input[CONF_USERNAME], CONF_REGION: user_input[CONF_REGION], "nonce": nonce, "device_guid": user_input["device_guid"], } else: try: token_info = await client.oauth.async_login_new( user_input[CONF_USERNAME], user_input[CONF_PASSWORD] ) except (MBAuthError, MbapiError) as error: LOGGER.error("Login error: %s", error) return self.async_show_form( step_id="credentials", data_schema=schema, errors={"base": "invalid_auth"} ) except MBAuth2FAError as error: LOGGER.error("Login error - 2FA accounts are not supported: %s", error) return self.async_show_form( step_id="credentials", data_schema=schema, errors={"base": "2fa_required"} ) except MBLegalTermsError as error: LOGGER.error("Login error - Legal terms not accepted: %s", error) return self.async_show_form( step_id="credentials", data_schema=schema, errors={"base": "legal_terms"} ) self._data = { CONF_USERNAME: user_input[CONF_USERNAME], CONF_REGION: user_input[CONF_REGION], CONF_PASSWORD: user_input[CONF_PASSWORD], "token": token_info, "device_guid": client.oauth._device_guid, # noqa: SLF001 } if self._reauth_mode: self.hass.config_entries.async_update_entry(self._reauth_entry, data=self._data) self.hass.config_entries.async_schedule_reload(self._reauth_entry.entry_id) return self.async_abort(reason="reauth_successful") return self.async_create_entry( title=f"{self._data[CONF_USERNAME]} (Region: {self._data[CONF_REGION]})", data=self._data, ) return self.async_show_form(step_id="credentials", data_schema=schema) async def async_step_pin(self, user_input=None): """Handle the step where the user inputs his/her station.""" errors = {} if user_input is not None: pin = user_input[CONF_PASSWORD] nonce = self._data["nonce"] new_config_entry: config_entries.ConfigEntry = await self.async_set_unique_id( f"{self._data[CONF_USERNAME]}-{self._data[CONF_REGION]}" ) session = async_get_clientsession(self.hass, VERIFY_SSL) client = Client(self.hass, session, new_config_entry, self._data[CONF_REGION]) try: result = await client.oauth.request_access_token_with_pin(self._data[CONF_USERNAME], pin, nonce) except MbapiError as error: LOGGER.error("Request token error: %s", error) errors = {"base": "token_with_pin_request_failed"} if not errors: LOGGER.debug("Token received") self._data["token"] = result if self._reauth_mode: self.hass.config_entries.async_update_entry(self._reauth_entry, data=self._data) self.hass.async_create_task(self.hass.config_entries.async_reload(self._reauth_entry.entry_id)) return self.async_abort(reason="reauth_successful") return self.async_create_entry( title=f"{self._data[CONF_USERNAME]} (Region: {self._data[CONF_REGION]})", data=self._data, ) return self.async_show_form(step_id="pin", data_schema=USER_STEP_PIN, errors=errors) async def async_step_reauth(self, user_input=None): """Get new tokens for a config entry that can't authenticate.""" self._reauth_mode = True self._reauth_entry = self.hass.config_entries.async_get_entry(self.context["entry_id"]) self._region = self._reauth_entry.data.get(CONF_REGION) return await self.async_step_credentials() # async def async_step_reconfigure(self, user_input=None): # """Get new tokens for a config entry that can't authenticate.""" # self._reauth_mode = True # self._reauth_entry = self.hass.config_entries.async_get_entry(self.context["entry_id"]) # return self.async_show_form(step_id="user", data_schema=SCHEMA_STEP_AUTH_SELECT) @staticmethod @callback def async_get_options_flow(config_entry): """Get options flow.""" return OptionsFlowHandler(config_entry) class OptionsFlowHandler(config_entries.OptionsFlow): """Options flow handler.""" def __init__(self, config_entry: config_entries.ConfigEntry) -> None: """Initialize MBAI2020 options flow.""" self.options = dict(config_entry.options) # See: https://github.com/home-assistant/core/pull/129562 if AwesomeVersion(HAVERSION) < HA_OPTIONS_FLOW_VERSION_THRESHOLD: self.config_entry = config_entry async def async_step_init(self, user_input=None): """Manage the options.""" if user_input is not None: LOGGER.debug( "user_input: %s", {k: ("xxxx" if v else v) if k == CONF_PIN else v for k, v in user_input.items()}, ) if user_input[CONF_DELETE_AUTH_FILE] is True: auth_file = self.hass.config.path(STORAGE_DIR, f"{TOKEN_FILE_PREFIX}-{self.config_entry.entry_id}") LOGGER.warning("DELETE Auth Information requested %s", auth_file) new_config_entry_data = deepcopy(dict(self.config_entry.data)) new_config_entry_data["token"] = None changed = self.hass.config_entries.async_update_entry(self.config_entry, data=new_config_entry_data) LOGGER.debug("%s Creating restart_required issue", DOMAIN) async_create_issue( hass=self.hass, domain=DOMAIN, issue_id="restart_required_auth_deleted", is_fixable=True, issue_domain=DOMAIN, severity=IssueSeverity.WARNING, translation_key="restart_required", translation_placeholders={ "name": DOMAIN, }, ) self.options.update(user_input) changed = self.hass.config_entries.async_update_entry( self.config_entry, options=user_input, ) if changed: await self.hass.config_entries.async_reload(self.config_entry.entry_id) return self.async_create_entry(title=DOMAIN, data=self.options) excluded_cars = self.options.get(CONF_EXCLUDED_CARS, "") pin = self.options.get(CONF_PIN, "") cap_check_disabled = self.options.get(CONF_FT_DISABLE_CAPABILITY_CHECK, False) save_debug_files = self.options.get(CONF_DEBUG_FILE_SAVE, False) enable_china_gcj_02 = self.options.get(CONF_ENABLE_CHINA_GCJ_02, False) overwrite_cap_precondnow = self.options.get(CONF_OVERWRITE_PRECONDNOW, False) return self.async_show_form( step_id="init", data_schema=vol.Schema( { vol.Optional(CONF_EXCLUDED_CARS, default="", description={"suggested_value": excluded_cars}): str, vol.Optional(CONF_PIN, default="", description={"suggested_value": pin}): str, vol.Optional(CONF_FT_DISABLE_CAPABILITY_CHECK, default=cap_check_disabled): bool, vol.Optional(CONF_DEBUG_FILE_SAVE, default=save_debug_files): bool, vol.Optional(CONF_DELETE_AUTH_FILE, default=False): bool, vol.Optional(CONF_ENABLE_CHINA_GCJ_02, default=enable_china_gcj_02): bool, vol.Optional(CONF_OVERWRITE_PRECONDNOW, default=overwrite_cap_precondnow): bool, } ), ) ================================================ FILE: custom_components/mbapi2020/const.py ================================================ """Constants for the MercedesME 2020 integration.""" from __future__ import annotations from datetime import timedelta from enum import Enum, StrEnum import logging import voluptuous as vol from homeassistant.components.binary_sensor import BinarySensorDeviceClass from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass from homeassistant.const import ( PERCENTAGE, EntityCategory, Platform, UnitOfEnergy, UnitOfLength, UnitOfMass, UnitOfPower, UnitOfPressure, UnitOfSpeed, UnitOfTemperature, UnitOfVolume, ) from homeassistant.helpers import config_validation as cv MERCEDESME_COMPONENTS = [ Platform.SENSOR, Platform.LOCK, Platform.BINARY_SENSOR, Platform.BUTTON, Platform.DEVICE_TRACKER, Platform.SWITCH, ] REGION_EUROPE = "Europe" REGION_NORAM = "North America" REGION_APAC = "Asia-Pacific" REGION_CHINA = "China" CONF_ALLOWED_REGIONS = [REGION_EUROPE, REGION_NORAM, REGION_APAC, REGION_CHINA] CONF_LOCALE = "locale" CONF_COUNTRY_CODE = "country_code" CONF_EXCLUDED_CARS = "excluded_cars" CONF_PIN = "pin" CONF_REGION = "region" CONF_VIN = "vin" CONF_TIME = "time" CONF_DEBUG_FILE_SAVE = "save_files" CONF_FT_DISABLE_CAPABILITY_CHECK = "cap_check_disabled" CONF_DELETE_AUTH_FILE = "delete_auth_file" CONF_ENABLE_CHINA_GCJ_02 = "enable_china_gcj_02" CONF_AUTH_METHOD = "auth_method" CONF_ACCESS_TOKEN = "access_token" CONF_REFRESH_TOKEN = "refresh_token" CONF_OVERWRITE_PRECONDNOW = "overwrite_cap_precondnow" DOMAIN = "mbapi2020" LOGGER = logging.getLogger(__package__) UPDATE_INTERVAL = timedelta(seconds=180) # Duration to wait for state confirmation of interactive entitiess in seconds STATE_CONFIRMATION_DURATION = 60 DEFAULT_CACHE_PATH = "custom_components/mbapi2020/messages" DEFAULT_DOWNLOAD_PATH = "custom_components/mbapi2020/resources" DEFAULT_LOCALE = "en-GB" DEFAULT_COUNTRY_CODE = "EN" TOKEN_FILE_PREFIX = ".mercedesme-token-cache" JSON_EXPORT_IGNORED_KEYS = ( "pin", "access_token", "refresh_token", "username", "unique_id", "nonce", "_update_listeners", "finorvin", "licenseplate", "fin", "licensePlate", "vin", "dealers", "positionLong", "positionHeading", "id_token", "password", "title", ) RIS_APPLICATION_VERSION_NA = "3.65.1" RIS_APPLICATION_VERSION_CN = "1.65.0" RIS_APPLICATION_VERSION_PA = "1.65.0" RIS_APPLICATION_VERSION = "1.65.1 (3174)" RIS_SDK_VERSION = "4.4.2" RIS_SDK_VERSION_CN = "2.132.2" RIS_OS_VERSION = "26.3" RIS_OS_NAME = "ios" X_APPLICATIONNAME = "mycar-store-ece" X_APPLICATIONNAME_ECE = "mycar-store-ece" X_APPLICATIONNAME_CN = "mycar-store-cn" X_APPLICATIONNAME_US = "mycar-store-us" X_APPLICATIONNAME_AP = "mycar-store-ap" USE_PROXY = False VERIFY_SSL = True SYSTEM_PROXY: str | None = None if not USE_PROXY else "http://192.168.178.68:9090" LOGIN_APP_ID_EU = "62778dc4-1de3-44f4-af95-115f06a3a008" LOGIN_APP_ID_CN = "3f36efb1-f84b-4402-b5a2-68a118fec33e" LOGIN_BASE_URI = "https://id.mercedes-benz.com" LOGIN_BASE_URI_CN = "https://ciam-1.mercedes-benz.com.cn" PSAG_BASE_URI = "https://psag.query.api.dvb.corpinter.net" PSAG_BASE_URI_CN = "https://psag.query.api.dvb.corpinter.net.cn" RCP_BASE_URI = "https://rcp-rs.query.api.dvb.corpinter.net" RCP_BASE_URI_CN = "https://rcp-rs.query.api.dvb.corpinter.net.cn" REST_API_BASE = "https://bff.emea-prod.mobilesdk.mercedes-benz.com" REST_API_BASE_CN = "https://bff.cn-prod.mobilesdk.mercedes-benz.com" REST_API_BASE_NA = "https://bff.amap-prod.mobilesdk.mercedes-benz.com" REST_API_BASE_PA = "https://bff.amap-prod.mobilesdk.mercedes-benz.com" WEBSOCKET_API_BASE = "wss://websocket.emea-prod.mobilesdk.mercedes-benz.com/v2/ws" WEBSOCKET_API_BASE_NA = "wss://websocket.amap-prod.mobilesdk.mercedes-benz.com/v2/ws" WEBSOCKET_API_BASE_PA = "wss://websocket.amap-prod.mobilesdk.mercedes-benz.com/v2/ws" WEBSOCKET_API_BASE_CN = "wss://websocket.cn-prod.mobilesdk.mercedes-benz.com/v2/ws" WEBSOCKET_USER_AGENT = "Mercedes-Benz/3044 CFNetwork/3860.400.22 Darwin/25.3.0" WEBSOCKET_USER_AGENT_CN = "MyStarCN/1.63.0 (com.daimler.ris.mercedesme.cn.ios; build:1758; iOS 16.3.1) Alamofire/5.4.0" WEBSOCKET_USER_AGENT_PA = ( f"mycar-store-ap {RIS_APPLICATION_VERSION}, {RIS_OS_NAME} {RIS_OS_VERSION}, SDK {RIS_SDK_VERSION}" ) WEBSOCKET_USER_AGENT_US = ( f"mycar-store-us v{RIS_APPLICATION_VERSION_NA}, {RIS_OS_NAME} {RIS_OS_VERSION}, SDK {RIS_SDK_VERSION}" ) WIDGET_API_BASE = "https://widget.emea-prod.mobilesdk.mercedes-benz.com" WIDGET_API_BASE_NA = "https://widget.amap-prod.mobilesdk.mercedes-benz.com" WIDGET_API_BASE_PA = "https://widget.amap-prod.mobilesdk.mercedes-benz.com" WIDGET_API_BASE_CN = "https://widget.cn-prod.mobilesdk.mercedes-benz.com" DEFAULT_SOCKET_MIN_RETRY = 15 SERVICE_AUXHEAT_CONFIGURE = "auxheat_configure" SERVICE_AUXHEAT_START = "auxheat_start" SERVICE_AUXHEAT_STOP = "auxheat_stop" SERVICE_BATTERY_MAX_SOC_CONFIGURE = "battery_max_soc_configure" SERVICE_CHARGE_PROGRAM_CONFIGURE = "charge_program_configure" SERVICE_CHARGING_BREAK_CLOCKTIMER_CONFIGURE = "charging_break_clocktimer_configure" SERVICE_DOORS_LOCK_URL = "doors_lock" SERVICE_DOORS_UNLOCK_URL = "doors_unlock" SERVICE_ENGINE_START = "engine_start" SERVICE_ENGINE_STOP = "engine_stop" SERVICE_SEND_ROUTE = "send_route" SERVICE_SIGPOS_START = "sigpos_start" SERVICE_SUNROOF_OPEN = "sunroof_open" SERVICE_SUNROOF_TILT = "sunroof_tilt" SERVICE_SUNROOF_CLOSE = "sunroof_close" SERVICE_PREHEAT_START = "preheat_start" SERVICE_PREHEAT_START_DEPARTURE_TIME = "preheat_start_departure_time" SERVICE_PREHEAT_STOP_DEPARTURE_TIME = "preheat_stop_departure_time" SERVICE_PREHEAT_STOP = "preheat_stop" SERVICE_PRECONDITIONING_CONFIGURE = "preconditioning_configure" SERVICE_WINDOWS_OPEN = "windows_open" SERVICE_WINDOWS_CLOSE = "windows_close" SERVICE_WINDOWS_MOVE = "windows_move" SERVICE_DOWNLOAD_IMAGES = "download_images" SERVICE_PRECONDITIONING_CONFIGURE_SEATS = "preconditioning_configure_seats" SERVICE_TEMPERATURE_CONFIGURE = "temperature_configure" SERVICE_HV_BATTERY_START_CONDITIONING = "hv_battery_start_conditioning" SERVICE_HV_BATTERY_STOP_CONDITIONING = "hv_battery_stop_conditioning" SERVICE_AUXHEAT_CONFIGURE_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Required("time_selection"): vol.All(vol.Coerce(int), vol.Range(min=0, max=3)), vol.Required("time_1"): vol.All(vol.Coerce(int), vol.Range(min=0, max=1439)), vol.Required("time_2"): vol.All(vol.Coerce(int), vol.Range(min=0, max=1439)), vol.Required("time_3"): vol.All(vol.Coerce(int), vol.Range(min=0, max=1439)), } ) SERVICE_CHARGING_BREAK_CLOCKTIMER_CONFIGURE_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Optional("status_timer_1"): cv.string, vol.Optional("starttime_timer_1"): cv.time_period, vol.Optional("stoptime_timer_1"): cv.time_period, vol.Optional("status_timer_2"): cv.string, vol.Optional("starttime_timer_2"): cv.time_period, vol.Optional("stoptime_timer_2"): cv.time_period, vol.Optional("status_timer_3"): cv.string, vol.Optional("starttime_timer_3"): cv.time_period, vol.Optional("stoptime_timer_3"): cv.time_period, vol.Optional("status_timer_4"): cv.string, vol.Optional("starttime_timer_4"): cv.time_period, vol.Optional("stoptime_timer_4"): cv.time_period, } ) SERVICE_PREHEAT_START_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Required("type", default=0): vol.All(vol.Coerce(int), vol.Range(min=0, max=1)), } ) SERVICE_SEND_ROUTE_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Required("title"): cv.string, vol.Required("latitude"): cv.latitude, vol.Required("longitude"): cv.longitude, vol.Required("city"): cv.string, vol.Required("postcode"): cv.string, vol.Required("street"): cv.string, } ) SERVICE_BATTERY_MAX_SOC_CONFIGURE_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Required("max_soc", default=100): vol.All(vol.Coerce(int), vol.In([30, 40, 50, 60, 70, 80, 90, 100])), vol.Optional("charge_program", default=0): vol.All(vol.Coerce(int), vol.In([0, 2, 3])), } ) SERVICE_VIN_SCHEMA = vol.Schema({vol.Required(CONF_VIN): cv.string}) SERVICE_VIN_PIN_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Optional(CONF_PIN): cv.string, } ) SERVICE_VIN_TIME_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Required(CONF_TIME): vol.All(vol.Coerce(int), vol.Range(min=0, max=1439)), } ) SERVICE_VIN_CHARGE_PROGRAM_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Required("charge_program", default=0): vol.All(vol.Coerce(int), vol.In([0, 2, 3])), vol.Optional("max_soc", default=None): vol.Any( None, vol.All(vol.Coerce(int), vol.In([50, 60, 70, 80, 90, 100])), ), } ) SERVICE_WINDOWS_MOVE_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Optional(CONF_PIN): cv.string, vol.Optional("front_left", default=None): vol.Any( None, vol.All(vol.Coerce(int), vol.In([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])), ), vol.Optional("front_right", default=None): vol.Any( None, vol.All(vol.Coerce(int), vol.In([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])), ), vol.Optional("rear_left", default=None): vol.Any( None, vol.All(vol.Coerce(int), vol.In([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])), ), vol.Optional("rear_right", default=None): vol.Any( None, vol.All(vol.Coerce(int), vol.In([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])), ), } ) SERVICE_TEMPERATURE_CONFIGURE_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Optional("front_left", default=None): vol.Any( None, vol.All( vol.Coerce(float), vol.In( [ 0, 16, 16.5, 17, 17.5, 18, 18.5, 19, 19.5, 20, 20.5, 21, 21.5, 22, 22.5, 23, 23.5, 24, 24.5, 25, 25.5, 26, 26.5, 27, 27.5, 28, 30, ] ), ), ), vol.Optional("front_right", default=None): vol.Any( None, vol.All( vol.Coerce(float), vol.In( [ 0, 16, 16.5, 17, 17.5, 18, 18.5, 19, 19.5, 20, 20.5, 21, 21.5, 22, 22.5, 23, 23.5, 24, 24.5, 25, 25.5, 26, 26.5, 27, 27.5, 28, 30, ] ), ), ), vol.Optional("rear_left", default=None): vol.Any( None, vol.All( vol.Coerce(float), vol.In( [ 0, 16, 16.5, 17, 17.5, 18, 18.5, 19, 19.5, 20, 20.5, 21, 21.5, 22, 22.5, 23, 23.5, 24, 24.5, 25, 25.5, 26, 26.5, 27, 27.5, 28, 30, ] ), ), ), vol.Optional("rear_right", default=None): vol.Any( None, vol.All( vol.Coerce(float), vol.In( [ 0, 16, 16.5, 17, 17.5, 18, 18.5, 19, 19.5, 20, 20.5, 21, 21.5, 22, 22.5, 23, 23.5, 24, 24.5, 25, 25.5, 26, 26.5, 27, 27.5, 28, 30, ] ), ), ), } ) SERVICE_PRECONDITIONING_CONFIGURE_SEATS_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Required("front_left"): cv.boolean, vol.Required("front_right"): cv.boolean, vol.Required("rear_left"): cv.boolean, vol.Required("rear_right"): cv.boolean, } ) SERVICE_PRECONDITIONING_CONFIGURE_SCHEMA = vol.Schema( { vol.Required(CONF_VIN): cv.string, vol.Required("departure_time_mode", default=0): vol.All(vol.Coerce(int), vol.In([0, 1, 2])), vol.Optional("departure_time", default=0): vol.All(vol.Coerce(int), vol.Range(min=0, max=1439)), } ) ATTR_MB_MANUFACTURER = "Mercedes Benz" BinarySensors = { "chargingactive": [ "Charging active", None, # Deprecated: DO NOT USE "electric", "chargingactive", "value", None, None, None, BinarySensorDeviceClass.BATTERY_CHARGING, False, None, None, None, None, ], "liquidRangeCritical": [ "Liquid Range Critical", None, # Deprecated: DO NOT USE "binarysensors", "liquidRangeCritical", "value", None, None, "mdi:gas-station", BinarySensorDeviceClass.PROBLEM, False, None, None, None, None, ], "warningbrakefluid": [ "Low Brake Fluid Warning", None, # Deprecated: DO NOT USE "binarysensors", "warningbrakefluid", "value", None, None, "mdi:car-brake-alert", BinarySensorDeviceClass.PROBLEM, False, None, None, None, None, ], "warningwashwater": [ "Low Wash Water Warning", None, # Deprecated: DO NOT USE "binarysensors", "warningwashwater", "value", None, None, "mdi:wiper-wash", BinarySensorDeviceClass.PROBLEM, False, None, None, None, None, ], "warningcoolantlevellow": [ "Low Coolant Level Warning", None, # Deprecated: DO NOT USE "binarysensors", "warningcoolantlevellow", "value", None, None, "mdi:oil-level", BinarySensorDeviceClass.PROBLEM, False, None, None, None, None, ], "warningenginelight": [ "Engine Light Warning", None, # Deprecated: DO NOT USE "binarysensors", "warningenginelight", "value", None, { "warningbrakefluid", "warningwashwater", "warningcoolantlevellow", "warninglowbattery", }, "mdi:engine", BinarySensorDeviceClass.PROBLEM, False, None, None, None, None, ], "parkbrakestatus": [ "Park Brake Status", None, # Deprecated: DO NOT USE "binarysensors", "parkbrakestatus", "value", None, {"preWarningBrakeLiningWear"}, "mdi:car-brake-parking", None, False, None, None, None, None, ], "windowStatusOverall": [ "Windows Closed", None, # Deprecated: DO NOT USE "windows", "windowStatusOverall", "value", None, { "windowstatusrearleft", "windowstatusrearright", "windowstatusfrontright", "windowstatusfrontleft", "windowstatusrearleftblind", "windowstatusrearrightblind", "windowstatusfrontrightblind", "windowstatusfrontleftblind", }, "mdi:car-door", None, False, None, None, None, None, ], "tirewarninglamp": [ "Tire Warning", None, # Deprecated: DO NOT USE "tires", "tirewarninglamp", "value", None, { "tireMarkerFrontRight", "tireMarkerFrontLeft", "tireMarkerRearLeft", "tireMarkerRearRight", "tirewarningsrdk", "tirewarningsprw", "tireTemperatureRearLeft", "tireTemperatureFrontRight", "tireTemperatureRearRight", "tireTemperatureFrontLeft", }, "mdi:car-tire-alert", BinarySensorDeviceClass.PROBLEM, False, None, None, None, None, ], "remoteStartActive": [ "Remote Start Active", None, # Deprecated: DO NOT USE "binarysensors", "remoteStartActive", "value", None, {"remoteStartTemperature"}, "mdi:engine-outline", None, False, None, None, None, None, ], "engineState": [ "Engine State", None, # Deprecated: DO NOT USE "binarysensors", "engineState", "value", None, None, "mdi:engine", None, False, None, None, None, None, ], "chargeflapacstatus": [ "Charge Flap AC Status", None, # Deprecated: DO NOT USE "doors", "chargeFlapACStatus", "value", None, {}, None, BinarySensorDeviceClass.DOOR, True, None, None, None, None, ], "preclimateStatus": [ "Preclimate Status", None, # Deprecated: DO NOT USE "precond", "precondStatus", "value", None, { "precondOperatingMode", "precondState", "precondActive", "precondError", "precondNow", "precondNowError", "precondDuration", "precondatdeparture", "precondAtDepartureDisable", "precondSeatFrontLeft", "precondSeatFrontRight", "precondSeatRearLeft", "precondSeatRearRight", "temperature_points_frontLeft", "temperature_points_frontRight", "temperature_points_rearLeft", "temperature_points_rearRight", }, "mdi:car-seat-heater", BinarySensorDeviceClass.RUNNING, False, None, None, None, None, ], "theftsystemarmed": [ "Theft system armed", None, # Deprecated: DO NOT USE "caralarm", "theftSystemArmed", "value", None, { "carAlarmLastTime", "carAlarmReason", "collisionAlarmTimestamp", "interiorSensor", "interiorProtectionStatus", "interiorMonitoringLastEvent", "interiorMonitoringStatus", "exteriorMonitoringLastEvent", "exteriorMonitoringStatus", "lastParkEvent", "lastTheftWarning", "lastTheftWarningReason", "parkEventLevel", "parkEventType", "theftAlarmActive", "towProtectionSensorStatus", "towSensor", }, "mdi:alarm-light", None, False, None, None, None, None, ], } BUTTONS = { "btn_preheat_start_now": [ "Preclimate start", None, # Deprecated: DO NOT USE None, "preheat_start", None, "ZEV_PRECONDITIONING_START", None, "mdi:hvac", None, False, None, None, None, None, ], "btn_preheat_stop_now": [ "Preclimate stop", None, # Deprecated: DO NOT USE None, "preheat_stop", None, "ZEV_PRECONDITIONING_STOP", None, "mdi:hvac", None, False, None, None, None, None, ], "btn_sigpos_start_now": [ "Signal position", None, # Deprecated: DO NOT USE None, "sigpos_start", None, "SIGPOS_START", None, "mdi:flashlight", None, False, None, None, None, None, ], } DEVICE_TRACKER = { "tracker": [ "Device Tracker", None, # Deprecated: DO NOT USE "location", "positionLong", "value", None, {"positionHeading"}, None, None, False, None, None, None, None, ] } SENSORS = { "chargingpowerkw": [ "Charging Power", UnitOfPower.KILO_WATT, # Deprecated: DO NOT USE "electric", "chargingPower", "value", None, {}, None, # "mdi:ev-station", SensorDeviceClass.POWER, False, None, SensorStateClass.MEASUREMENT, "Zero", 1, ], "chargingpowerecolimit": [ "Charging Power Limit", UnitOfPower.KILO_WATT, # Deprecated: DO NOT USE "electric", "chargingPowerEcoLimit", "value", None, {"chargingPowerRestriction"}, "mdi:ev-station", SensorDeviceClass.POWER, False, None, SensorStateClass.MEASUREMENT, None, None, ], "rcp_features": [ "RCP Features", None, # Deprecated: DO NOT USE "rcp_options", "rcp_supported", "value", None, {"rcp_supported_settings"}, "mdi:car", None, False, EntityCategory.DIAGNOSTIC, None, None, None, ], "car": [ "Car", None, # Deprecated: DO NOT USE None, "full_updatemessages_received", "value", None, { "partital_updatemessages_received", "last_message_received", "last_command_type", "last_command_state", "last_command_error_code", "last_command_error_message", "is_owner", "electric.chargingBreakClockTimer", }, "mdi:car", None, False, EntityCategory.DIAGNOSTIC, None, None, 0, ], "data_mode": [ "Data Mode", None, # Deprecated: DO NOT USE None, "data_collection_mode", "value", None, {}, "mdi:connection", None, False, EntityCategory.DIAGNOSTIC, None, None, 0, ], "departuretime": [ "Departure time", None, # Deprecated: DO NOT USE "odometer", "departuretime", "display_value", None, {"departureTimeWeekday"}, "mdi:clock-out", None, False, None, None, None, None, ], "lock": [ "Lock", None, # Deprecated: DO NOT USE "doors", "doorlockstatusvehicle", "value", None, { "decklidstatus", "doorStatusOverall", "doorLockStatusOverall", "doorlockstatusgas", "doorlockstatusvehicle", "doorlockstatusfrontleft", "doorlockstatusfrontright", "doorlockstatusrearright", "doorlockstatusrearleft", "doorlockstatusdecklid", "doorstatusrearleft", "doorstatusfrontright", "doorstatusrearright", "doorstatusfrontleft", "rooftopstatus", "sunroofstatus", "engineHoodStatus", "tankCapOpenLamp", }, "mdi:car-key", None, False, None, None, None, None, ], "rangeElectricKm": [ "Range Electric", None, # Deprecated: DO NOT USE "electric", "rangeelectric", "display_value", None, { "chargingactive", "chargingstatus", "distanceElectricalReset", "distanceElectricalStart", "distanceZEReset", "distanceZEStart", "ecoElectricBatteryTemperature", "endofchargetime", "endofChargeTimeWeekday", "precond.precondActive", # DEPRECATED "precond.precondNow", # DEPRECATED "precond.precondDuration", # DEPRECATED "maxrange", "selectedChargeProgram", "electricRatioStart", "electricRatioOverall", "electricRatioReset", }, "mdi:ev-station", SensorDeviceClass.DISTANCE, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "chargingstatus": [ "Charging Status", None, # Deprecated: DO NOT USE "electric", "chargingstatus", "value", None, {}, "mdi:car-electric", None, False, None, None, None, 0, ], "electricconsumptionstart": [ "Electric consumption start", None, # Deprecated: DO NOT USE, "electric", "electricconsumptionstart", "display_value", None, {}, "mdi:ev-station", None, False, None, SensorStateClass.MEASUREMENT, "Zero", 1, ], "electricconsumptionreset": [ "Electric consumption reset", None, # Deprecated: DO NOT USE "electric", "electricconsumptionreset", "display_value", None, {}, "mdi:ev-station", None, False, None, SensorStateClass.MEASUREMENT, None, 1, ], "soc": [ "State of Charge", None, # Deprecated: DO NOT USE "electric", "soc", "value", None, {"maxSocLowerLimit", "maxSoc", "selectedChargeProgram"}, None, SensorDeviceClass.BATTERY, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "max_soc": [ "Max State of Charge", None, # Deprecated: DO NOT USE "electric", "max_soc", "value", None, {"selectedChargeProgram"}, None, None, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "auxheatstatus": [ "Auxheat Status", None, # Deprecated: DO NOT USE "auxheat", "auxheatstatus", "value", None, { "auxheatActive", "auxheatwarnings", "auxheatruntime", "auxheatwarningsPush", "auxheattimeselection", "auxheattime1", "auxheattime2", "auxheattime3", "temperature_points_frontLeft", "temperature_points_frontRight", }, "mdi:radiator", None, False, None, None, None, None, ], "tanklevelpercent": [ "Fuel Level", None, # Deprecated: DO NOT USE "odometer", "tanklevelpercent", "value", None, {"tankLevelAdBlue", "gasTankLevelPercent"}, "mdi:gas-station", SensorDeviceClass.POWER_FACTOR, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "tankleveladblue": [ "AdBlue Level", None, # Deprecated: DO NOT USE "odometer", "tankLevelAdBlue", "value", None, {}, "mdi:gas-station", SensorDeviceClass.POWER_FACTOR, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "odometer": [ "Odometer", None, # Deprecated: DO NOT USE, "odometer", "odo", "display_value", None, { "gasconsumptionstart", "gasconsumptionreset", "gasTankRange", "gasTankLevel", "liquidRangeSkipIndication", "outsideTemperature", "serviceintervaldays", "serviceintervaldistance", "tankReserveLamp", "tankLevelAdBlue", "vehicleDataConnectionState", "remoteStartTemperature", }, "mdi:car-cruise-control", SensorDeviceClass.DISTANCE, False, None, SensorStateClass.TOTAL_INCREASING, None, 0, ], "averageSpeedStart": [ "Average speed start", None, # Deprecated: DO NOT USE "odometer", "averageSpeedStart", "display_value", None, {}, None, # "mdi:car-cruise-control", SensorDeviceClass.SPEED, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "averageSpeedReset": [ "Average speed reset", None, # Deprecated: DO NOT USE, "odometer", "averageSpeedReset", "display_value", None, {}, None, # "mdi:car-cruise-control", SensorDeviceClass.SPEED, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "distanceReset": [ "Distance reset", None, # Deprecated: DO NOT USE, "odometer", "distanceReset", "display_value", None, {"drivenTimeReset"}, "mdi:map-marker-distance", SensorDeviceClass.DISTANCE, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "distanceStart": [ "Distance start", None, # Deprecated: DO NOT USE, "odometer", "distanceStart", "display_value", None, {"drivenTimeStart"}, "mdi:map-marker-distance", SensorDeviceClass.DISTANCE, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "distanceZEReset": [ "Distance zero-emission reset", None, # Deprecated: DO NOT USE, "electric", "distanceZEReset", "display_value", None, {"drivenTimeZEReset"}, "mdi:map-marker-distance", SensorDeviceClass.DISTANCE, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "distanceZEStart": [ "Distance zero-emission start", None, # Deprecated: DO NOT USE, "electric", "distanceZEStart", "display_value", None, {"drivenTimeZEStart"}, "mdi:map-marker-distance", SensorDeviceClass.DISTANCE, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "ecoscoretotal": [ "Eco score total", None, # Deprecated: DO NOT USE "odometer", "ecoscoretotal", "display_value", None, {}, "mdi:leaf", None, False, None, SensorStateClass.MEASUREMENT, None, None, ], "ecoscorefreewhl": [ "Eco score free wheel", None, # Deprecated: DO NOT USE "odometer", "ecoscorefreewhl", "display_value", None, {}, "mdi:leaf", SensorDeviceClass.POWER_FACTOR, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "ecoscorebonusrange": [ "Eco score bonus range", None, # Deprecated: DO NOT USE, "odometer", "ecoscorebonusrange", "display_value", None, {}, "mdi:leaf", SensorDeviceClass.DISTANCE, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "ecoscoreconst": [ "Eco score constant", None, # Deprecated: DO NOT USE "odometer", "ecoscoreconst", "display_value", None, {}, "mdi:leaf", SensorDeviceClass.POWER_FACTOR, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "ecoscoreaccel": [ "Eco score acceleration", None, # Deprecated: DO NOT USE "odometer", "ecoscoreaccel", "display_value", None, {}, "mdi:leaf", SensorDeviceClass.POWER_FACTOR, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "liquidconsumptionstart": [ "Liquid consumption start", None, # Deprecated: DO NOT USE "odometer", "liquidconsumptionstart", "display_value", None, {}, "mdi:fuel", None, # No device class present in HA 2024.2 False, None, SensorStateClass.MEASUREMENT, None, 1, ], "liquidconsumptionreset": [ "Liquid consumption reset", None, # Deprecated: DO NOT USE "odometer", "liquidconsumptionreset", "display_value", None, {}, "mdi:fuel", None, # No device class present in HA 2024.2 False, None, SensorStateClass.MEASUREMENT, None, 1, ], "rangeliquid": [ "Range liquid", None, # Deprecated: DO NOT USE, "odometer", "rangeliquid", "display_value", None, {}, "mdi:gas-station", SensorDeviceClass.DISTANCE, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "starterBatteryState": [ "Starter Battery State", None, # Deprecated: DO NOT USE "binarysensors", "starterBatteryState", "value", None, {}, "mdi:car-battery", None, False, None, None, None, None, ], "ignitionstate": [ "Ignition State", None, # Deprecated: DO NOT USE "odometer", "ignitionstate", "value", None, {}, "mdi:key-wireless", None, False, None, None, None, None, ], "oilLevel": [ "Oil Level", None, # Deprecated: DO NOT USE "odometer", "oilLevel", "value", None, {}, "mdi:oil-level", SensorDeviceClass.POWER_FACTOR, False, None, SensorStateClass.MEASUREMENT, None, 0, ], "tirepressureRearLeft": [ "Tire pressure rear left", None, # Deprecated: DO NOT USE "tires", "tirepressureRearLeft", "display_value", None, {}, None, SensorDeviceClass.ATMOSPHERIC_PRESSURE, False, None, SensorStateClass.MEASUREMENT, None, 1, ], "tirepressureRearRight": [ "Tire pressure rear right", None, # Deprecated: DO NOT USE "tires", "tirepressureRearRight", "display_value", None, {}, None, SensorDeviceClass.ATMOSPHERIC_PRESSURE, False, None, SensorStateClass.MEASUREMENT, None, 1, ], "tirepressureFrontRight": [ "Tire pressure front right", None, # Deprecated: DO NOT USE "tires", "tirepressureFrontRight", "display_value", None, {}, None, SensorDeviceClass.ATMOSPHERIC_PRESSURE, False, None, SensorStateClass.MEASUREMENT, None, 1, ], "tirepressureFrontLeft": [ "Tire pressure front left", None, # Deprecated: DO NOT USE "tires", "tirepressureFrontLeft", "display_value", None, {}, None, SensorDeviceClass.ATMOSPHERIC_PRESSURE, False, None, SensorStateClass.MEASUREMENT, None, 1, ], "tirewarningsrdk": [ "Tires RDK state", None, # Deprecated: DO NOT USE "tires", "tirewarningsrdk", "value", None, {}, "mdi:car-tire-alert", None, False, None, None, None, None, ], "lastParkEvent": [ "Last park event", None, # Deprecated: DO NOT USE "caralarm", "lastParkEvent", "value", None, { "parkEventType", "parkEventLevel", }, None, SensorDeviceClass.DATE, False, None, None, None, None, ], "interiorProtectionSensorStatus": [ "Interior Protection", None, # Deprecated: DO NOT USE "caralarm", "interiorProtectionSensorStatus", "value", None, {}, None, SensorDeviceClass.DATE, False, None, None, None, None, ], "sunroofstatus": [ "Sunroof Status", None, # Deprecated: DO NOT USE "doors", "sunroofstatus", "value", None, {}, None, None, False, None, None, None, None, ], "chargeflapstate": [ "Charge Flap", None, # Deprecated: DO NOT USE "electric", "chargeflap", "value", None, {}, "mdi:ev-plug-type2", None, False, None, None, None, None, ], "chargeinletcoupler": [ "Charge Inlet Coupler", None, # Deprecated: DO NOT USE "electric", "chargeinletcoupler", "value", None, {}, "mdi:ev-plug-type2", None, False, None, None, None, None, ], "chargeinletlock": [ "Charge Inlet Lock", None, # Deprecated: DO NOT USE "electric", "chargeinletlock", "value", None, {}, "mdi:ev-plug-type2", None, False, None, None, None, None, ], "chargeflapdcstatus": [ "Charge Flap DC Status", None, # Deprecated: DO NOT USE "doors", "chargeFlapDCStatus", "value", None, {}, None, None, False, None, None, None, None, ], "departuretimemode": [ "Departure Time Mode", None, # Deprecated: DO NOT USE "electric", "departureTimeMode", "value", None, {}, "mdi:ev-station", None, False, EntityCategory.DIAGNOSTIC, None, None, None, ], "endofchargetime": [ "End of charge", None, # Deprecated: DO NOT USE "electric", "endofchargetime", "display_value", None, {}, "mdi:ev-station", SensorDeviceClass.TIMESTAMP, False, None, None, None, None, ], "wiperHealthPercent": [ "Wiper Health", None, # Deprecated: DO NOT USE "wipers", "wiperHealthPercent", "value", None, { "wiperLifetimeExceeded", }, "mdi:wiper", SensorDeviceClass.POWER_FACTOR, False, None, None, None, 0, ], "selectedchargeprogram": [ "Selected Charge Program", None, # Deprecated: DO NOT USE "electric", "selectedChargeProgram", "value", None, {}, None, None, False, None, None, None, 0, ], } LOCKS = { "lock": [ "Lock", None, # Deprecated: DO NOT USE "doors", "doorlockstatusvehicle", "value", "DOORS_LOCK", {}, None, None, False, None, None, None, None, ], } SENSORS_POLL = { "geofencing_violation": [ "Geofencing Violation", None, # Deprecated: DO NOT USE "geofence_events", "last_event_type", "value", None, {"last_event_zone"}, "mdi:map-marker-radius", None, False, None, None, None, None, ], } UNITS = { "BAR": UnitOfPressure.BAR, "CELSIUS": UnitOfTemperature.CELSIUS, "FAHRENHEIT": UnitOfTemperature.FAHRENHEIT, "KG_PER_100KM": UnitOfMass.KILOGRAMS + "/100" + UnitOfLength.KILOMETERS, "KILOMETERS": UnitOfLength.KILOMETERS, "KM_PER_HOUR": UnitOfSpeed.KILOMETERS_PER_HOUR, "KM_PER_KWH": UnitOfLength.KILOMETERS + "/" + UnitOfEnergy.KILO_WATT_HOUR, "KM_PER_LITER": UnitOfLength.KILOMETERS + "/" + UnitOfVolume.LITERS, "KPA": UnitOfPressure.KPA, "KW": UnitOfPower.KILO_WATT, "KWH_PER_100KM": UnitOfEnergy.KILO_WATT_HOUR + "/100" + UnitOfLength.KILOMETERS, "KWH_PER_100MI": UnitOfEnergy.KILO_WATT_HOUR + "/100" + UnitOfLength.MILES, "LITER_PER_100KM": UnitOfVolume.LITERS + "/100" + UnitOfLength.KILOMETERS, "M_PER_HOUR": UnitOfSpeed.MILES_PER_HOUR, "M_PER_KWH": "mpkWh", "MILES": UnitOfLength.MILES, "MPG_UK": "mpg", "MPG_US": "mpg", "MPGE": "mpge", "PERCENT": PERCENTAGE, "PSI": UnitOfPressure.PSI, "T24H": "", "T12H": "", "%": PERCENTAGE, } class SensorConfigFields(Enum): """Representation of a Sensor.""" # "internal_name":[ 0 Display_Name # 1 unit_of_measurement, # 2 object in car.py # 3 attribute in car.py # 4 value field # 5 unused --> None (for capabilities check in the future) # 6 [list of extended attributes] # 7 icon # 8 device_class # 9 invert boolean value - Default: False # 10 entity_category - Default: None # 11 state_class - Default: None # 12 default_value_mode - Default: None # 13 suggested_display_precision - Default: None # ] DISPLAY_NAME = 0 UNIT_OF_MEASUREMENT = 1 OBJECT_NAME = 2 ATTRIBUTE_NAME = 3 VALUE_FIELD_NAME = 4 CAPABILITIES_LIST = 5 EXTENDED_ATTRIBUTE_LIST = 6 ICON = 7 DEVICE_CLASS = 8 FLIP_RESULT = 9 ENTITY_CATEGORY = 10 STATE_CLASS = 11 DEFAULT_VALUE_MODE = 12 SUGGESTED_DISPLAY_PRECISION = 13 class DefaultValueModeType(StrEnum): """Source type for device trackers.""" NONE = "None" ZERO = "Zero" ================================================ FILE: custom_components/mbapi2020/coordinator.py ================================================ """DataUpdateCoordinator class for the MBAPI2020 Integration.""" from __future__ import annotations import logging from typing import Any from awesomeversion import AwesomeVersion from homeassistant.config_entries import ConfigEntry from homeassistant.const import __version__ as HAVERSION from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.entity_platform import async_get_platforms from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .car import Car from .client import Client from .const import CONF_REGION, DOMAIN, MERCEDESME_COMPONENTS, UPDATE_INTERVAL, VERIFY_SSL from .errors import MbapiError from .helper import LogHelper as loghelper LOGGER = logging.getLogger(__name__) # Version threshold for config_entry setting in options flow # See: https://github.com/home-assistant/core/pull/127980 HA_DATACOORDINATOR_CONTEXTVAR_VERSION_THRESHOLD = "2025.07.99" class MBAPI2020DataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]): """DataUpdateCoordinator class for the MBAPI2020 Integration.""" def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Initialize.""" self.hass: HomeAssistant = hass self.config_entry: ConfigEntry = config_entry self.initialized: bool = False self.entry_setup_complete: bool = False session = async_get_clientsession(hass, VERIFY_SSL) # Find the right way to migrate old configs region = config_entry.data.get(CONF_REGION, None) if region is None: region = "Europe" self.client = Client(hass, session, config_entry, region) if AwesomeVersion(HAVERSION) < HA_DATACOORDINATOR_CONTEXTVAR_VERSION_THRESHOLD: super().__init__(hass, LOGGER, name=DOMAIN, update_interval=UPDATE_INTERVAL) else: super().__init__(hass, LOGGER, name=DOMAIN, config_entry=config_entry, update_interval=UPDATE_INTERVAL) async def _async_update_data(self) -> dict[str, Car]: """Update data via library.""" if self.entry_setup_complete: try: for vin in self.client.cars: await self.client.update_poll_states(vin) except Exception as err: raise MbapiError from err return {} # self.client.cars @callback async def on_dataload_complete(self): """Create sensors after the web_socket initial data is complete.""" if not self.entry_setup_complete: LOGGER.info("Car Load complete - start sensor creation") await self.hass.config_entries.async_forward_entry_setups(self.config_entry, MERCEDESME_COMPONENTS) self.entry_setup_complete = True self.client._dataload_complete_fired = True async def ws_connect(self): """Register handlers and connect to the websocket.""" await self.client.attempt_connect(self.on_dataload_complete, self) @callback async def check_missing_sensors_for_vin(self, vin: str): """Check for newly available sensors after vep_updates.""" if not self.entry_setup_complete: return from .binary_sensor import create_missing_binary_sensors_for_car # noqa: PLC0415 from .sensor import create_missing_sensors_for_car # noqa: PLC0415 car = self.client.cars.get(vin) if not car: return platforms = async_get_platforms(self.hass, "mbapi2020") sensor_platform = None binary_sensor_platform = None for platform in platforms: if platform.domain == "sensor": sensor_platform = platform elif platform.domain == "binary_sensor": binary_sensor_platform = platform total_count = 0 if sensor_platform and hasattr(sensor_platform, "async_add_entities"): count = await create_missing_sensors_for_car(car, self, sensor_platform.async_add_entities) total_count += count if binary_sensor_platform and hasattr(binary_sensor_platform, "async_add_entities"): count = await create_missing_binary_sensors_for_car(car, self, binary_sensor_platform.async_add_entities) total_count += count if total_count > 0: LOGGER.info("Added %d missing sensors/binary_sensors for %s", total_count, loghelper.Mask_VIN(vin)) ================================================ FILE: custom_components/mbapi2020/device_tracker.py ================================================ """Device Tracker support for Mercedes cars with Mercedes ME. For more details about this component, please refer to the documentation at https://github.com/ReneNulschDE/mbapi2020/ """ from __future__ import annotations import logging from homeassistant.components.device_tracker import SourceType, TrackerEntity from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import MercedesMeEntity from .const import DEVICE_TRACKER, DOMAIN from .coordinator import MBAPI2020DataUpdateCoordinator from .helper import CoordinatesHelper as ch LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the MB device tracker by config_entry.""" coordinator: MBAPI2020DataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] if not coordinator.client.cars: LOGGER.info("No Cars found.") return sensor_list = [] for car in coordinator.client.cars.values(): for key, value in sorted(DEVICE_TRACKER.items()): device = MercedesMEDeviceTracker( internal_name=key, config=value, vin=car.finorvin, coordinator=coordinator, ) if device.device_retrieval_status() in ["VALID", "NOT_RECEIVED"]: sensor_list.append(device) async_add_entities(sensor_list, True) class MercedesMEDeviceTracker(MercedesMeEntity, TrackerEntity, RestoreEntity): """Representation of a Sensor.""" @property def latitude(self) -> float | None: """Return latitude value of the device.""" lat = self._get_car_value("location", "positionLat", "value", 0) lng = self._get_car_value("location", "positionLong", "value", 0) if self._use_chinese_location_data: lng, lat = ch.gcj02_to_wgs84(gcj_lon=lng, gcj_lat=lat) return lat or None @property def longitude(self) -> float | None: """Return longitude value of the device.""" lat = self._get_car_value("location", "positionLat", "value", 0) lng = self._get_car_value("location", "positionLong", "value", 0) if self._use_chinese_location_data: lng, lat = ch.gcj02_to_wgs84(gcj_lon=lng, gcj_lat=lat) return lng or None @property def source_type(self): """Return the source type, eg gps or router, of the device.""" return SourceType.GPS @property def device_class(self): """Return the device class of the device tracker.""" return None ================================================ FILE: custom_components/mbapi2020/diagnostics.py ================================================ """Diagnostics support for MBAPI2020.""" from __future__ import annotations import json from typing import Any from homeassistant.components.diagnostics import async_redact_data from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from .const import DOMAIN, JSON_EXPORT_IGNORED_KEYS from .helper import LogHelper as loghelper, MBJSONEncoder async def async_get_config_entry_diagnostics( hass: HomeAssistant, config_entry: ConfigEntry, ) -> dict[str, Any]: """Return diagnostics for a config entry.""" domain = hass.data[DOMAIN][config_entry.entry_id] data = {"entry": config_entry.as_dict(), "cars": []} for car in domain.client.cars.values(): data["cars"].append({loghelper.Mask_VIN(car.finorvin): json.loads(json.dumps(car, cls=MBJSONEncoder))}) return async_redact_data(data, JSON_EXPORT_IGNORED_KEYS) ================================================ FILE: custom_components/mbapi2020/errors.py ================================================ """Define package errors.""" from __future__ import annotations from homeassistant.exceptions import ConfigEntryAuthFailed, HomeAssistantError class MbapiError(HomeAssistantError): """Define a base error.""" class WebsocketError(MbapiError): """Define an error related to generic websocket errors.""" class RequestError(MbapiError): """Define an error related to generic websocket errors.""" class MBAuthError(ConfigEntryAuthFailed): """Define an error related to authentication.""" class MBAuth2FAError(ConfigEntryAuthFailed): """Define an error related to two-factor authentication (2FA).""" class MBLegalTermsError(ConfigEntryAuthFailed): """Define an error related to acceptance of legal terms.""" ================================================ FILE: custom_components/mbapi2020/helper.py ================================================ """Helper functions for MBAPI2020 integration.""" from __future__ import annotations import asyncio import base64 from collections.abc import Awaitable, Callable import datetime from enum import Enum import inspect import json import logging import math from .const import ( JSON_EXPORT_IGNORED_KEYS, LOGIN_APP_ID_CN, LOGIN_APP_ID_EU, LOGIN_BASE_URI, LOGIN_BASE_URI_CN, PSAG_BASE_URI, PSAG_BASE_URI_CN, RCP_BASE_URI, RCP_BASE_URI_CN, REGION_APAC, REGION_CHINA, REGION_EUROPE, REGION_NORAM, REST_API_BASE, REST_API_BASE_CN, REST_API_BASE_NA, REST_API_BASE_PA, WEBSOCKET_API_BASE, WEBSOCKET_API_BASE_CN, WEBSOCKET_API_BASE_NA, ) LOGGER = logging.getLogger(__name__) class LogHelper: """Helper functions for MBAPI2020 logging.""" @staticmethod def Mask_VIN(vin: str) -> str: if len(vin) > 12: return vin[:5] + "X" * (12 - 5 + 1) + vin[13:] return "X" * len(vin) @staticmethod def Mask_email(email: str) -> str: if len(email) > 7: return email[:2] + "X" * (6 - 2 + 1) + email[7:] return "x" * len(email) class UrlHelper: """Helper functions for MBAPI2020 url handling.""" @staticmethod def Rest_url(region: str) -> str: match region: case current if current == REGION_APAC: return REST_API_BASE_PA case current if current == REGION_CHINA: return REST_API_BASE_CN case current if current == REGION_NORAM: return REST_API_BASE_NA case current if current == REGION_EUROPE: return REST_API_BASE @staticmethod def Websocket_url(region: str) -> str: match region: case current if current == REGION_APAC: return WEBSOCKET_API_BASE_NA case current if current == REGION_CHINA: return WEBSOCKET_API_BASE_CN case current if current == REGION_NORAM: return WEBSOCKET_API_BASE_NA case current if current == REGION_EUROPE: return WEBSOCKET_API_BASE @staticmethod def Widget_url(region: str) -> str: env: str = "emea" match region: case current if current in (REGION_APAC, REGION_NORAM): env = "amap" case current if current == REGION_CHINA: env = "cn" case current if current == REGION_EUROPE: env = "emea" return f"https://widget.{env}-prod.mobilesdk.mercedes-benz.com" @staticmethod def Device_code_confirm_url(region: str, device_code: str) -> str: """Return a formatted url to confirm a device code auth.""" base64_code = base64.b64encode(device_code).decode("ascii") env = "emea" match region: case current if current == REGION_APAC: env = "amap" case current if current == REGION_CHINA: env = "cn" case current if current == REGION_NORAM: env = "amap" return ( f"https://link.{env}-prod.mobilesdk.mercedes-benz.com/device-login?userCode={base64_code}&deviceType=watch" ) @staticmethod def RCP_url(region: str) -> str: match region: case current if current == REGION_CHINA: return RCP_BASE_URI_CN case _: return RCP_BASE_URI @staticmethod def PSAG_url(region: str) -> str: match region: case current if current == REGION_CHINA: return PSAG_BASE_URI_CN case _: return PSAG_BASE_URI @staticmethod def Login_Base_Url(region: str) -> str: match region: case current if current == REGION_CHINA: return LOGIN_BASE_URI_CN case _: return LOGIN_BASE_URI @staticmethod def Login_App_Id(region: str) -> str: match region: case current if current == REGION_CHINA: return LOGIN_APP_ID_CN case _: return LOGIN_APP_ID_EU class CoordinatesHelper: @staticmethod def _transform_lat(lon, lat): """Transform latitude for GCJ-02 offset calculation. :param lon: Longitude offset :param lat: Latitude offset :return: Transformed latitude """ ret = -100.0 + 2.0 * lon + 3.0 * lat + 0.2 * lat * lat + 0.1 * lon * lat + 0.2 * math.sqrt(abs(lon)) ret += (20.0 * math.sin(6.0 * lon * math.pi) + 20.0 * math.sin(2.0 * lon * math.pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(lat * math.pi) + 40.0 * math.sin(lat / 3.0 * math.pi)) * 2.0 / 3.0 ret += (160.0 * math.sin(lat / 12.0 * math.pi) + 320 * math.sin(lat * math.pi / 30.0)) * 2.0 / 3.0 return ret @staticmethod def _transform_lon(lon, lat): """Transform longitude for GCJ-02 offset calculation. :param lon: Longitude offset :param lat: Latitude offset :return: Transformed longitude """ ret = 300.0 + lon + 2.0 * lat + 0.1 * lon * lon + 0.1 * lon * lat + 0.1 * math.sqrt(abs(lon)) ret += (20.0 * math.sin(6.0 * lon * math.pi) + 20.0 * math.sin(2.0 * lon * math.pi)) * 2.0 / 3.0 ret += (20.0 * math.sin(lon * math.pi) + 40.0 * math.sin(lon / 3.0 * math.pi)) * 2.0 / 3.0 ret += (150.0 * math.sin(lon / 12.0 * math.pi) + 300.0 * math.sin(lon / 30.0 * math.pi)) * 2.0 / 3.0 return ret @staticmethod def wgs84_to_gcj02(lon, lat): """Convert WGS-84 coordinates to GCJ-02 coordinates. :param lon: WGS-84 longitude :param lat: WGS-84 latitude :return: GCJ-02 longitude and latitude """ a = 6378245.0 # Major axis ee = 0.00669342162296594323 # Flattening dlat = CoordinatesHelper._transform_lat(lon - 105.0, lat - 35.0) dlon = CoordinatesHelper._transform_lon(lon - 105.0, lat - 35.0) radlat = lat / 180.0 * math.pi magic = math.sin(radlat) magic = 1 - ee * magic * magic sqrtmagic = math.sqrt(magic) dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * math.pi) dlon = (dlon * 180.0) / (a / sqrtmagic * math.cos(radlat) * math.pi) mglat = lat + dlat mglon = lon + dlon return mglon, mglat @staticmethod def gcj02_to_wgs84(gcj_lon, gcj_lat): """Convert GCJ-02 coordinates to WGS-84 coordinates. :param gcj_lon: GCJ-02 longitude :param gcj_lat: GCJ-02 latitude :return: WGS-84 longitude and latitude """ EARTH_RADIUS = 6378245.0 EE = 0.00669342162296594323 dlat = CoordinatesHelper._transform_lat(gcj_lon - 105.0, gcj_lat - 35.0) dlon = CoordinatesHelper._transform_lon(gcj_lon - 105.0, gcj_lat - 35.0) rad_lat = gcj_lat / 180.0 * math.pi magic = math.sin(rad_lat) magic = 1 - EE * magic * magic sqrt_magic = math.sqrt(magic) dlat = (dlat * 180.0) / ((EARTH_RADIUS * (1 - EE)) / (magic * sqrt_magic) * math.pi) dlon = (dlon * 180.0) / (EARTH_RADIUS / sqrt_magic * math.cos(rad_lat) * math.pi) wgs_lat = gcj_lat - dlat wgs_lon = gcj_lon - dlon return wgs_lon, wgs_lat def get_class_property_names(obj: object): """Return the names of all properties of a class.""" return [p[0] for p in inspect.getmembers(type(obj), inspect.isdatadescriptor) if not p[0].startswith("_")] class MBJSONEncoder(json.JSONEncoder): """JSON Encoder that handles data classes, properties and additional data types.""" def default(self, o) -> str | dict: # noqa: D102 if isinstance(o, (datetime.datetime, datetime.date, datetime.time)): return o.isoformat() if not isinstance(o, Enum) and hasattr(o, "__dict__") and isinstance(o.__dict__, dict): retval: dict = o.__dict__ retval.update({p: getattr(o, p) for p in get_class_property_names(o)}) return {k: v for k, v in retval.items() if k not in JSON_EXPORT_IGNORED_KEYS} return str(o) class Watchdog: """Define a watchdog to run actions at intervals.""" def __init__(self, action: Callable[..., Awaitable], timeout_seconds: int, topic: str, log_events: bool = False): """Initialize.""" self._action: Callable[..., Awaitable] = action self._loop = asyncio.get_running_loop() self._timer_task: asyncio.TimerHandle | None = None self._expire_task: asyncio.Task | None = None self._topic: str = topic self._log_events: bool = log_events self.timeout: int = timeout_seconds def cancel(self, *, graceful: bool = True): """Cancel the watchdog. graceful=True: stoppe nur den Timer; lasse einen laufenden expire-Task fertiglaufen. graceful=False: cancelt auch einen laufenden expire-Task (vorsichtig verwenden). """ if self._timer_task: self._timer_task.cancel() self._timer_task = None if self._expire_task and not self._expire_task.done(): if graceful: # Falls wir UNS SELBST sind: auf keinen Fall sofort canceln if asyncio.current_task() is self._expire_task: # optional: gar nichts tun; der Task beendet sich gleich selbst pass else: # Laufenden expire-Task laufen lassen (kein Cancel) pass else: # Hartes Cancel nur, wenn explizit gewünscht self._expire_task.cancel() self._expire_task = None async def on_expire(self): """Log and act when the watchdog expires.""" try: if self._log_events: LOGGER.debug("%s Watchdog expired – calling %s", self._topic, self._action.__name__) await self._action() except asyncio.CancelledError: # noqa: TRY203 # Don't log here - will be logged in _on_expire_task_done callback raise async def trigger(self): """Trigger the watchdog.""" # if self._log_events: # LOGGER.debug("%s Watchdog trigger", self._topic) if self._timer_task: self._timer_task.cancel() # Cancel any existing expire task if self._expire_task and not self._expire_task.done(): self._expire_task.cancel() self._expire_task = None self._timer_task = self._loop.call_later(self.timeout, self._on_timer_expire) def _on_timer_expire(self): """Handle timer expiration - create and manage the expire task.""" # Create and store the expire task for proper management self._expire_task = asyncio.create_task(self.on_expire()) # Add done callback to clean up the task reference self._expire_task.add_done_callback(self._on_expire_task_done) def _on_expire_task_done(self, task: asyncio.Task): """Cleanup when expire task is done.""" self._expire_task = None if task.cancelled(): # Task was cancelled - this is normal during shutdown if self._log_events: LOGGER.debug("%s Watchdog expire task cancelled.", self._topic) else: # Safe exception handling - only check for exceptions if not cancelled try: exc = task.exception() if exc and self._log_events: LOGGER.error("%s Watchdog expire task failed: %s", self._topic, exc) except asyncio.CancelledError: # This shouldn't happen, but just in case pass ================================================ FILE: custom_components/mbapi2020/icons.json ================================================ { "services": { "auxheat_configure": "mdi:radiator", "auxheat_start": "mdi:radiator", "auxheat_stop": "mdi:radiator", "battery_max_soc_configure": "mdi:car-battery", "charging_break_clocktimer_configure": "mdi:power-plug-off", "charge_program_configure": "mdi:car-battery", "doors_unlock": "mdi:car-door", "doors_lock": "mdi:car-door", "download_images": "mdi:download", "engine_start": "mdi:engine", "engine_stop": "mdi:engine-off", "hv_battery_start_conditioning": "mdi:car-battery", "hv_battery_stop_conditioning": "mdi:car-battery", "preconditioning_configure": "mdi:car-seat-heater", "preconditioning_configure_seats": "mdi:car-seat-heater", "preheat_start": "mdi:car-seat-heater", "preheat_start_departure_time": "mdi:car-seat-heater", "preheat_stop": "mdi:car-seat-heater", "preheat_stop_departure_time": "mdi:car-seat-heater", "sigpos_start": "mdi:bugle", "sunroof_open": "mdi:car-door", "sunroof_tilt": "mdi:car-door", "sunroof_close": "mdi:car-door", "windows_open": "mdi:car-door", "windows_close": "mdi:car-door", "windows_move": "mdi:car-door", "send_route": "mdi:routes", "temperature_configure": "mdi:temperature-check" }, "entity": { "sensor": { "selectedchargeprogram": { "default": "mdi:ev-station", "state": { "0": "mdi:ev-station", "2": "mdi:home-battery", "3": "mdi:office-building" } } } } } ================================================ FILE: custom_components/mbapi2020/lock.py ================================================ """Lock Support for Mercedes cars with Mercedes ME. For more details about this component, please refer to the documentation at https://github.com/ReneNulschDE/mbapi2020/ """ from __future__ import annotations import asyncio from homeassistant.components.lock import LockEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import ATTR_CODE from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.restore_state import RestoreEntity from . import MercedesMeEntity from .const import CONF_FT_DISABLE_CAPABILITY_CHECK, CONF_PIN, DOMAIN, LOCKS, LOGGER, SensorConfigFields as scf from .coordinator import MBAPI2020DataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Create the sensor platform.""" coordinator: MBAPI2020DataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] if not coordinator.client.cars: LOGGER.info("No Cars found.") return sensor_list = [] for car in coordinator.client.cars.values(): for key, value in sorted(LOCKS.items()): if ( value[scf.CAPABILITIES_LIST.value] is None or config_entry.options.get(CONF_FT_DISABLE_CAPABILITY_CHECK, False) is True or car.features.get(value[scf.CAPABILITIES_LIST.value], False) is True ): device = MercedesMELock( internal_name=key, config=value, vin=car.finorvin, coordinator=coordinator, ) sensor_list.append(device) async_add_entities(sensor_list, True) class MercedesMELock(MercedesMeEntity, LockEntity, RestoreEntity): """Representation of a Lock.""" async def async_lock(self, **kwargs): """Lock the device.""" old_state = self.is_locked LOGGER.debug("starting lock") self._attr_is_locking = True await self._coordinator.client.doors_lock(self._vin) LOGGER.debug("lock initiated") count = 0 while count < 30: if old_state == self.is_locked: count += 1 LOGGER.debug("lock running %s", count) await asyncio.sleep(1) else: break self._attr_is_locking = False LOGGER.debug("unlock finalized %s", count) async def async_unlock(self, **kwargs): """Unlock the device.""" old_state = self.is_locked LOGGER.debug("starting unlock") code = kwargs.get(ATTR_CODE, "") pin = self._coordinator.client.config_entry.options.get(CONF_PIN, "") self._attr_is_unlocking = True if pin and pin.strip(): await self._coordinator.client.doors_unlock_with_pin(self._vin, pin) elif code is None or not code.strip(): LOGGER.error("Code required but none provided") self._attr_is_unlocking = False return else: await self._coordinator.client.doors_unlock_with_pin(self._vin, code) LOGGER.debug("unlock initiated") count = 0 while count < 30: if old_state == self.is_locked: count += 1 LOGGER.debug("unlock running %s", count) await asyncio.sleep(1) else: break self._attr_is_unlocking = False LOGGER.debug("unlock finalized %s", count) @property def is_locked(self): """Return true if device is locked.""" value = self._get_car_value(self._feature_name, self._object_name, self._attrib_name, None) if value and int(value) in (1, 2): return True if value and int(value) in (0, 3): return False return None @property def code_format(self): """Return the required four digit code if the PIN is not set in config_entry.""" pin = self._coordinator.client.config_entry.options.get(CONF_PIN, None) if pin and pin.strip(): # Pin is set --> we don't ask for a pin return None # Pin is not set --> we ask for a pin return "^\\d{4}$" ================================================ FILE: custom_components/mbapi2020/manifest.json ================================================ { "domain": "mbapi2020", "name": "MercedesME 2020", "codeowners": ["@ReneNulschDE"], "config_flow": true, "dependencies": [], "documentation": "https://github.com/ReneNulschDE/mbapi2020", "integration_type": "hub", "iot_class": "cloud_push", "issue_tracker": "https://github.com/ReneNulschDE/mbapi2020/issues", "loggers": ["custom_components.mbapi2020"], "requirements": ["protobuf>=3.19.5"], "version": "0.36.0" } ================================================ FILE: custom_components/mbapi2020/oauth.py ================================================ """Integration of optimized Mercedes Me OAuth2 LoginNew functionality.""" from __future__ import annotations import asyncio import base64 from copy import deepcopy import hashlib import json import logging import secrets import time from typing import Any import urllib.parse import uuid import aiohttp from aiohttp import ClientSession from custom_components.mbapi2020.errors import MBAuth2FAError, MBAuthError, MBLegalTermsError from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_create_clientsession from .const import ( DEFAULT_COUNTRY_CODE, DEFAULT_LOCALE, LOGIN_APP_ID_CN, LOGIN_APP_ID_EU, REGION_APAC, REGION_CHINA, REGION_EUROPE, REGION_NORAM, RIS_APPLICATION_VERSION, RIS_APPLICATION_VERSION_CN, RIS_APPLICATION_VERSION_NA, RIS_APPLICATION_VERSION_PA, RIS_OS_NAME, RIS_OS_VERSION, RIS_SDK_VERSION, SYSTEM_PROXY, VERIFY_SSL, WEBSOCKET_USER_AGENT, WEBSOCKET_USER_AGENT_CN, WEBSOCKET_USER_AGENT_PA, X_APPLICATIONNAME_AP, X_APPLICATIONNAME_CN, X_APPLICATIONNAME_ECE, X_APPLICATIONNAME_US, ) from .helper import LogHelper, UrlHelper as helper _LOGGER = logging.getLogger(__name__) class Oauth: """OAuth2 class for Mercedes Me integration.""" # OAuth2 Configuration for new login method CLIENT_ID = LOGIN_APP_ID_EU REDIRECT_URI = "rismycar://login-callback" SCOPE = "email profile ciam-uid phone openid offline_access" def __init__( self, hass: HomeAssistant, session: ClientSession, region: str, config_entry: ConfigEntry, ) -> None: """Initialize the extended OAuth instance.""" self._session: ClientSession = session self._region: str = region self._hass = hass self._config_entry = config_entry self.token = None self._sessionid = "" self._get_token_lock = asyncio.Lock() self._device_guid: str = (config_entry.data.get("device_guid") if config_entry else None) or str(uuid.uuid4()) if region == REGION_CHINA: self.CLIENT_ID = LOGIN_APP_ID_CN # PKCE parameters for new login method self.code_verifier: str | None = None self.code_challenge: str | None = None def _generate_pkce_parameters(self) -> tuple[str, str]: """Generate PKCE (Proof Key for Code Exchange) parameters for OAuth2. Returns: tuple: (code_verifier, code_challenge) """ # Generate code_verifier (43-128 characters, URL-safe) code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).decode("utf-8").rstrip("=") # Generate code_challenge (SHA256 hash of code_verifier, base64url encoded) code_challenge_bytes = hashlib.sha256(code_verifier.encode("utf-8")).digest() code_challenge = base64.urlsafe_b64encode(code_challenge_bytes).decode("utf-8").rstrip("=") _LOGGER.debug("Generated PKCE parameters for OAuth2 flow") return code_verifier, code_challenge def _ensure_pkce_parameters(self) -> None: """Ensure PKCE parameters are generated.""" if not self.code_verifier or not self.code_challenge: self.code_verifier, self.code_challenge = self._generate_pkce_parameters() async def async_login_new(self, email: str, password: str) -> dict[str, Any]: """Perform new OAuth2 login flow with PKCE. Args: email: Mercedes Me account email password: Mercedes Me account password Returns: dict containing token information Raises: MBAuthError: If login fails """ _LOGGER.info("Starting OAuth2 login flow") # create a fresh session with CIAM.DEVICE cookie device_guid = self._device_guid cookie_jar = aiohttp.CookieJar() cookie_jar.update_cookies({"CIAM.DEVICE": device_guid}) self._session = async_create_clientsession(self._hass, verify_ssl=VERIFY_SSL, cookie_jar=cookie_jar) try: # Step 1: Get authorization URL and extract resume parameter resume_url = await self._get_authorization_resume() # Step 2: Send user agent information await self._send_user_agent_info() # Step 3: Submit username await self._submit_username(email) # Step 4: Submit password and get pre-login token pre_login_data = await self._submit_password(email, password) if pre_login_data and pre_login_data.get("result", "") != "RESUME2OIDCP": if pre_login_data.get("result", "") == "GOTO_LOGIN_OTP": raise MBAuth2FAError("Two-factor authentication (2FA) is not supported.") if pre_login_data.get("result", "") == "GOTO_LOGIN_LEGAL_TEXTS": home_ountry = pre_login_data.get("homeCountry", "") consent_country = pre_login_data.get("consentCountry", "") pre_login_data = await self._submit_legal_consent(home_ountry, consent_country) if pre_login_data.get("result", "") != "RESUME2OIDCP": raise MBLegalTermsError("Problem accepting legal terms during login. %s", pre_login_data) else: raise MBAuthError("Unexpected login result: %s", pre_login_data) # Step 5: Resume authorization and get code auth_code = await self._resume_authorization(resume_url, pre_login_data["token"]) # Step 6: Exchange code for tokens token_info = await self._exchange_code_for_tokens(auth_code) # Add custom values and save token token_info = self._add_custom_values_to_token_info(token_info) self._save_token_info(token_info) self.token = token_info self.code_verifier = None self.code_challenge = None _LOGGER.info("OAuth2 login successful") return token_info except (MBAuth2FAError, MBLegalTermsError): raise except Exception as e: _LOGGER.error("OAuth2 login failed: %s", e) raise MBAuthError(f"Login failed: {e}") from e def _get_mobile_safari_headers( self, accept: str = "application/json, text/plain, */*", include_referer: bool = True, ) -> dict[str, str]: """Build headers with mobile Safari user agent and common fields.""" base_url = helper.Login_Base_Url(self._region) headers = { "accept": accept, "content-type": "application/json", "origin": base_url, "accept-language": "de-DE,de;q=0.9", "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.6 Mobile/15E148 Safari/604.1", } if include_referer: headers["referer"] = f"{base_url}/ciam/auth/login" return headers def _extract_code_from_redirect_url(self, redirect_url: str) -> str: """Extract authorization code from redirect URL.""" parsed_url = urllib.parse.urlparse(redirect_url) params = urllib.parse.parse_qs(parsed_url.query) code = params.get("code", [None])[0] if not code: raise MBAuthError("Authorization code not found in redirect URL") return code async def _get_authorization_resume(self) -> str: """Get authorization URL and extract resume parameter.""" self._ensure_pkce_parameters() params = { "client_id": self.CLIENT_ID, "code_challenge": self.code_challenge, "code_challenge_method": "S256", "redirect_uri": self.REDIRECT_URI, "response_type": "code", "scope": self.SCOPE, } headers = { "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6.6 Mobile/15E148 Safari/604.1", "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "accept-language": "de-DE,de;q=0.9", } auth_url = f"{helper.Login_Base_Url(self._region)}/as/authorization.oauth2" async with self._session.get( auth_url, params=params, headers=headers, proxy=SYSTEM_PROXY, allow_redirects=True ) as response: if response.status >= 400: raise MBAuthError(f"Authorization request failed: {response.status}") parsed_url = urllib.parse.urlparse(str(response.url)) url_params = urllib.parse.parse_qs(parsed_url.query) resume = url_params.get("resume", [None])[0] if not resume: raise MBAuthError("Resume parameter not found in authorization response") return resume async def _send_user_agent_info(self) -> None: """Send user agent information.""" headers = self._get_mobile_safari_headers( accept="*/*", include_referer=False, ) data = { "browserName": "Mobile Safari", "browserVersion": "15.6.6", "osName": "iOS", } url = f"{helper.Login_Base_Url(self._region)}/ciam/auth/ua" async with self._session.post(url, json=data, headers=headers, proxy=SYSTEM_PROXY) as response: if response.status >= 400: _LOGGER.warning("User agent info submission failed: %s", response.status) async def _submit_username(self, email: str) -> None: """Submit username.""" headers = self._get_mobile_safari_headers() url = f"{helper.Login_Base_Url(self._region)}/ciam/auth/login/user" async with self._session.post(url, json={"username": email}, headers=headers, proxy=SYSTEM_PROXY) as response: if response.status >= 400: error_text = await response.text() raise MBAuthError(f"Username submission failed: {response.status} - {error_text}") async def _submit_password(self, email: str, password: str) -> dict[str, Any]: """Submit password and get pre-login data.""" rid = secrets.token_urlsafe(24) headers = self._get_mobile_safari_headers() data = { "username": email, "password": password, "rememberMe": False, "rid": rid, } url = f"{helper.Login_Base_Url(self._region)}/ciam/auth/login/pass" async with self._session.post(url, json=data, headers=headers, proxy=SYSTEM_PROXY) as response: if response.status >= 400: error_text = await response.text() raise MBAuthError(f"Password submission failed: {response.status} - {error_text}") return await response.json() async def _submit_legal_consent(self, home_country: str, consent_country: str) -> dict[str, Any]: """Submit legal consent and get pre-login data.""" headers = self._get_mobile_safari_headers() data = { "texts": {}, "homeCountry": home_country, "consentCountry": consent_country, } url = f"{helper.Login_Base_Url(self._region)}/ciam/auth/toas/saveLoginConsent" async with self._session.post(url, json=data, headers=headers, proxy=SYSTEM_PROXY) as response: if response.status >= 400: error_text = await response.text() raise MBAuthError(f"legal_consent submission failed: {response.status} - {error_text}") return await response.json() async def _resume_authorization(self, resume_url: str, token: str) -> str: """Resume authorization and extract code.""" headers = self._get_mobile_safari_headers() headers["accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" headers["content-type"] = "application/x-www-form-urlencoded" data = aiohttp.FormData({"token": token}) try: async with self._session.post( f"{helper.Login_Base_Url(self._region)}{resume_url}", data=data, headers=headers, proxy=SYSTEM_PROXY, allow_redirects=False, ) as response: if response.status in (302, 301): redirect_url = response.headers.get("location", "") if redirect_url.startswith("rismycar://"): return self._extract_code_from_redirect_url(redirect_url) raise MBAuthError(f"Unexpected response during authorization: {response.status}") except aiohttp.InvalidURL as e: # Handle custom scheme redirect error_str = str(e) if "rismycar://" in error_str: # Extract URL from error message start = error_str.find("'") + 1 end = error_str.find("'", start) redirect_url = error_str[start:end] try: return self._extract_code_from_redirect_url(redirect_url) except MBAuthError as extract_error: raise MBAuthError("Authorization code not found in redirect URL") from extract_error raise MBAuthError(f"Unexpected URL error: {e}") from e async def _exchange_code_for_tokens(self, code: str) -> dict[str, Any]: """Exchange authorization code for access and refresh tokens.""" if not self.code_verifier: raise MBAuthError("Code verifier not available for token exchange") headers = self._get_header() headers["Content-Type"] = "application/x-www-form-urlencoded" data = { "client_id": self.CLIENT_ID, "code": code, "code_verifier": self.code_verifier, "grant_type": "authorization_code", "redirect_uri": self.REDIRECT_URI, } # Convert to form data form_data = "&".join([f"{k}={urllib.parse.quote_plus(str(v))}" for k, v in data.items()]) url = f"{helper.Login_Base_Url(self._region)}/as/token.oauth2" async with self._session.post(url, data=form_data, headers=headers, proxy=SYSTEM_PROXY) as response: if response.status >= 400: error_text = await response.text() raise MBAuthError(f"Token exchange failed: {response.status} - {error_text}") return await response.json() async def request_access_token_with_pin(self, email: str, pin: str, nonce: str): """Request the access token using the Pin.""" url = f"{helper.Login_Base_Url(self._region)}/as/token.oauth2" encoded_email = urllib.parse.quote_plus(email, safe="@") data = ( f"client_id={helper.Login_App_Id(self._region)}&grant_type=password&username={encoded_email}&password={nonce}:{pin}" "&scope=openid email phone profile offline_access ciam-uid" ) headers = self._get_header() headers["Content-Type"] = "application/x-www-form-urlencoded" headers["Stage"] = "prod" headers["X-Device-Id"] = self._device_guid headers["X-Request-Id"] = str(uuid.uuid4()) token_info = await self._async_request("post", url, data=data, headers=headers) if token_info is not None: token_info = self._add_custom_values_to_token_info(token_info) self._save_token_info(token_info) self.token = token_info return token_info return None async def request_pin(self, email: str, nonce: str): """Initiate a PIN request.""" _LOGGER.info("Start request PIN %s", LogHelper.Mask_email(email)) _LOGGER.debug("PIN preflight request 1") headers = self._get_header() url = f"{helper.Rest_url(self._region)}/v1/config" await self._async_request("get", url, headers=headers) _LOGGER.info("PIN request") url = f"{helper.Rest_url(self._region)}/v1/login" data = json.dumps({"emailOrPhoneNumber": email, "countryCode": DEFAULT_COUNTRY_CODE, "nonce": nonce}) headers = self._get_header() return await self._async_request("post", url, data=data, headers=headers) async def async_refresh_access_token(self, refresh_token: str, is_retry: bool = False): """Refresh the access token.""" _LOGGER.info("Start async_refresh_access_token() with refresh_token") _LOGGER.debug("Auth token refresh preflight request 1") headers = self._get_header() url = f"{helper.Rest_url(self._region)}/v1/config" await self._async_request("get", url, headers=headers) url = f"{helper.Login_Base_Url(self._region)}/as/token.oauth2" data = f"grant_type=refresh_token&refresh_token={refresh_token}" headers = self._get_header() headers["Content-Type"] = "application/x-www-form-urlencoded" headers["X-Device-Id"] = self._device_guid headers["X-Request-Id"] = str(uuid.uuid4()) token_info = None try: token_info = await self._async_request(method="post", url=url, data=data, headers=headers) except MBAuthError: if is_retry: if self._config_entry and self._config_entry.data: new_config_entry_data = deepcopy(dict(self._config_entry.data)) new_config_entry_data.pop("token", None) self._hass.config_entries.async_update_entry(self._config_entry, data=new_config_entry_data) raise if token_info is not None: if "refresh_token" not in token_info: token_info["refresh_token"] = refresh_token token_info = self._add_custom_values_to_token_info(token_info) self._save_token_info(token_info) self.token = token_info return token_info async def async_get_cached_token(self): """Get a cached auth token.""" # _LOGGER.debug("Start async_get_cached_token()") token_info: dict[str, any] if self.token: token_info = self.token elif self._config_entry and self._config_entry.data and "token" in self._config_entry.data: token_info = self._config_entry.data["token"] else: _LOGGER.warning("No token information - reauth required") return None if self.is_token_expired(token_info): async with self._get_token_lock: if not self.is_token_expired(self.token or token_info): token_info = self.token else: _LOGGER.debug("%s token expired -> start refresh", __name__) if not token_info or "refresh_token" not in token_info: _LOGGER.warning("Refresh token is missing - reauth required") return None token_info = await self.async_refresh_access_token(token_info["refresh_token"], is_retry=False) self.token = token_info return token_info @classmethod def is_token_expired(cls, token_info) -> bool: """Check if the token is expired.""" if token_info is not None: now = int(time.time()) return token_info["expires_at"] - now < 60 return True def _save_token_info(self, token_info): """Save token info.""" if self._config_entry: _LOGGER.debug( "Start _save_token_info() to config_entry %s", self._config_entry.entry_id, ) new_config_entry_data = deepcopy(dict(self._config_entry.data)) new_config_entry_data["token"] = token_info # Ensure device_guid is preserved if self._device_guid: new_config_entry_data["device_guid"] = self._device_guid self._hass.config_entries.async_update_entry(self._config_entry, data=new_config_entry_data) @classmethod def _add_custom_values_to_token_info(cls, token_info): """Add custom values to token info.""" token_info["expires_at"] = int(time.time()) + token_info["expires_in"] return token_info def _get_header(self): """Get headers with Session-ID.""" if not self._sessionid: self._sessionid = str(uuid.uuid4()) header = { "Ris-Os-Name": RIS_OS_NAME, "Ris-Os-Version": RIS_OS_VERSION, "Ris-Sdk-Version": RIS_SDK_VERSION, "X-Locale": DEFAULT_LOCALE, "X-Trackingid": str(uuid.uuid4()), "X-Sessionid": self._sessionid, "User-Agent": WEBSOCKET_USER_AGENT, "Content-Type": "application/json", "Accept-Language": "en-GB", } return self._get_region_header(header) def _get_region_header(self, header): """Get region-specific headers.""" if self._region == REGION_EUROPE: header["X-Applicationname"] = X_APPLICATIONNAME_ECE header["Ris-Application-Version"] = RIS_APPLICATION_VERSION if self._region == REGION_NORAM: header["X-Applicationname"] = X_APPLICATIONNAME_US header["Ris-Application-Version"] = RIS_APPLICATION_VERSION_NA if self._region == REGION_APAC: header["X-Applicationname"] = X_APPLICATIONNAME_AP header["Ris-Application-Version"] = RIS_APPLICATION_VERSION_PA header["User-Agent"] = WEBSOCKET_USER_AGENT_PA if self._region == REGION_CHINA: header["X-Applicationname"] = X_APPLICATIONNAME_CN header["Ris-Application-Version"] = RIS_APPLICATION_VERSION_CN header["User-Agent"] = WEBSOCKET_USER_AGENT_CN return header async def _async_request(self, method: str, url: str, data: str = "", **kwargs): """Make a request against the API.""" kwargs.setdefault("headers", {}) kwargs.setdefault("proxy", SYSTEM_PROXY) if not self._session or self._session.closed: device_guid = self._device_guid cookie_jar = aiohttp.CookieJar() cookie_jar.update_cookies({"CIAM.DEVICE": device_guid}) self._session = async_create_clientsession(self._hass, verify_ssl=VERIFY_SSL, cookie_jar=cookie_jar) async with self._session.request(method, url, data=data, **kwargs) as resp: if 400 <= resp.status <= 500: try: error = await resp.text() error_json = json.loads(error) if error_json: error_message = f"Error requesting: {url} - {error_json['code']} - {error_json['errors']}" else: error_message = f"Error requesting: {url} - 0 - {error}" except (json.JSONDecodeError, KeyError): error_message = f"Error requesting: {url} - 0 - {error}" _LOGGER.error(error_message) raise MBAuthError(error_message) return await resp.json(content_type=None) ================================================ FILE: custom_components/mbapi2020/proto/acp_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: acp.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() import custom_components.mbapi2020.proto.gogo_pb2 as gogo__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\tacp.proto\x12\x05proto\x1a\ngogo.proto"\xa5\x02\n\x03VVA"v\n\x0c\x43ommandState\x12\x19\n\x15UNKNOWN_COMMAND_STATE\x10\x00\x12\x0c\n\x07\x43REATED\x10\xf2\x07\x12\r\n\x08\x45NQUEUED\x10\xf8\x07\x12\x0f\n\nPROCESSING\x10\xf4\x07\x12\x0e\n\tSUSPENDED\x10\xf9\x07\x12\r\n\x08\x46INISHED\x10\xfa\x07"\xa5\x01\n\x10\x43ommandCondition\x12\x1d\n\x19UNKNWON_COMMAND_CONDITION\x10\x00\x12\t\n\x04NONE\x10\xe8\x07\x12\r\n\x08\x41\x43\x43\x45PTED\x10\xe9\x07\x12\r\n\x08REJECTED\x10\xea\x07\x12\x0e\n\tTERMINATE\x10\xeb\x07\x12\x0c\n\x07SUCCESS\x10\xf3\x07\x12\x0b\n\x06\x46\x41ILED\x10\xf5\x07\x12\x10\n\x0bOVERWRITTEN\x10\xf6\x07\x12\x0c\n\x07TIMEOUT\x10\xf7\x07"\xfe\x0b\n\nVehicleAPI"\xec\x01\n\x0c\x43ommandState\x12\x19\n\x15UNKNOWN_COMMAND_STATE\x10\x00\x12\x0e\n\nINITIATION\x10\x01\x12\x0c\n\x08\x45NQUEUED\x10\x02\x12\x0e\n\nPROCESSING\x10\x03\x12\x0b\n\x07WAITING\x10\x04\x12\x0c\n\x08\x46INISHED\x10\x05\x12\n\n\x06\x46\x41ILED\x10\x06\x12\x14\n\x10\x41\x43KED_BY_APPTWIN\x10\x07\x12\r\n\tPIN_VALID\x10\x08\x12\x0f\n\x0bWAKEUP_SENT\x10\t\x12\x12\n\x0eWAITING_WAKEUP\x10\n\x12\x10\n\x0cWAITING_SYNC\x10\x0b\x12\x10\n\x0c\x43OMMAND_SENT\x10\x0c"S\n\x0f\x41ttributeStatus\x12\r\n\tVALUE_SET\x10\x00\x12\x11\n\rVALUE_NOT_SET\x10\x01\x12\x0b\n\x07INVALID\x10\x03\x12\x11\n\rNOT_AVAILABLE\x10\x04"\xab\t\n\tQueueType\x12\x1b\n\x17UNKNOWNCOMMANDQUEUETYPE\x10\x00\x12\t\n\x05\x44OORS\x10\n\x12\x0b\n\x07\x41UXHEAT\x10\x0b\x12\x0b\n\x07PRECOND\x10\x0c\x12\r\n\tCHARGEOPT\x10\r\x12\x0f\n\x0bMAINTENANCE\x10\x0e\x12\x07\n\x03TCU\x10\x0f\x12\x08\n\x04\x46\x45\x45\x44\x10\x10\x12\x15\n\x11SERVICEACTIVATION\x10\x11\x12\x07\n\x03\x41TP\x10\x12\x12\x0e\n\nASSISTANCE\x10\x13\x12\x08\n\x04RACP\x10\x14\x12\x0f\n\x0bWEEKPROFILE\x10\x15\x12\x13\n\x0fREMOTEDIAGNOSIS\x10\x16\x12\x08\n\x04\x46LSH\x10\x17\x12\x0f\n\x0bTEMPERATURE\x10\x18\x12\x0c\n\x08TRIPCOMP\x10\x19\x12\n\n\x06\x45NGINE\x10\x1a\x12\x0e\n\nTHEFTALARM\x10\x1b\x12\n\n\x06WINDOW\x10\x1c\x12\x0c\n\x08HEADUNIT\x10\x1d\x12\n\n\x06MECALL\x10\x1f\x12\x0f\n\x0bIMMOBILIZER\x10 \x12\x10\n\x0cRENTALSIGNAL\x10!\x12\x07\n\x03\x42\x43\x46\x10"\x12\x11\n\rPLUGANDCHARGE\x10#\x12\x14\n\x10\x43\x41RSHARINGMODULE\x10$\x12\x0b\n\x07\x42\x41TTERY\x10%\x12\x11\n\rONBOARDFENCES\x10&\x12\x0f\n\x0bSPEEDFENCES\x10\'\x12\x13\n\x0f\x43HARGINGTARIFFS\x10(\x12\r\n\tRTMCONFIG\x10)\x12\x17\n\x13MAINTENANCECOMPUTER\x10*\x12\x0b\n\x07MECALL2\x10+\x12\x19\n\x15\x41UTOMATEDVALETPARKING\x10,\x12\x11\n\rCHARGECONTROL\x10-\x12\x0e\n\nSPEEDALERT\x10.\x12\x1b\n\x17unknowncommandqueuetype\x10\x00\x12\t\n\x05\x64oors\x10\n\x12\x0b\n\x07\x61uxheat\x10\x0b\x12\x0b\n\x07precond\x10\x0c\x12\r\n\tchargeopt\x10\r\x12\x0f\n\x0bmaintenance\x10\x0e\x12\x07\n\x03tcu\x10\x0f\x12\x08\n\x04\x66\x65\x65\x64\x10\x10\x12\x15\n\x11serviceactivation\x10\x11\x12\x07\n\x03\x61tp\x10\x12\x12\x0e\n\nassistance\x10\x13\x12\x08\n\x04racp\x10\x14\x12\x0f\n\x0bweekprofile\x10\x15\x12\x13\n\x0fremotediagnosis\x10\x16\x12\x08\n\x04\x66lsh\x10\x17\x12\x0f\n\x0btemperature\x10\x18\x12\x0c\n\x08tripcomp\x10\x19\x12\n\n\x06\x65ngine\x10\x1a\x12\x0e\n\ntheftalarm\x10\x1b\x12\n\n\x06window\x10\x1c\x12\x0c\n\x08headunit\x10\x1d\x12\n\n\x06mecall\x10\x1f\x12\x0f\n\x0bimmobilizer\x10 \x12\x10\n\x0crentalsignal\x10!\x12\x07\n\x03\x62\x63\x66\x10"\x12\x11\n\rplugandcharge\x10#\x12\x14\n\x10\x63\x61rsharingmodule\x10$\x12\x0b\n\x07\x62\x61ttery\x10%\x12\x11\n\ronboardfences\x10&\x12\x0f\n\x0bspeedfences\x10\'\x12\x13\n\x0f\x63hargingtariffs\x10(\x12\r\n\trtmconfig\x10)\x12\x17\n\x13maintenancecomputer\x10*\x12\x0b\n\x07mecall2\x10+\x12\x19\n\x15\x61utomatedvaletparking\x10,\x12\x11\n\rchargecontrol\x10-\x12\x0e\n\nspeedalert\x10.\x1a\x02\x10\x01"\xed\x31\n\x03\x41\x43P"\xe5\x31\n\x0b\x43ommandType\x12\x16\n\x12UNKNOWNCOMMANDTYPE\x10\x00\x12\r\n\tDOORSLOCK\x10\x64\x12\x0f\n\x0b\x44OORSUNLOCK\x10n\x12\x0f\n\x0bTRUNKUNLOCK\x10s\x12\x12\n\x0e\x46UELFLAPUNLOCK\x10t\x12\x17\n\x13\x43HARGECOUPLERUNLOCK\x10v\x12\x16\n\x12\x44OORSPREPARERENTAL\x10x\x12\x17\n\x12\x44OORSSECUREVEHICLE\x10\x82\x01\x12\x11\n\x0c\x41UXHEATSTART\x10\xac\x02\x12\x10\n\x0b\x41UXHEATSTOP\x10\xb6\x02\x12\x15\n\x10\x41UXHEATCONFIGURE\x10\xc0\x02\x12\x19\n\x14TEMPERATURECONFIGURE\x10\xde\x02\x12\x19\n\x14WEEKPROFILECONFIGURE\x10\xe8\x02\x12\x1b\n\x16WEEKPROFILEV2CONFIGURE\x10\xf2\x02\x12\x11\n\x0cPRECONDSTART\x10\x90\x03\x12\x10\n\x0bPRECONDSTOP\x10\x9a\x03\x12\x15\n\x10PRECONDCONFIGURE\x10\xa4\x03\x12\x1a\n\x15PRECONDCONFIGURESEATS\x10\xa9\x03\x12\x17\n\x12\x43HARGEOPTCONFIGURE\x10\xae\x03\x12\x13\n\x0e\x43HARGEOPTSTART\x10\xb8\x03\x12\x12\n\rCHARGEOPTSTOP\x10\xc2\x03\x12\x0c\n\x07\x46\x45\x45\x44POI\x10\xf4\x03\x12\x11\n\x0c\x46\x45\x45\x44\x46REETEXT\x10\xfe\x03\x12\x10\n\x0b\x45NGINESTART\x10\xa6\x04\x12\x0f\n\nENGINESTOP\x10\xb0\x04\x12\x13\n\x0e\x45NGINEAVPSTART\x10\xba\x04\x12\x0e\n\tTCUWAKEUP\x10\xd8\x04\x12\x10\n\x0bTCUSWUPDATE\x10\xe2\x04\x12\x10\n\x0bTCURCSRESET\x10\xec\x04\x12\x15\n\x10TCUINTERROGATION\x10\xf6\x04\x12\x14\n\x0fSPEEDALERTSTART\x10\xc6\x05\x12\x13\n\x0eSPEEDALERTSTOP\x10\xd0\x05\x12\x0e\n\tFLSHSTART\x10\xee\x05\x12\r\n\x08\x46LSHSTOP\x10\xf8\x05\x12\x10\n\x0bSIGPOSSTART\x10\x82\x06\x12\x16\n\x11\x43ONTRACTCONFIGURE\x10\xa0\x06\x12\x13\n\x0e\x43ONTRACTREMOVE\x10\xaa\x06\x12\x12\n\rROOTCONFIGURE\x10\xb4\x06\x12\x0f\n\nROOTREMOVE\x10\xbe\x06\x12\r\n\x08TRIPCOMP\x10\xd2\x06\x12\x19\n\x14MAINTENANCECONFIGURE\x10\xa2\x07\x12\x1e\n\x19MAINTENANCECOMPUTEROFFSET\x10\xa3\x07\x12\x15\n\x10SHORTTESTEXECUTE\x10\xa7\x07\x12\x1f\n\x1aSERVICEACTIVATIONCONFIGURE\x10\xac\x07\x12"\n\x1d\x44\x43\x32SERVICEACTIVATIONCONFIGURE\x10\xb1\x07\x12\x13\n\x0e\x44\x43\x32RAWDOWNLOAD\x10\xb6\x07\x12\x1d\n\x18\x41PPLICATIONCONFIGURATION\x10\xbb\x07\x12\x15\n\x10\x44\x43\x32STARTTRACKING\x10\xc0\x07\x12\x10\n\x0b\x41TPSEQUENCE\x10\xde\x07\x12\x1d\n\x18THEFTALARMTOGGLEINTERIOR\x10\xe8\x07\x12\x18\n\x13THEFTALARMTOGGLETOW\x10\xf2\x07\x12 \n\x1bTHEFTALARMSELECTINTERIORTOW\x10\xfc\x07\x12"\n\x1dTHEFTALARMDESELECTINTERIORTOW\x10\x86\x08\x12\x13\n\x0eTHEFTALARMSTOP\x10\x90\x08\x12\x0f\n\nWINDOWOPEN\x10\xcc\x08\x12\x10\n\x0bWINDOWCLOSE\x10\xd6\x08\x12\x14\n\x0fWINDOWVENTILATE\x10\xe0\x08\x12\x0f\n\nWINDOWMOVE\x10\xe1\x08\x12\r\n\x08ROOFOPEN\x10\xea\x08\x12\x0e\n\tROOFCLOSE\x10\xf4\x08\x12\r\n\x08ROOFLIFT\x10\xfe\x08\x12\r\n\x08ROOFMOVE\x10\xff\x08\x12\x12\n\rBATTERYMAXSOC\x10\xd0\x0f\x12\x19\n\x14\x42\x41TTERYCHARGEPROGRAM\x10\xda\x0f\x12\x1b\n\x16\x43HARGEPROGRAMCONFIGURE\x10\xe4\x0f\x12\x18\n\x13ONBOARDFENCESCREATE\x10\xb4\x10\x12\x18\n\x13ONBOARDFENCESUPDATE\x10\xbe\x10\x12\x18\n\x13ONBOARDFENCESDELETE\x10\xc8\x10\x12\x16\n\x11SPEEDFENCESCREATE\x10\x98\x11\x12\x16\n\x11SPEEDFENCESUPDATE\x10\xa2\x11\x12\x16\n\x11SPEEDFENCESDELETE\x10\xac\x11\x12\x1a\n\x15\x43HARGINGTARIFFSCREATE\x10\xfc\x11\x12\x1a\n\x15\x43HARGINGTARIFFSUPDATE\x10\x86\x12\x12\x1a\n\x15\x43HARGINGTARIFFSDELETE\x10\x90\x12\x12\x14\n\x0fTHEFTALARMSTART\x10\xc4\x13\x12\x1d\n\x18THEFTALARMSELECTINTERIOR\x10\xce\x13\x12\x1f\n\x1aTHEFTALARMDESELECTINTERIOR\x10\xd8\x13\x12\x18\n\x13THEFTALARMSELECTTOW\x10\xe2\x13\x12\x1a\n\x15THEFTALARMDESELECTTOW\x10\xec\x13\x12$\n\x1fTHEFTALARMSELECTDAMAGEDETECTION\x10\xf6\x13\x12&\n!THEFTALARMDESELECTDAMAGEDETECTION\x10\x80\x14\x12%\n THEFTALARMCONFIRMDAMAGEDETECTION\x10\x8a\x14\x12\x11\n\x0cMECALL2START\x10\xa8\x14\x12\x1e\n\x19UDXTRIGGERSYNCHRONIZATION\x10\xb0\t\x12\x19\n\x14UDXACTIVEUSERPROFILE\x10\xba\t\x12\x15\n\x10UDXRESETUSERDATA\x10\xc4\t\x12\x12\n\rUSERPROFSYNCH\x10\xce\t\x12\x12\n\rUSERDATARESET\x10\xd8\t\x12\x17\n\x12PROFACTIVATIONSNAP\x10\xe2\t\x12\x19\n\x14PROFACTIVATIONDIRECT\x10\xe7\t\x12\x13\n\x0eSOFTWAREUPDATE\x10\xec\t\x12\x15\n\x10PUSHNOTIFICATION\x10\xf6\t\x12\x12\n\rMECALLCOMMAND\x10\x9e\n\x12\x14\n\x0fPRECONDSTARTRCS\x10\xf8\n\x12\x13\n\x0ePRECONDSTOPRCS\x10\x82\x0b\x12\x18\n\x13PRECONDCONFIGURERCS\x10\x8c\x0b\x12\x11\n\x0cTCUCONFIGURE\x10\x96\x0b\x12\x1c\n\x17\x45\x44ISONSERVICEACTIVATION\x10\x97\x0b\x12\x11\n\x0cTESTSEQUENCE\x10\x98\x0b\x12\x19\n\x14PRECONDCONFIGURERACP\x10\x99\x0b\x12\x1b\n\x16\x43HARGEOPTCONFIGURERACP\x10\x9a\x0b\x12\x18\n\x13TARIFFTABLEDOWNLOAD\x10\x9b\x0b\x12\x15\n\x10PRECONDSTARTRACP\x10\x9c\x0b\x12\x14\n\x0fPRECONDSTOPRACP\x10\x9d\x0b\x12\x1a\n\x15ROOTCERTIFICATEREMOVE\x10\x9e\x0b\x12\x19\n\x14ONREQUESTPROBEUPLOAD\x10\x9f\x0b\x12\x1c\n\x17ROOTCERTIFICATEDOWNLOAD\x10\xa0\x0b\x12\x1e\n\x19\x43ONTRACTCERTIFICATEREMOVE\x10\xa1\x0b\x12 \n\x1b\x43ONTRACTCERTIFICATEDOWNLOAD\x10\xa2\x0b\x12\x1d\n\x18PROBECONFIGURATIONUPDATE\x10\xa3\x0b\x12\x13\n\x0eRDIAGDELETEECU\x10\xdc\x0b\x12\x16\n\x11RDIAGSTATUSREPORT\x10\xdd\x0b\x12\x13\n\x0eRDIAGEXECUTION\x10\xde\x0b\x12\x19\n\x14IMMOBILIZERCHALLENGE\x10\xc0\x0c\x12\x1d\n\x18IMMOBILIZERSEARCHKEYLINE\x10\xca\x0c\x12\x1e\n\x19IMMOBILIZERRELEASEKEYLINE\x10\xd4\x0c\x12\x1b\n\x16IMMOBILIZERLOCKKEYLINE\x10\xde\x0c\x12\x1b\n\x16IMMOBILIZERLOCKVEHICLE\x10\xdf\x0c\x12\x1e\n\x19IMMOBILIZERRELEASEVEHICLE\x10\xd5\x0c\x12\x14\n\x0fSETRENTALSIGNAL\x10\xa4\r\x12\x19\n\x14\x42LACKCHANNELDOWNLOAD\x10\x88\x0e\x12\x17\n\x12\x42LACKCHANNELUPLOAD\x10\x92\x0e\x12\x11\n\x0c\x43ONFIGURECSM\x10\xec\x0e\x12\x16\n\x11UPDATEVEHICLEINFO\x10\xed\x0e\x12\x16\n\x11RELAYMESSAGETOCSM\x10\xee\x0e\x12\x1c\n\x17RELAYRENTALREQUESTTOCSB\x10\xef\x0e\x12\x16\n\x11RTMDOWNLOADCONFIG\x10\xe0\x12\x12\x12\n\rRTMREADCONFIG\x10\xea\x12\x12\x10\n\x0b\x41VPACTIVATE\x10\x8c\x15\x12\x1b\n\x16\x43HARGECONTROLCONFIGURE\x10\xf0\x15\x12%\n CHARGINGBREAKCLOCKTIMERCONFIGURE\x10\xb8\x17\x12\x0f\n\nWIPERRESET\x10\xa6\x18\x12\x16\n\x12unknownCommandType\x10\x00\x12\r\n\tdoorsLock\x10\x64\x12\x0f\n\x0b\x64oorsUnlock\x10n\x12\x0f\n\x0btrunkUnlock\x10s\x12\x12\n\x0e\x66uelflapUnlock\x10t\x12\x17\n\x13\x63hargecouplerUnlock\x10v\x12\x16\n\x12\x64oorsPrepareRental\x10x\x12\x17\n\x12\x64oorsSecureVehicle\x10\x82\x01\x12\x11\n\x0c\x61uxheatStart\x10\xac\x02\x12\x10\n\x0b\x61uxheatStop\x10\xb6\x02\x12\x15\n\x10\x61uxheatConfigure\x10\xc0\x02\x12\x19\n\x14temperatureConfigure\x10\xde\x02\x12\x19\n\x14weekprofileConfigure\x10\xe8\x02\x12\x1b\n\x16weekprofileV2Configure\x10\xf2\x02\x12\x11\n\x0cprecondStart\x10\x90\x03\x12\x10\n\x0bprecondStop\x10\x9a\x03\x12\x15\n\x10precondConfigure\x10\xa4\x03\x12\x1a\n\x15precondConfigureSeats\x10\xa9\x03\x12\x17\n\x12\x63hargeoptConfigure\x10\xae\x03\x12\x13\n\x0e\x63hargeoptStart\x10\xb8\x03\x12\x12\n\rchargeoptStop\x10\xc2\x03\x12\x0c\n\x07\x66\x65\x65\x64Poi\x10\xf4\x03\x12\x11\n\x0c\x66\x65\x65\x64\x46reetext\x10\xfe\x03\x12\x10\n\x0b\x65ngineStart\x10\xa6\x04\x12\x0f\n\nengineStop\x10\xb0\x04\x12\x13\n\x0e\x65ngineAvpstart\x10\xba\x04\x12\x0e\n\ttcuWakeup\x10\xd8\x04\x12\x10\n\x0btcuSwUpdate\x10\xe2\x04\x12\x10\n\x0btcuRcsReset\x10\xec\x04\x12\x15\n\x10tcuInterrogation\x10\xf6\x04\x12\x14\n\x0fspeedalertStart\x10\xc6\x05\x12\x13\n\x0espeedalertStop\x10\xd0\x05\x12\x0e\n\tflshStart\x10\xee\x05\x12\r\n\x08\x66lshStop\x10\xf8\x05\x12\x10\n\x0bsigposStart\x10\x82\x06\x12\x16\n\x11\x63ontractConfigure\x10\xa0\x06\x12\x13\n\x0e\x63ontractRemove\x10\xaa\x06\x12\x12\n\rrootConfigure\x10\xb4\x06\x12\x0f\n\nrootRemove\x10\xbe\x06\x12\r\n\x08tripcomp\x10\xd2\x06\x12\x19\n\x14maintenanceConfigure\x10\xa2\x07\x12\x1e\n\x19maintenanceComputerOffset\x10\xa3\x07\x12\x15\n\x10shorttestExecute\x10\xa7\x07\x12\x1f\n\x1aserviceactivationConfigure\x10\xac\x07\x12"\n\x1d\x64\x63\x32ServiceactivationConfigure\x10\xb1\x07\x12\x13\n\x0e\x64\x63\x32RawDownload\x10\xb6\x07\x12\x1d\n\x18\x61pplicationConfiguration\x10\xbb\x07\x12\x15\n\x10\x64\x63\x32StartTracking\x10\xc0\x07\x12\x10\n\x0b\x61tpSequence\x10\xde\x07\x12\x1d\n\x18theftalarmToggleInterior\x10\xe8\x07\x12\x18\n\x13theftalarmToggleTow\x10\xf2\x07\x12 \n\x1btheftalarmSelectInteriorTow\x10\xfc\x07\x12"\n\x1dtheftalarmDeselectInteriorTow\x10\x86\x08\x12\x13\n\x0etheftalarmStop\x10\x90\x08\x12\x0f\n\nwindowOpen\x10\xcc\x08\x12\x10\n\x0bwindowClose\x10\xd6\x08\x12\x14\n\x0fwindowVentilate\x10\xe0\x08\x12\x0f\n\nwindowMove\x10\xe1\x08\x12\r\n\x08roofOpen\x10\xea\x08\x12\x0e\n\troofClose\x10\xf4\x08\x12\r\n\x08roofLift\x10\xfe\x08\x12\r\n\x08roofMove\x10\xff\x08\x12\x12\n\rbatteryMaxsoc\x10\xd0\x0f\x12\x19\n\x14\x62\x61tteryChargeprogram\x10\xda\x0f\x12\x1b\n\x16\x63hargeprogramconfigure\x10\xe4\x0f\x12\x18\n\x13onboardfencesCreate\x10\xb4\x10\x12\x18\n\x13onboardfencesUpdate\x10\xbe\x10\x12\x18\n\x13onboardfencesDelete\x10\xc8\x10\x12\x16\n\x11speedfencesCreate\x10\x98\x11\x12\x16\n\x11speedfencesUpdate\x10\xa2\x11\x12\x16\n\x11speedfencesDelete\x10\xac\x11\x12\x1a\n\x15\x63hargingtariffsCreate\x10\xfc\x11\x12\x1a\n\x15\x63hargingtariffsUpdate\x10\x86\x12\x12\x1a\n\x15\x63hargingtariffsDelete\x10\x90\x12\x12\x14\n\x0ftheftalarmstart\x10\xc4\x13\x12\x1d\n\x18theftalarmselectinterior\x10\xce\x13\x12\x1f\n\x1atheftalarmdeselectinterior\x10\xd8\x13\x12\x18\n\x13theftalarmselecttow\x10\xe2\x13\x12\x1a\n\x15theftalarmdeselecttow\x10\xec\x13\x12$\n\x1ftheftalarmselectdamagedetection\x10\xf6\x13\x12&\n!theftalarmdeselectdamagedetection\x10\x80\x14\x12%\n theftalarmconfirmdamagedetection\x10\x8a\x14\x12\x11\n\x0cmecall2start\x10\xa8\x14\x12\x1e\n\x19udxTriggerSynchronization\x10\xb0\t\x12\x19\n\x14udxActiveUserProfile\x10\xba\t\x12\x15\n\x10udxResetUserData\x10\xc4\t\x12\x12\n\ruserProfSynch\x10\xce\t\x12\x12\n\ruserDataReset\x10\xd8\t\x12\x17\n\x12profActivationSnap\x10\xe2\t\x12\x19\n\x14profActivationDirect\x10\xe7\t\x12\x13\n\x0esoftwareUpdate\x10\xec\t\x12\x15\n\x10pushNotification\x10\xf6\t\x12\x12\n\rmecallcommand\x10\x9e\n\x12\x14\n\x0fprecondStartRcs\x10\xf8\n\x12\x13\n\x0eprecondStopRcs\x10\x82\x0b\x12\x18\n\x13precondConfigureRcs\x10\x8c\x0b\x12\x11\n\x0ctcuConfigure\x10\x96\x0b\x12\x1c\n\x17\x65\x64isonServiceActivation\x10\x97\x0b\x12\x11\n\x0ctestSequence\x10\x98\x0b\x12\x19\n\x14precondConfigureRacp\x10\x99\x0b\x12\x1b\n\x16\x63hargeoptConfigureRacp\x10\x9a\x0b\x12\x18\n\x13tariffTableDownload\x10\x9b\x0b\x12\x15\n\x10precondStartRacp\x10\x9c\x0b\x12\x14\n\x0fprecondStopRacp\x10\x9d\x0b\x12\x1a\n\x15rootCertificateRemove\x10\x9e\x0b\x12\x19\n\x14onRequestProbeUpload\x10\x9f\x0b\x12\x1c\n\x17rootCertificateDownload\x10\xa0\x0b\x12\x1e\n\x19\x63ontractCertificateRemove\x10\xa1\x0b\x12 \n\x1b\x63ontractCertificateDownload\x10\xa2\x0b\x12\x1d\n\x18probeConfigurationUpdate\x10\xa3\x0b\x12\x13\n\x0erdiagDeleteEcu\x10\xdc\x0b\x12\x16\n\x11rdiagStatusReport\x10\xdd\x0b\x12\x13\n\x0erdiagExecution\x10\xde\x0b\x12\x19\n\x14immobilizerChallenge\x10\xc0\x0c\x12\x1d\n\x18immobilizerSearchKeyline\x10\xca\x0c\x12\x1e\n\x19immobilizerReleaseKeyline\x10\xd4\x0c\x12\x1b\n\x16immobilizerLockKeyline\x10\xde\x0c\x12\x1b\n\x16immobilizerLockVehicle\x10\xdf\x0c\x12\x1e\n\x19immobilizerReleaseVehicle\x10\xd5\x0c\x12\x14\n\x0fsetRentalSignal\x10\xa4\r\x12\x19\n\x14\x62lackchannelDownload\x10\x88\x0e\x12\x17\n\x12\x62lackchannelUpload\x10\x92\x0e\x12\x11\n\x0c\x63onfigurecsm\x10\xec\x0e\x12\x16\n\x11updatevehicleinfo\x10\xed\x0e\x12\x16\n\x11relaymessagetocsm\x10\xee\x0e\x12\x1c\n\x17relayrentalrequesttocsb\x10\xef\x0e\x12\x16\n\x11rtmDownloadConfig\x10\xe0\x12\x12\x12\n\rrtmReadConfig\x10\xea\x12\x12\x10\n\x0b\x61vpActivate\x10\x8c\x15\x12\x1b\n\x16\x63hargecontrolconfigure\x10\xf0\x15\x12%\n chargingbreakclocktimerconfigure\x10\xb8\x17\x12\x0f\n\nwiperreset\x10\xa6\x18\x1a\x02\x10\x01\x42 \n\x1a\x63om.daimler.mbcarkit.proto\xd0\xe1\x1e\x01\x62\x06proto3' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "acp_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals["DESCRIPTOR"]._serialized_options = b"\n\032com.daimler.mbcarkit.proto\320\341\036\001" _globals["_VEHICLEAPI_QUEUETYPE"]._loaded_options = None _globals["_VEHICLEAPI_QUEUETYPE"]._serialized_options = b"\020\001" _globals["_ACP_COMMANDTYPE"]._loaded_options = None _globals["_ACP_COMMANDTYPE"]._serialized_options = b"\020\001" _globals["_VVA"]._serialized_start = 33 _globals["_VVA"]._serialized_end = 326 _globals["_VVA_COMMANDSTATE"]._serialized_start = 40 _globals["_VVA_COMMANDSTATE"]._serialized_end = 158 _globals["_VVA_COMMANDCONDITION"]._serialized_start = 161 _globals["_VVA_COMMANDCONDITION"]._serialized_end = 326 _globals["_VEHICLEAPI"]._serialized_start = 329 _globals["_VEHICLEAPI"]._serialized_end = 1863 _globals["_VEHICLEAPI_COMMANDSTATE"]._serialized_start = 344 _globals["_VEHICLEAPI_COMMANDSTATE"]._serialized_end = 580 _globals["_VEHICLEAPI_ATTRIBUTESTATUS"]._serialized_start = 582 _globals["_VEHICLEAPI_ATTRIBUTESTATUS"]._serialized_end = 665 _globals["_VEHICLEAPI_QUEUETYPE"]._serialized_start = 668 _globals["_VEHICLEAPI_QUEUETYPE"]._serialized_end = 1863 _globals["_ACP"]._serialized_start = 1866 _globals["_ACP"]._serialized_end = 8247 _globals["_ACP_COMMANDTYPE"]._serialized_start = 1874 _globals["_ACP_COMMANDTYPE"]._serialized_end = 8247 # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/proto/client_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: client.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() import custom_components.mbapi2020.proto.protos_pb2 as protos__pb2 import custom_components.mbapi2020.proto.service_activation_pb2 as service__activation__pb2 import custom_components.mbapi2020.proto.user_events_pb2 as user__events__pb2 import custom_components.mbapi2020.proto.vehicle_commands_pb2 as vehicle__commands__pb2 import custom_components.mbapi2020.proto.vehicle_events_pb2 as vehicle__events__pb2 import custom_components.mbapi2020.proto.vehicleapi_pb2 as vehicleapi__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\x0c\x63lient.proto\x12\x05proto\x1a\x0cprotos.proto\x1a\x18service-activation.proto\x1a\x11user-events.proto\x1a\x16vehicle-commands.proto\x1a\x14vehicle-events.proto\x1a\x10vehicleapi.proto"\xca\r\n\rClientMessage\x12\x13\n\x0btracking_id\x18\x05 \x01(\t\x12\x37\n\x12unsubscribeRequest\x18\x02 \x01(\x0b\x32\x19.proto.UnsubscribeRequestH\x00\x12/\n\x0e\x63ommandRequest\x18\x03 \x01(\x0b\x32\x15.proto.CommandRequestH\x00\x12.\n\x0etracking_event\x18\x04 \x01(\x0b\x32\x14.proto.TrackingEventH\x00\x12\x35\n\rping_interval\x18\x06 \x01(\x0b\x32\x1c.proto.ConfigurePingIntervalH\x00\x12?\n\x17\x61\x63knowledge_vep_request\x18\x07 \x01(\x0b\x32\x1c.proto.AcknowledgeVEPRequestH\x00\x12`\n)acknowledge_service_status_updates_by_vin\x18\t \x01(\x0b\x32+.proto.AcknowledgeServiceStatusUpdatesByVINH\x00\x12R\n!acknowledge_service_status_update\x18\r \x01(\x0b\x32%.proto.AcknowledgeServiceStatusUpdateH\x00\x12H\n\x1c\x61\x63knowledge_user_data_update\x18\n \x01(\x0b\x32 .proto.AcknowledgeUserDataUpdateH\x00\x12N\n\x1f\x61\x63knowledge_user_picture_update\x18\x0b \x01(\x0b\x32#.proto.AcknowledgeUserPictureUpdateH\x00\x12\x46\n\x1b\x61\x63knowledge_user_pin_update\x18\x0c \x01(\x0b\x32\x1f.proto.AcknowledgeUserPINUpdateH\x00\x12>\n\x17update_user_jwt_request\x18\x0e \x01(\x0b\x32\x1b.proto.UpdateUserJWTRequestH\x00\x12\x66\n,acknowledge_user_vehicle_auth_changed_update\x18\x0f \x01(\x0b\x32..proto.AcknowledgeUserVehicleAuthChangedUpdateH\x00\x12\x82\x01\n\n\x16unsafe_unmarshaler_all\x12\x1c.google.protobuf.FileOptions\x18\xb0\xec\x03 \x01(\x08:B\n\x1agoproto_extensions_map_all\x12\x1c.google.protobuf.FileOptions\x18\xb1\xec\x03 \x01(\x08:@\n\x18goproto_unrecognized_all\x12\x1c.google.protobuf.FileOptions\x18\xb2\xec\x03 \x01(\x08:8\n\x10gogoproto_import\x12\x1c.google.protobuf.FileOptions\x18\xb3\xec\x03 \x01(\x08:6\n\x0eprotosizer_all\x12\x1c.google.protobuf.FileOptions\x18\xb4\xec\x03 \x01(\x08:3\n\x0b\x63ompare_all\x12\x1c.google.protobuf.FileOptions\x18\xb5\xec\x03 \x01(\x08:4\n\x0ctypedecl_all\x12\x1c.google.protobuf.FileOptions\x18\xb6\xec\x03 \x01(\x08:4\n\x0c\x65numdecl_all\x12\x1c.google.protobuf.FileOptions\x18\xb7\xec\x03 \x01(\x08:<\n\x14goproto_registration\x12\x1c.google.protobuf.FileOptions\x18\xb8\xec\x03 \x01(\x08:7\n\x0fmessagename_all\x12\x1c.google.protobuf.FileOptions\x18\xb9\xec\x03 \x01(\x08:=\n\x15goproto_sizecache_all\x12\x1c.google.protobuf.FileOptions\x18\xba\xec\x03 \x01(\x08:;\n\x13goproto_unkeyed_all\x12\x1c.google.protobuf.FileOptions\x18\xbb\xec\x03 \x01(\x08::\n\x0fgoproto_getters\x12\x1f.google.protobuf.MessageOptions\x18\x81\xf4\x03 \x01(\x08:;\n\x10goproto_stringer\x12\x1f.google.protobuf.MessageOptions\x18\x83\xf4\x03 \x01(\x08:8\n\rverbose_equal\x12\x1f.google.protobuf.MessageOptions\x18\x84\xf4\x03 \x01(\x08:/\n\x04\x66\x61\x63\x65\x12\x1f.google.protobuf.MessageOptions\x18\x85\xf4\x03 \x01(\x08:3\n\x08gostring\x12\x1f.google.protobuf.MessageOptions\x18\x86\xf4\x03 \x01(\x08:3\n\x08populate\x12\x1f.google.protobuf.MessageOptions\x18\x87\xf4\x03 \x01(\x08:3\n\x08stringer\x12\x1f.google.protobuf.MessageOptions\x18\xc0\x8b\x04 \x01(\x08:2\n\x07onlyone\x12\x1f.google.protobuf.MessageOptions\x18\x89\xf4\x03 \x01(\x08:0\n\x05\x65qual\x12\x1f.google.protobuf.MessageOptions\x18\x8d\xf4\x03 \x01(\x08:6\n\x0b\x64\x65scription\x12\x1f.google.protobuf.MessageOptions\x18\x8e\xf4\x03 \x01(\x08:2\n\x07testgen\x12\x1f.google.protobuf.MessageOptions\x18\x8f\xf4\x03 \x01(\x08:3\n\x08\x62\x65nchgen\x12\x1f.google.protobuf.MessageOptions\x18\x90\xf4\x03 \x01(\x08:4\n\tmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x91\xf4\x03 \x01(\x08:6\n\x0bunmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x92\xf4\x03 \x01(\x08:;\n\x10stable_marshaler\x12\x1f.google.protobuf.MessageOptions\x18\x93\xf4\x03 \x01(\x08:0\n\x05sizer\x12\x1f.google.protobuf.MessageOptions\x18\x94\xf4\x03 \x01(\x08:;\n\x10unsafe_marshaler\x12\x1f.google.protobuf.MessageOptions\x18\x97\xf4\x03 \x01(\x08:=\n\x12unsafe_unmarshaler\x12\x1f.google.protobuf.MessageOptions\x18\x98\xf4\x03 \x01(\x08:A\n\x16goproto_extensions_map\x12\x1f.google.protobuf.MessageOptions\x18\x99\xf4\x03 \x01(\x08:?\n\x14goproto_unrecognized\x12\x1f.google.protobuf.MessageOptions\x18\x9a\xf4\x03 \x01(\x08:5\n\nprotosizer\x12\x1f.google.protobuf.MessageOptions\x18\x9c\xf4\x03 \x01(\x08:2\n\x07\x63ompare\x12\x1f.google.protobuf.MessageOptions\x18\x9d\xf4\x03 \x01(\x08:3\n\x08typedecl\x12\x1f.google.protobuf.MessageOptions\x18\x9e\xf4\x03 \x01(\x08:6\n\x0bmessagename\x12\x1f.google.protobuf.MessageOptions\x18\xa1\xf4\x03 \x01(\x08:<\n\x11goproto_sizecache\x12\x1f.google.protobuf.MessageOptions\x18\xa2\xf4\x03 \x01(\x08::\n\x0fgoproto_unkeyed\x12\x1f.google.protobuf.MessageOptions\x18\xa3\xf4\x03 \x01(\x08:1\n\x08nullable\x12\x1d.google.protobuf.FieldOptions\x18\xe9\xfb\x03 \x01(\x08:.\n\x05\x65mbed\x12\x1d.google.protobuf.FieldOptions\x18\xea\xfb\x03 \x01(\x08:3\n\ncustomtype\x12\x1d.google.protobuf.FieldOptions\x18\xeb\xfb\x03 \x01(\t:3\n\ncustomname\x12\x1d.google.protobuf.FieldOptions\x18\xec\xfb\x03 \x01(\t:0\n\x07jsontag\x12\x1d.google.protobuf.FieldOptions\x18\xed\xfb\x03 \x01(\t:1\n\x08moretags\x12\x1d.google.protobuf.FieldOptions\x18\xee\xfb\x03 \x01(\t:1\n\x08\x63\x61sttype\x12\x1d.google.protobuf.FieldOptions\x18\xef\xfb\x03 \x01(\t:0\n\x07\x63\x61stkey\x12\x1d.google.protobuf.FieldOptions\x18\xf0\xfb\x03 \x01(\t:2\n\tcastvalue\x12\x1d.google.protobuf.FieldOptions\x18\xf1\xfb\x03 \x01(\t:0\n\x07stdtime\x12\x1d.google.protobuf.FieldOptions\x18\xf2\xfb\x03 \x01(\x08:4\n\x0bstdduration\x12\x1d.google.protobuf.FieldOptions\x18\xf3\xfb\x03 \x01(\x08:3\n\nwktpointer\x12\x1d.google.protobuf.FieldOptions\x18\xf4\xfb\x03 \x01(\x08\x42\x45\n\x13\x63om.google.protobufB\nGoGoProtosZ"github.com/gogo/protobuf/gogoproto' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "gogo_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals[ "DESCRIPTOR" ]._serialized_options = b'\n\023com.google.protobufB\nGoGoProtosZ"github.com/gogo/protobuf/gogoproto' # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/proto/protos_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: protos.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\x0cprotos.proto\x12\x05proto"3\n\x10SubscribeRequest\x12\x0e\n\x06topics\x18\x01 \x03(\t\x12\x0f\n\x07replace\x18\x02 \x01(\x08"\xbe\x01\n\x11SubscribeResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x34\n\x06\x65rrors\x18\x02 \x03(\x0b\x32$.proto.SubscribeResponse.ErrorsEntry\x12\x19\n\x11subscribed_topics\x18\x03 \x03(\t\x1aG\n\x0b\x45rrorsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\'\n\x05value\x18\x02 \x01(\x0b\x32\x18.proto.SubscriptionError:\x02\x38\x01"A\n\x12UnsubscribeRequest\x12\x0e\n\x06topics\x18\x01 \x03(\t\x12\x1b\n\x13\x61nticipate_response\x18\x02 \x01(\x08"\xc4\x01\n\x13UnsubscribeResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x36\n\x06\x65rrors\x18\x02 \x03(\x0b\x32&.proto.UnsubscribeResponse.ErrorsEntry\x12\x1b\n\x13unsubscribed_topics\x18\x03 \x03(\t\x1aG\n\x0b\x45rrorsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\'\n\x05value\x18\x02 \x01(\x0b\x32\x18.proto.SubscriptionError:\x02\x38\x01"P\n\x11SubscriptionError\x12*\n\x04\x63ode\x18\x01 \x03(\x0e\x32\x1c.proto.SubscriptionErrorType\x12\x0f\n\x07message\x18\x02 \x03(\t"\x81\x02\n\x19SubscribeToAppTwinRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0f\n\x07\x63iam_id\x18\x02 \x01(\t\x12\x15\n\rdevice_locale\x18\x03 \x01(\t\x12\x0e\n\x06\x61pp_id\x18\x04 \x01(\t\x12\x13\n\x0b\x61pp_version\x18\x05 \x01(\t\x12+\n\x07os_name\x18\x06 \x01(\x0e\x32\x1a.proto.OperatingSystemName\x12\x12\n\nos_version\x18\x07 \x01(\t\x12\x14\n\x0c\x64\x65vice_model\x18\x08 \x01(\t\x12\x17\n\x0fnetwork_carrier\x18\t \x01(\t\x12\x13\n\x0bsdk_version\x18\n \x01(\t"B\n\x1bResubscribeToAppTwinRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t\x12\x0f\n\x07\x63iam_id\x18\x02 \x01(\t"\xcc\x01\n\x1cResubscribeToAppTwinResponse\x12\x45\n\x06result\x18\x01 \x01(\x0e\x32\x35.proto.ResubscribeToAppTwinResponse.ResubscribeResult"e\n\x11ResubscribeResult\x12\x11\n\rUNKNOWN_ERROR\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\x12\x15\n\x11INVALID_JWT_ERROR\x10\x02\x12\x19\n\x15TARGET_DOES_NOT_EXIST\x10\x03"_\n\x1aSubscribeToAppTwinResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x30\n\nerror_code\x18\x02 \x01(\x0e\x32\x1c.proto.SubscriptionErrorType"3\n\x1dUnsubscribeFromAppTwinRequest\x12\x12\n\nsession_id\x18\x01 \x01(\t"\xbd\x01\n\x1eUnsubscribeFromAppTwinResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x41\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x31.proto.UnsubscribeFromAppTwinResponse.ErrorsEntry\x1aG\n\x0b\x45rrorsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\'\n\x05value\x18\x02 \x01(\x0b\x32\x18.proto.SubscriptionError:\x02\x38\x01"\x0b\n\tHeartbeat" \n\x10\x41ssignedVehicles\x12\x0c\n\x04vins\x18\x01 \x03(\t"\x1d\n\x1b\x41\x63knowledgeAssignedVehicles*5\n\x15SubscriptionErrorType\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0f\n\x0bINVALID_JWT\x10\x01*q\n\x13OperatingSystemName\x12\x1c\n\x18UNKNOWN_OPERATING_SYSTEM\x10\x00\x12\x07\n\x03IOS\x10\x01\x12\x0b\n\x07\x41NDROID\x10\x02\x12\x0c\n\x08INT_TEST\x10\x03\x12\x0f\n\x0bMANUAL_TEST\x10\x04\x12\x07\n\x03WEB\x10\x05\x42\x1c\n\x1a\x63om.daimler.mbcarkit.protob\x06proto3' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "protos_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals["DESCRIPTOR"]._serialized_options = b"\n\032com.daimler.mbcarkit.proto" _globals["_SUBSCRIBERESPONSE_ERRORSENTRY"]._loaded_options = None _globals["_SUBSCRIBERESPONSE_ERRORSENTRY"]._serialized_options = b"8\001" _globals["_UNSUBSCRIBERESPONSE_ERRORSENTRY"]._loaded_options = None _globals["_UNSUBSCRIBERESPONSE_ERRORSENTRY"]._serialized_options = b"8\001" _globals["_UNSUBSCRIBEFROMAPPTWINRESPONSE_ERRORSENTRY"]._loaded_options = None _globals["_UNSUBSCRIBEFROMAPPTWINRESPONSE_ERRORSENTRY"]._serialized_options = b"8\001" _globals["_SUBSCRIPTIONERRORTYPE"]._serialized_start = 1572 _globals["_SUBSCRIPTIONERRORTYPE"]._serialized_end = 1625 _globals["_OPERATINGSYSTEMNAME"]._serialized_start = 1627 _globals["_OPERATINGSYSTEMNAME"]._serialized_end = 1740 _globals["_SUBSCRIBEREQUEST"]._serialized_start = 23 _globals["_SUBSCRIBEREQUEST"]._serialized_end = 74 _globals["_SUBSCRIBERESPONSE"]._serialized_start = 77 _globals["_SUBSCRIBERESPONSE"]._serialized_end = 267 _globals["_SUBSCRIBERESPONSE_ERRORSENTRY"]._serialized_start = 196 _globals["_SUBSCRIBERESPONSE_ERRORSENTRY"]._serialized_end = 267 _globals["_UNSUBSCRIBEREQUEST"]._serialized_start = 269 _globals["_UNSUBSCRIBEREQUEST"]._serialized_end = 334 _globals["_UNSUBSCRIBERESPONSE"]._serialized_start = 337 _globals["_UNSUBSCRIBERESPONSE"]._serialized_end = 533 _globals["_UNSUBSCRIBERESPONSE_ERRORSENTRY"]._serialized_start = 196 _globals["_UNSUBSCRIBERESPONSE_ERRORSENTRY"]._serialized_end = 267 _globals["_SUBSCRIPTIONERROR"]._serialized_start = 535 _globals["_SUBSCRIPTIONERROR"]._serialized_end = 615 _globals["_SUBSCRIBETOAPPTWINREQUEST"]._serialized_start = 618 _globals["_SUBSCRIBETOAPPTWINREQUEST"]._serialized_end = 875 _globals["_RESUBSCRIBETOAPPTWINREQUEST"]._serialized_start = 877 _globals["_RESUBSCRIBETOAPPTWINREQUEST"]._serialized_end = 943 _globals["_RESUBSCRIBETOAPPTWINRESPONSE"]._serialized_start = 946 _globals["_RESUBSCRIBETOAPPTWINRESPONSE"]._serialized_end = 1150 _globals["_RESUBSCRIBETOAPPTWINRESPONSE_RESUBSCRIBERESULT"]._serialized_start = 1049 _globals["_RESUBSCRIBETOAPPTWINRESPONSE_RESUBSCRIBERESULT"]._serialized_end = 1150 _globals["_SUBSCRIBETOAPPTWINRESPONSE"]._serialized_start = 1152 _globals["_SUBSCRIBETOAPPTWINRESPONSE"]._serialized_end = 1247 _globals["_UNSUBSCRIBEFROMAPPTWINREQUEST"]._serialized_start = 1249 _globals["_UNSUBSCRIBEFROMAPPTWINREQUEST"]._serialized_end = 1300 _globals["_UNSUBSCRIBEFROMAPPTWINRESPONSE"]._serialized_start = 1303 _globals["_UNSUBSCRIBEFROMAPPTWINRESPONSE"]._serialized_end = 1492 _globals["_UNSUBSCRIBEFROMAPPTWINRESPONSE_ERRORSENTRY"]._serialized_start = 196 _globals["_UNSUBSCRIBEFROMAPPTWINRESPONSE_ERRORSENTRY"]._serialized_end = 267 _globals["_HEARTBEAT"]._serialized_start = 1494 _globals["_HEARTBEAT"]._serialized_end = 1505 _globals["_ASSIGNEDVEHICLES"]._serialized_start = 1507 _globals["_ASSIGNEDVEHICLES"]._serialized_end = 1539 _globals["_ACKNOWLEDGEASSIGNEDVEHICLES"]._serialized_start = 1541 _globals["_ACKNOWLEDGEASSIGNEDVEHICLES"]._serialized_end = 1570 # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/proto/service_activation_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: service-activation.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\x18service-activation.proto\x12\x05proto"?\n$AcknowledgeServiceStatusUpdatesByVIN\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05"9\n\x1e\x41\x63knowledgeServiceStatusUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05"\xc0\x01\n\x19ServiceStatusUpdatesByVIN\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05\x12>\n\x07updates\x18\x02 \x03(\x0b\x32-.proto.ServiceStatusUpdatesByVIN.UpdatesEntry\x1aJ\n\x0cUpdatesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12)\n\x05value\x18\x02 \x01(\x0b\x32\x1a.proto.ServiceStatusUpdate:\x02\x38\x01"\x82\x02\n\x13ServiceStatusUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05\x12\x0f\n\x07\x63iam_id\x18\x07 \x01(\t\x12\x0b\n\x03vin\x18\x05 \x01(\t\x12\x16\n\x0e\x65mit_timestamp\x18\x02 \x01(\x03\x12\x1c\n\x14\x65mit_timestamp_in_ms\x18\x08 \x01(\x03\x12\x38\n\x07updates\x18\x06 \x03(\x0b\x32\'.proto.ServiceStatusUpdate.UpdatesEntry\x1a\x44\n\x0cUpdatesEntry\x12\x0b\n\x03key\x18\x01 \x01(\x05\x12#\n\x05value\x18\x02 \x01(\x0e\x32\x14.proto.ServiceStatus:\x02\x38\x01*\xb3\x01\n\rServiceStatus\x12\x1a\n\x16SERVICE_STATUS_UNKNOWN\x10\x00\x12\x19\n\x15SERVICE_STATUS_ACTIVE\x10\x01\x12\x1b\n\x17SERVICE_STATUS_INACTIVE\x10\x02\x12%\n!SERVICE_STATUS_ACTIVATION_PENDING\x10\x03\x12\'\n#SERVICE_STATUS_DEACTIVATION_PENDING\x10\x04\x42\x1c\n\x1a\x63om.daimler.mbcarkit.protob\x06proto3' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "service_activation_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals["DESCRIPTOR"]._serialized_options = b"\n\032com.daimler.mbcarkit.proto" _globals["_SERVICESTATUSUPDATESBYVIN_UPDATESENTRY"]._loaded_options = None _globals["_SERVICESTATUSUPDATESBYVIN_UPDATESENTRY"]._serialized_options = b"8\001" _globals["_SERVICESTATUSUPDATE_UPDATESENTRY"]._loaded_options = None _globals["_SERVICESTATUSUPDATE_UPDATESENTRY"]._serialized_options = b"8\001" _globals["_SERVICESTATUS"]._serialized_start = 616 _globals["_SERVICESTATUS"]._serialized_end = 795 _globals["_ACKNOWLEDGESERVICESTATUSUPDATESBYVIN"]._serialized_start = 35 _globals["_ACKNOWLEDGESERVICESTATUSUPDATESBYVIN"]._serialized_end = 98 _globals["_ACKNOWLEDGESERVICESTATUSUPDATE"]._serialized_start = 100 _globals["_ACKNOWLEDGESERVICESTATUSUPDATE"]._serialized_end = 157 _globals["_SERVICESTATUSUPDATESBYVIN"]._serialized_start = 160 _globals["_SERVICESTATUSUPDATESBYVIN"]._serialized_end = 352 _globals["_SERVICESTATUSUPDATESBYVIN_UPDATESENTRY"]._serialized_start = 278 _globals["_SERVICESTATUSUPDATESBYVIN_UPDATESENTRY"]._serialized_end = 352 _globals["_SERVICESTATUSUPDATE"]._serialized_start = 355 _globals["_SERVICESTATUSUPDATE"]._serialized_end = 613 _globals["_SERVICESTATUSUPDATE_UPDATESENTRY"]._serialized_start = 545 _globals["_SERVICESTATUSUPDATE_UPDATESENTRY"]._serialized_end = 613 # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/proto/user_events_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: user-events.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\x11user-events.proto\x12\x05proto"4\n\x19\x41\x63knowledgeUserDataUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05"\xbc\x01\n\x0eUserDataUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05\x12\x0f\n\x07\x63iam_id\x18\x02 \x01(\t\x12\x16\n\x0e\x65mit_timestamp\x18\x03 \x01(\x03\x12\x1c\n\x14\x65mit_timestamp_in_ms\x18\x08 \x01(\x03\x12$\n\x08old_data\x18\x06 \x01(\x0b\x32\x12.proto.CPDUserData\x12$\n\x08new_data\x18\x07 \x01(\x0b\x32\x12.proto.CPDUserData"B\n\'AcknowledgeUserVehicleAuthChangedUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05"N\n3AcknowledgeAbilityToGetVehicleMasterDataFromRestAPI\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05"~\n\x1cUserVehicleAuthChangedUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05\x12\x0f\n\x07\x63iam_id\x18\x02 \x01(\t\x12\x16\n\x0e\x65mit_timestamp\x18\x03 \x01(\x03\x12\x1c\n\x14\x65mit_timestamp_in_ms\x18\x08 \x01(\x03"\x9e\x04\n\x0b\x43PDUserData\x12\x0f\n\x07\x63iam_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\x12\n\nfirst_name\x18\x03 \x01(\t\x12\x12\n\nlast_name1\x18\x04 \x01(\t\x12\x12\n\nlast_name2\x18\x05 \x01(\t\x12\r\n\x05title\x18\x06 \x01(\t\x12\x13\n\x0bname_prefix\x18\x07 \x01(\t\x12\x16\n\x0emiddle_initial\x18\x08 \x01(\t\x12\x17\n\x0fsalutation_code\x18\t \x01(\t\x12\r\n\x05\x65mail\x18\n \x01(\t\x12\x16\n\x0elandline_phone\x18\x0b \x01(\t\x12\x1b\n\x13mobile_phone_number\x18\x0c \x01(\t\x12\x12\n\ncreated_at\x18\r \x01(\t\x12\x12\n\ncreated_by\x18\x0e \x01(\t\x12\x12\n\nupdated_at\x18\x0f \x01(\t\x12\x10\n\x08\x62irthday\x18\x1c \x01(\t\x12\x1f\n\x17preferred_language_code\x18\x1d \x01(\t\x12\x1c\n\x14\x61\x63\x63ount_country_code\x18\x1e \x01(\t\x12\r\n\x05uc_id\x18\x1f \x01(\t\x12\x0b\n\x03vip\x18 \x01(\x08\x12&\n\x07\x61\x64\x64ress\x18! \x01(\x0b\x32\x15.proto.CPDUserAddress\x12G\n\x18\x63ommunication_preference\x18" \x01(\x0b\x32%.proto.CPDUserCommunicationPreference"\xb3\x02\n\x0e\x43PDUserAddress\x12\x14\n\x0c\x63ountry_code\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\t\x12\x10\n\x08province\x18\x03 \x01(\t\x12\x0e\n\x06street\x18\x04 \x01(\t\x12\x10\n\x08house_no\x18\x05 \x01(\t\x12\x10\n\x08zip_code\x18\x06 \x01(\t\x12\x0c\n\x04\x63ity\x18\x07 \x01(\t\x12\x13\n\x0bstreet_type\x18\x08 \x01(\t\x12\x12\n\nhouse_name\x18\t \x01(\t\x12\x10\n\x08\x66loor_no\x18\n \x01(\t\x12\x0f\n\x07\x64oor_no\x18\x0b \x01(\t\x12\x15\n\raddress_line1\x18\x0c \x01(\t\x12\x15\n\raddress_line2\x18\r \x01(\t\x12\x15\n\raddress_line3\x18\x0e \x01(\t\x12\x17\n\x0fpost_office_box\x18\x0f \x01(\t"\x8f\x01\n\x1e\x43PDUserCommunicationPreference\x12\x1a\n\x12\x63ontacted_by_phone\x18\x01 \x01(\x08\x12\x1b\n\x13\x63ontacted_by_letter\x18\x02 \x01(\x08\x12\x1a\n\x12\x63ontacted_by_email\x18\x03 \x01(\x08\x12\x18\n\x10\x63ontacted_by_sms\x18\x04 \x01(\x08"7\n\x1c\x41\x63knowledgeUserPictureUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05"\xba\x01\n\x11UserPictureUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05\x12\x0f\n\x07\x63iam_id\x18\x05 \x01(\t\x12\x16\n\x0e\x65mit_timestamp\x18\x02 \x01(\x03\x12\x1c\n\x14\x65mit_timestamp_in_ms\x18\x06 \x01(\x03\x12"\n\x1a\x65venthub_receive_timestamp\x18\x03 \x01(\x03\x12!\n\x19\x61pptwin_receive_timestamp\x18\x04 \x01(\x03"3\n\x18\x41\x63knowledgeUserPINUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05"\xb6\x01\n\rUserPINUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05\x12\x0f\n\x07\x63iam_id\x18\x05 \x01(\t\x12\x16\n\x0e\x65mit_timestamp\x18\x02 \x01(\x03\x12\x1c\n\x14\x65mit_timestamp_in_ms\x18\x06 \x01(\x03\x12"\n\x1a\x65venthub_receive_timestamp\x18\x03 \x01(\x03\x12!\n\x19\x61pptwin_receive_timestamp\x18\x04 \x01(\x03"#\n\x14UpdateUserJWTRequest\x12\x0b\n\x03jwt\x18\x01 \x01(\t"!\n\x1f\x41\x63knowledgeUpdateUserJWTRequestB\x1c\n\x1a\x63om.daimler.mbcarkit.protob\x06proto3' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "user_events_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals["DESCRIPTOR"]._serialized_options = b"\n\032com.daimler.mbcarkit.proto" _globals["_ACKNOWLEDGEUSERDATAUPDATE"]._serialized_start = 28 _globals["_ACKNOWLEDGEUSERDATAUPDATE"]._serialized_end = 80 _globals["_USERDATAUPDATE"]._serialized_start = 83 _globals["_USERDATAUPDATE"]._serialized_end = 271 _globals["_ACKNOWLEDGEUSERVEHICLEAUTHCHANGEDUPDATE"]._serialized_start = 273 _globals["_ACKNOWLEDGEUSERVEHICLEAUTHCHANGEDUPDATE"]._serialized_end = 339 _globals["_ACKNOWLEDGEABILITYTOGETVEHICLEMASTERDATAFROMRESTAPI"]._serialized_start = 341 _globals["_ACKNOWLEDGEABILITYTOGETVEHICLEMASTERDATAFROMRESTAPI"]._serialized_end = 419 _globals["_USERVEHICLEAUTHCHANGEDUPDATE"]._serialized_start = 421 _globals["_USERVEHICLEAUTHCHANGEDUPDATE"]._serialized_end = 547 _globals["_CPDUSERDATA"]._serialized_start = 550 _globals["_CPDUSERDATA"]._serialized_end = 1092 _globals["_CPDUSERADDRESS"]._serialized_start = 1095 _globals["_CPDUSERADDRESS"]._serialized_end = 1402 _globals["_CPDUSERCOMMUNICATIONPREFERENCE"]._serialized_start = 1405 _globals["_CPDUSERCOMMUNICATIONPREFERENCE"]._serialized_end = 1548 _globals["_ACKNOWLEDGEUSERPICTUREUPDATE"]._serialized_start = 1550 _globals["_ACKNOWLEDGEUSERPICTUREUPDATE"]._serialized_end = 1605 _globals["_USERPICTUREUPDATE"]._serialized_start = 1608 _globals["_USERPICTUREUPDATE"]._serialized_end = 1794 _globals["_ACKNOWLEDGEUSERPINUPDATE"]._serialized_start = 1796 _globals["_ACKNOWLEDGEUSERPINUPDATE"]._serialized_end = 1847 _globals["_USERPINUPDATE"]._serialized_start = 1850 _globals["_USERPINUPDATE"]._serialized_end = 2032 _globals["_UPDATEUSERJWTREQUEST"]._serialized_start = 2034 _globals["_UPDATEUSERJWTREQUEST"]._serialized_end = 2069 _globals["_ACKNOWLEDGEUPDATEUSERJWTREQUEST"]._serialized_start = 2071 _globals["_ACKNOWLEDGEUPDATEUSERJWTREQUEST"]._serialized_end = 2104 # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/proto/vehicle_commands_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: vehicle-commands.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() from google.protobuf import wrappers_pb2 as google_dot_protobuf_dot_wrappers__pb2 import custom_components.mbapi2020.proto.gogo_pb2 as gogo__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\x16vehicle-commands.proto\x12\x05proto\x1a\ngogo.proto\x1a\x1egoogle/protobuf/wrappers.proto"/\n\x19\x41\x63knowledgeCommandRequest\x12\x12\n\nrequest_id\x18\x01 \x01(\t"\xca\x1f\n\x0e\x43ommandRequest\x12\x0b\n\x03vin\x18\x01 \x01(\t\x12\x12\n\nrequest_id\x18\x07 \x01(\t\x12.\n\x07\x62\x61\x63kend\x18$ \x01(\x0e\x32\x1d.proto.CommandRequest.Backend\x12,\n\rauxheat_start\x18\x02 \x01(\x0b\x32\x13.proto.AuxheatStartH\x00\x12*\n\x0c\x61uxheat_stop\x18\x03 \x01(\x0b\x32\x12.proto.AuxheatStopH\x00\x12\x34\n\x11\x61uxheat_configure\x18\x04 \x01(\x0b\x32\x17.proto.AuxheatConfigureH\x00\x12&\n\ndoors_lock\x18\x05 \x01(\x0b\x32\x10.proto.DoorsLockH\x00\x12*\n\x0c\x64oors_unlock\x18\x06 \x01(\x0b\x32\x12.proto.DoorsUnlockH\x00\x12*\n\x0csunroof_open\x18\t \x01(\x0b\x32\x12.proto.SunroofOpenH\x00\x12,\n\rsunroof_close\x18\n \x01(\x0b\x32\x13.proto.SunroofCloseH\x00\x12*\n\x0csunroof_lift\x18\x0b \x01(\x0b\x32\x12.proto.SunroofLiftH\x00\x12*\n\x0csunroof_move\x18/ \x01(\x0b\x32\x12.proto.SunroofMoveH\x00\x12*\n\x0cwindows_open\x18\x0c \x01(\x0b\x32\x12.proto.WindowsOpenH\x00\x12,\n\rwindows_close\x18\r \x01(\x0b\x32\x13.proto.WindowsCloseH\x00\x12\x34\n\x11windows_ventilate\x18+ \x01(\x0b\x32\x17.proto.WindowsVentilateH\x00\x12*\n\x0cwindows_move\x18, \x01(\x0b\x32\x12.proto.WindowsMoveH\x00\x12*\n\x0c\x65ngine_start\x18\x13 \x01(\x0b\x32\x12.proto.EngineStartH\x00\x12(\n\x0b\x65ngine_stop\x18\x14 \x01(\x0b\x32\x11.proto.EngineStopH\x00\x12\x43\n\x19zev_preconditioning_start\x18\x15 \x01(\x0b\x32\x1e.proto.ZEVPreconditioningStartH\x00\x12\x41\n\x18zev_preconditioning_stop\x18\x16 \x01(\x0b\x32\x1d.proto.ZEVPreconditioningStopH\x00\x12H\n\x1azev_precondition_configure\x18\x19 \x01(\x0b\x32".proto.ZEVPreconditioningConfigureH\x00\x12S\n zev_precondition_configure_seats\x18\x1a \x01(\x0b\x32\'.proto.ZEVPreconditioningConfigureSeatsH\x00\x12\x32\n\x10speedalert_start\x18\x17 \x01(\x0b\x32\x16.proto.SpeedalertStartH\x00\x12\x30\n\x0fspeedalert_stop\x18\x18 \x01(\x0b\x32\x15.proto.SpeedalertStopH\x00\x12\x46\n\x16\x62\x61ttery_charge_program\x18\x1b \x01(\x0b\x32$.proto.BatteryChargeProgramConfigureH\x00\x12\x38\n\x0f\x62\x61ttery_max_soc\x18\x1c \x01(\x0b\x32\x1d.proto.BatteryMaxSocConfigureH\x00\x12\x41\n\x18\x63harge_program_configure\x18" \x01(\x0b\x32\x1d.proto.ChargeProgramConfigureH\x00\x12\x41\n\x18\x63harge_control_configure\x18( \x01(\x0b\x32\x1d.proto.ChargeControlConfigureH\x00\x12\x39\n\x14\x63harge_opt_configure\x18\x1d \x01(\x0b\x32\x19.proto.ChargeOptConfigureH\x00\x12\x31\n\x10\x63harge_opt_start\x18\x1e \x01(\x0b\x32\x15.proto.ChargeOptStartH\x00\x12/\n\x0f\x63harge_opt_stop\x18\x1f \x01(\x0b\x32\x14.proto.ChargeOptStopH\x00\x12<\n\x15temperature_configure\x18 \x01(\x0b\x32\x1b.proto.TemperatureConfigureH\x00\x12=\n\x16week_profile_configure\x18! \x01(\x0b\x32\x1b.proto.WeekProfileConfigureH\x00\x12\x42\n\x19week_profile_configure_v2\x18) \x01(\x0b\x32\x1d.proto.WeekProfileConfigureV2H\x00\x12*\n\x0csigpos_start\x18# \x01(\x0b\x32\x12.proto.SigPosStartH\x00\x12W\n#theftalarm_deselect_damagedetection\x18\x0e \x01(\x0b\x32(.proto.TheftalarmDeselectDamagedetectionH\x00\x12I\n\x1ctheftalarm_deselect_interior\x18\x0f \x01(\x0b\x32!.proto.TheftalarmDeselectInteriorH\x00\x12?\n\x17theftalarm_deselect_tow\x18\x10 \x01(\x0b\x32\x1c.proto.TheftalarmDeselectTowH\x00\x12S\n!theftalarm_select_damagedetection\x18\x11 \x01(\x0b\x32&.proto.TheftalarmSelectDamagedetectionH\x00\x12\x45\n\x1atheftalarm_select_interior\x18\x12 \x01(\x0b\x32\x1f.proto.TheftalarmSelectInteriorH\x00\x12;\n\x15theftalarm_select_tow\x18% \x01(\x0b\x32\x1a.proto.TheftalarmSelectTowH\x00\x12\x32\n\x10theftalarm_start\x18& \x01(\x0b\x32\x16.proto.TheftalarmStartH\x00\x12\x30\n\x0ftheftalarm_stop\x18\' \x01(\x0b\x32\x15.proto.TheftalarmStopH\x00\x12P\n automatic_valet_parking_activate\x18* \x01(\x0b\x32$.proto.AutomaticValetParkingActivateH\x00\x12\x35\n\x12\x63harge_flap_unlock\x18- \x01(\x0b\x32\x17.proto.ChargeFlapUnlockH\x00\x12;\n\x15\x63harge_coupler_unlock\x18. \x01(\x0b\x32\x1a.proto.ChargeCouplerUnlockH\x00\x12?\n\x17\x64\x65\x61\x63tivate_vehicle_keys\x18\x30 \x01(\x0b\x32\x1c.proto.DeactivateVehicleKeysH\x00\x12;\n\x15\x61\x63tivate_vehicle_keys\x18\x31 \x01(\x0b\x32\x1a.proto.ActivateVehicleKeysH\x00\x12U\n"chargingbreak_clocktimer_configure\x18\x32 \x01(\x0b\x32\'.proto.ChargingBreakClocktimerConfigureH\x00\x12\x45\n\x1aselective_key_deactivation\x18= \x01(\x0b\x32\x1f.proto.SelectiveKeyDeactivationH\x00\x12\x37\n\x13sunroof_blinds_move\x18> \x01(\x0b\x32\x18.proto.SunroofBlindsMoveH\x00\x12\x35\n\x12window_blinds_move\x18? \x01(\x0b\x32\x17.proto.WindowBlindsMoveH\x00\x12\x61\n)child_presence_detection_deactivate_alarm\x18\x41 \x01(\x0b\x32,.proto.ChildPresenceDetectionDeactivateAlarmH\x00\x12P\n interior_monitoring_take_picture\x18\x42 \x01(\x0b\x32$.proto.InteriorMonitoringTakePictureH\x00\x12P\n exterior_monitoring_take_picture\x18\x43 \x01(\x0b\x32$.proto.ExteriorMonitoringTakePictureH\x00\x12\x37\n\x13remote_update_start\x18\x44 \x01(\x0b\x32\x18.proto.RemoteUpdateStartH\x00\x12P\n theftalarm_select_picture_taking\x18\x45 \x01(\x0b\x32$.proto.TheftAlarmSelectPictureTakingH\x00\x12T\n"theftalarm_deselect_picture_taking\x18\x46 \x01(\x0b\x32&.proto.TheftAlarmDeselectPictureTakingH\x00\x12;\n\x15\x63lock_timer_configure\x18G \x01(\x0b\x32\x1a.proto.ClockTimerConfigureH\x00\x12\x36\n\x12\x63harging_configure\x18H \x01(\x0b\x32\x18.proto.ChargingConfigureH\x00\x12Y\n%child_presence_detection_take_picture\x18I \x01(\x0b\x32(.proto.ChildPresenceDetectionTakePictureH\x00\x12\x30\n\x0fstagemode_start\x18J \x01(\x0b\x32\x15.proto.StagemodeStartH\x00\x12.\n\x0estagemode_stop\x18K \x01(\x0b\x32\x14.proto.StagemodeStopH\x00\x12J\n\x1dhv_battery_start_conditioning\x18L \x01(\x0b\x32!.proto.HvBatteryStartConditioningH\x00\x12H\n\x1chv_battery_stop_conditioning\x18M \x01(\x0b\x32 .proto.HvBatteryStopConditioningH\x00\x12I\n\x1cremote_seat_ballet_configure\x18N \x01(\x0b\x32!.proto.RemoteSeatBallettConfigureH\x00""\n\x07\x42\x61\x63kend\x12\x07\n\x03VVA\x10\x00\x12\x0e\n\nVehicleAPI\x10\x01\x42\t\n\x07\x63ommand"\xbc\x07\n\x11\x43hargingConfigure\x12/\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x1f.proto.ChargingConfigure.Action\x12G\n\x13\x64\x63_charging_profile\x18\x02 \x01(\x0e\x32*.proto.ChargingConfigure.DcChargingProfile\x12M\n\x0e\x63harge_program\x18\x03 \x01(\x0e\x32&.proto.ChargingConfigure.ChargeProgramR\rchargeprogram\x12-\n\x08inlet_id\x18\x04 \x03(\x0b\x32\x1b.google.protobuf.Int32Value\x12,\n\x07max_soc\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12,\n\x07min_soc\x18\x06 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12/\n\ntarget_soc\x18\t \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x30\n\x0btarget_time\x18\n \x01(\x0b\x32\x1b.google.protobuf.Int64Value\x12U\n\x1asoh_calibration_activation\x18\x0b \x01(\x0e\x32\x31.proto.ChargingConfigure.SohCalibrationActivation"L\n\x06\x41\x63tion\x12\x16\n\x12NO_ACTION_SELECTED\x10\x00\x12\t\n\x05START\x10\x01\x12\t\n\x05PAUSE\x10\x02\x12\n\n\x06RESUME\x10\x03\x12\x08\n\x04STOP\x10\x04"\x92\x01\n\x11\x44\x63\x43hargingProfile\x12#\n\x1fNO_DC_CHARGING_PROFILE_SELECTED\x10\x00\x12\x0c\n\x08STANDARD\x10\x01\x12\x0e\n\nSILENT_ECO\x10\x02\x12\r\n\tULTRAFAST\x10\x03\x12\x0b\n\x07PITSTOP\x10\x04\x12\x0e\n\nFAST_ECO_1\x10\x05\x12\x0e\n\nFAST_ECO_2\x10\x06"]\n\rChargeProgram\x12\x1a\n\x16\x44\x45\x46\x41ULT_CHARGE_PROGRAM\x10\x00\x12\x17\n\x13HOME_CHARGE_PROGRAM\x10\x02\x12\x17\n\x13WORK_CHARGE_PROGRAM\x10\x03"W\n\x18SohCalibrationActivation\x12*\n&NO_SOH_CALIBRATION_ACTIVATION_SELECTED\x10\x00\x12\x06\n\x02ON\x10\x01\x12\x07\n\x03OFF\x10\x02"\x1c\n\x1aHvBatteryStartConditioning"\x1b\n\x19HvBatteryStopConditioning"\x1c\n\x1aRemoteSeatBallettConfigure"\xa5\x01\n\x15\x44\x65\x61\x63tivateVehicleKeys\x12\x0b\n\x03pin\x18\x01 \x01(\t\x12\x17\n\x0f\x65xpiration_unix\x18\x02 \x01(\x03\x12-\n\x12\x65xpiration_seconds\x18\x03 \x01(\tR\x11\x65xpirationSeconds\x12\x37\n\x17\x65xpiration_milliseconds\x18\x04 \x01(\tR\x16\x65xpirationMilliseconds"\xa3\x01\n\x13\x41\x63tivateVehicleKeys\x12\x0b\n\x03pin\x18\x01 \x01(\t\x12\x17\n\x0f\x65xpiration_unix\x18\x02 \x01(\x03\x12-\n\x12\x65xpiration_seconds\x18\x03 \x01(\tR\x11\x65xpirationSeconds\x12\x37\n\x17\x65xpiration_milliseconds\x18\x04 \x01(\tR\x16\x65xpirationMilliseconds"\x0e\n\x0c\x41uxheatStart"\r\n\x0b\x41uxheatStop"\x80\x02\n\x10\x41uxheatConfigure\x12O\n\x0etime_selection\x18\x01 \x01(\x0e\x32!.proto.AuxheatConfigure.SelectionR\x14\x61uxheattimeselection\x12\x1c\n\x06time_1\x18\x02 \x01(\x05R\x0c\x61uxheattime1\x12\x1c\n\x06time_2\x18\x03 \x01(\x05R\x0c\x61uxheattime2\x12\x1c\n\x06time_3\x18\x04 \x01(\x05R\x0c\x61uxheattime3"A\n\tSelection\x12\x10\n\x0cNO_SELECTION\x10\x00\x12\n\n\x06TIME_1\x10\x01\x12\n\n\x06TIME_2\x10\x02\x12\n\n\x06TIME_3\x10\x03"\'\n\tDoorsLock\x12\x1a\n\x05\x64oors\x18\x01 \x03(\x0e\x32\x0b.proto.Door"6\n\x0b\x44oorsUnlock\x12\x0b\n\x03pin\x18\x01 \x01(\t\x12\x1a\n\x05\x64oors\x18\x02 \x03(\x0e\x32\x0b.proto.Door"\x1a\n\x0b\x45ngineStart\x12\x0b\n\x03pin\x18\x01 \x01(\t"\x0c\n\nEngineStop"\x1a\n\x0bSunroofOpen\x12\x0b\n\x03pin\x18\x01 \x01(\t"\x0e\n\x0cSunroofClose"\x1a\n\x0bSunroofLift\x12\x0b\n\x03pin\x18\x01 \x01(\t"\xe9\x01\n\x0bSunroofMove\x12\x0b\n\x03pin\x18\x01 \x01(\t\x12\x35\n\x07sunroof\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x07sunroof\x12K\n\x13sunroof_blind_front\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x11sunroofblindfront\x12I\n\x12sunroof_blind_rear\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x10sunroofblindrear"\x1a\n\x0bWindowsOpen\x12\x0b\n\x03pin\x18\x01 \x01(\t"\x0e\n\x0cWindowsClose"\x1f\n\x10WindowsVentilate\x12\x0b\n\x03pin\x18\x01 \x01(\t"\xfc\x03\n\x0bWindowsMove\x12\x0b\n\x03pin\x18\x01 \x01(\t\x12@\n\nfront_left\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x0fwindowfrontleft\x12\x42\n\x0b\x66ront_right\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x10windowfrontright\x12@\n\nrear_blind\x18\x04 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x0fwindowrearblind\x12>\n\trear_left\x18\x05 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x0ewindowrearleft\x12I\n\x0frear_left_blind\x18\x06 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x13windowrearleftblind\x12@\n\nrear_right\x18\x07 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x0fwindowrearright\x12K\n\x10rear_right_blind\x18\x08 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x14windowrearrightblind"d\n\x0fSpeedalertStart\x12&\n\tthreshold\x18\x01 \x01(\x05R\x13speedAlertThreshold\x12)\n\x0e\x61lert_end_time\x18\x02 \x01(\x03R\x11speedAlertEndTime"\x10\n\x0eSpeedalertStop"s\n\x17ZEVPreconditioningStart\x12%\n\x0e\x64\x65parture_time\x18\x01 \x01(\x05R\rdeparturetime\x12\x31\n\x04type\x18\x02 \x01(\x0e\x32\x1d.proto.ZEVPreconditioningTypeR\x04type"K\n\x16ZEVPreconditioningStop\x12\x31\n\x04type\x18\x02 \x01(\x0e\x32\x1d.proto.ZEVPreconditioningTypeR\x04type"\xf9\x01\n\x1bZEVPreconditioningConfigure\x12\x64\n\x13\x64\x65parture_time_mode\x18\x01 \x01(\x0e\x32\x34.proto.ZEVPreconditioningConfigure.DepartureTimeModeR\x11\x64\x65partureTimeMode\x12%\n\x0e\x64\x65parture_time\x18\x03 \x01(\x05R\rdeparturetime"M\n\x11\x44\x65partureTimeMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x14\n\x10SINGLE_DEPARTURE\x10\x01\x12\x14\n\x10WEEKLY_DEPARTURE\x10\x02"\xca\x01\n ZEVPreconditioningConfigureSeats\x12(\n\nfront_left\x18\x01 \x01(\x08R\x14precondSeatFrontLeft\x12*\n\x0b\x66ront_right\x18\x02 \x01(\x08R\x15precondSeatFrontRight\x12&\n\trear_left\x18\x03 \x01(\x08R\x13precondSeatRearLeft\x12(\n\nrear_right\x18\x04 \x01(\x08R\x14precondSeatRearRight"\xa5\x01\n\x1d\x42\x61tteryChargeProgramConfigure\x12Y\n\x0e\x63harge_program\x18\x01 \x01(\x0e\x32\x32.proto.BatteryChargeProgramConfigure.ChargeProgramR\rchargeprogram")\n\rChargeProgram\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0b\n\x07INSTANT\x10\x01"1\n\x16\x42\x61tteryMaxSocConfigure\x12\x17\n\x07max_soc\x18\x01 \x01(\x05R\x06maxsoc"\x8e\x04\n\x16\x43hargeProgramConfigure\x12R\n\x0e\x63harge_program\x18\x01 \x01(\x0e\x32+.proto.ChargeProgramConfigure.ChargeProgramR\rchargeprogram\x12\x34\n\x07max_soc\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x06maxsoc\x12;\n\x0b\x61uto_unlock\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.BoolValueR\nautounlock\x12R\n\x17location_based_charging\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.BoolValueR\x15locationbasedcharging\x12;\n\x0b\x63lock_timer\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.BoolValueR\nclocktimer\x12=\n\x0c\x65\x63o_charging\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.BoolValueR\x0b\x65\x63ocharging"]\n\rChargeProgram\x12\x1a\n\x16\x44\x45\x46\x41ULT_CHARGE_PROGRAM\x10\x00\x12\x17\n\x13HOME_CHARGE_PROGRAM\x10\x02\x12\x17\n\x13WORK_CHARGE_PROGRAM\x10\x03"\xe0\x01\n\x16\x43hargeControlConfigure\x12L\n\x13\x62i_charging_enabled\x18\x01 \x01(\x0b\x32\x1a.google.protobuf.BoolValueR\x13\x62idichargingenabled\x12\x42\n\x0e\x63harging_power\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.FloatValueR\rchargingpower\x12\x34\n\x07min_soc\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x06minsoc"\xcc\x02\n\x12\x43hargeOptConfigure\x12G\n\x0eweekday_tariff\x18\x01 \x03(\x0b\x32 .proto.ChargeOptConfigure.TariffR\rweekdaytariff\x12G\n\x0eweekend_tariff\x18\x02 \x03(\x0b\x32 .proto.ChargeOptConfigure.TariffR\rweekendtariff\x1a\xa3\x01\n\x06Tariff\x12\x39\n\x04rate\x18\x01 \x01(\x0e\x32%.proto.ChargeOptConfigure.Tariff.RateR\x04rate\x12\x12\n\x04time\x18\x02 \x01(\x05R\x04time"J\n\x04Rate\x12\x11\n\rINVALID_PRICE\x10\x00\x12\r\n\tLOW_PRICE\x10!\x12\x10\n\x0cNORMAL_PRICE\x10,\x12\x0e\n\nHIGH_PRICE\x10\x42"\x10\n\x0e\x43hargeOptStart"\x0f\n\rChargeOptStop"\xcd\x04\n\x14TemperatureConfigure\x12[\n\x12temperature_points\x18\x01 \x03(\x0b\x32,.proto.TemperatureConfigure.TemperaturePointR\x11temperaturePoints\x1a\xd7\x03\n\x10TemperaturePoint\x12\x45\n\x04zone\x18\x01 \x01(\x0e\x32\x31.proto.TemperatureConfigure.TemperaturePoint.ZoneR\x04zone\x12$\n\x16temperature_in_celsius\x18\x03 \x01(\x01R\x04temp"\xcf\x02\n\x04Zone\x12\x0b\n\x07unknown\x10\x00\x12\r\n\tfrontLeft\x10\x01\x12\x0e\n\nfrontRight\x10\x02\x12\x0f\n\x0b\x66rontCenter\x10\x03\x12\x0c\n\x08rearLeft\x10\x04\x12\r\n\trearRight\x10\x05\x12\x0e\n\nrearCenter\x10\x06\x12\r\n\trear2Left\x10\x07\x12\x0e\n\nrear2Right\x10\x08\x12\x0f\n\x0brear2Center\x10\t\x12\x10\n\x0cUNKNOWN_ZONE\x10\x00\x12\x0e\n\nFRONT_LEFT\x10\x01\x12\x0f\n\x0b\x46RONT_RIGHT\x10\x02\x12\x10\n\x0c\x46RONT_CENTER\x10\x03\x12\r\n\tREAR_LEFT\x10\x04\x12\x0e\n\nREAR_RIGHT\x10\x05\x12\x0f\n\x0bREAR_CENTER\x10\x06\x12\x0f\n\x0bREAR_2_LEFT\x10\x07\x12\x10\n\x0cREAR_2_RIGHT\x10\x08\x12\x11\n\rREAR_2_CENTER\x10\t\x1a\x02\x10\x01J\x04\x08\x02\x10\x03"\xa9\x02\n\x14WeekProfileConfigure\x12K\n\rweekly_set_hu\x18\x01 \x03(\x0b\x32\'.proto.WeekProfileConfigure.WeeklySetHUR\x0bweeklySetHU\x1a\xc3\x01\n\x0bWeeklySetHU\x12=\n\x03\x64\x61y\x18\x01 \x01(\x0e\x32+.proto.WeekProfileConfigure.WeeklySetHU.DayR\x03\x64\x61y\x12\x12\n\x04time\x18\x02 \x01(\x05R\x04time"a\n\x03\x44\x61y\x12\n\n\x06MONDAY\x10\x00\x12\x0b\n\x07TUESDAY\x10\x01\x12\r\n\tWEDNESDAY\x10\x02\x12\x0c\n\x08THURSDAY\x10\x03\x12\n\n\x06\x46RIDAY\x10\x04\x12\x0c\n\x08SATURDAY\x10\x05\x12\n\n\x06SUNDAY\x10\x06"Q\n\x16WeekProfileConfigureV2\x12\x37\n\rtime_profiles\x18\x01 \x03(\x0b\x32\x12.proto.TimeProfileR\x0ctimeprofiles"\xb2\x02\n\x0bTimeProfile\x12\x33\n\nidentifier\x18\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x02id\x12/\n\x04hour\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x04hour\x12\x30\n\x06minute\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.Int32ValueR\x03min\x12(\n\x04\x64\x61ys\x18\x04 \x03(\x0e\x32\x15.proto.TimeProfileDayR\x03\x64\x61y\x12\x32\n\x06\x61\x63tive\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.BoolValueR\x06\x61\x63tive\x12-\n\x16\x61pplication_identifier\x18\x06 \x01(\x05R\rapplicationId"\xeb\x03\n\x0bSigPosStart\x12\x1f\n\x0bhorn_repeat\x18\x01 \x01(\x05R\nhornRepeat\x12\x38\n\thorn_type\x18\x02 \x01(\x0e\x32\x1b.proto.SigPosStart.HornTypeR\x08hornType\x12;\n\nlight_type\x18\x03 \x01(\x0e\x32\x1c.proto.SigPosStart.LightTypeR\tlightType\x12\'\n\x0fsigpos_duration\x18\x04 \x01(\x05R\x0esigposDuration\x12>\n\x0bsigpos_type\x18\x05 \x01(\x0e\x32\x1d.proto.SigPosStart.SigposTypeR\nsigposType"C\n\x08HornType\x12\x0c\n\x08HORN_OFF\x10\x00\x12\x13\n\x0fHORN_LOW_VOLUME\x10\x01\x12\x14\n\x10HORN_HIGH_VOLUME\x10\x02"D\n\tLightType\x12\r\n\tLIGHT_OFF\x10\x00\x12\x15\n\x11\x44IPPED_HEAD_LIGHT\x10\x01\x12\x11\n\rWARNING_LIGHT\x10\x02"P\n\nSigposType\x12\x0e\n\nLIGHT_ONLY\x10\x00\x12\r\n\tHORN_ONLY\x10\x01\x12\x12\n\x0eLIGHT_AND_HORN\x10\x02\x12\x0f\n\x0bPANIC_ALARM\x10\x03""\n TheftalarmConfirmDamagedetection"#\n!TheftalarmDeselectDamagedetection"\x1c\n\x1aTheftalarmDeselectInterior"\x17\n\x15TheftalarmDeselectTow"!\n\x1fTheftalarmSelectDamagedetection"\x1a\n\x18TheftalarmSelectInterior"\x15\n\x13TheftalarmSelectTow"C\n\x0fTheftalarmStart\x12\x30\n\x19\x61larm_duration_in_seconds\x18\x01 \x01(\x05R\ralarmduration"\x10\n\x0eTheftalarmStop"o\n\x1d\x41utomaticValetParkingActivate\x12\x1d\n\nbooking_id\x18\x01 \x01(\tR\tbookingId\x12/\n\ndrive_type\x18\x02 \x01(\x0e\x32\x10.proto.DriveTypeR\tdriveType"\x1f\n\x10\x43hargeFlapUnlock\x12\x0b\n\x03pin\x18\x01 \x01(\t"\x15\n\x13\x43hargeCouplerUnlock"\x82\x01\n ChargingBreakClocktimerConfigure\x12^\n(chargingbreak_clocktimer_configure_entry\x18\x01 \x03(\x0b\x32,.proto.ChargingBreakClockTimerConfigureEntry"\xcf\x01\n%ChargingBreakClockTimerConfigureEntry\x12\x39\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32).proto.ChargingBreakClockTimerEntryStatus\x12\x13\n\x0b\x65ndTimeHour\x18\x02 \x01(\x05\x12\x15\n\rendTimeMinute\x18\x03 \x01(\x05\x12\x15\n\rstartTimeHour\x18\x04 \x01(\x05\x12\x17\n\x0fstartTimeMinute\x18\x05 \x01(\x05\x12\x0f\n\x07timerId\x18\x06 \x01(\x05"\x12\n\x10WiperHealthReset"\'\n\x18SelectiveKeyDeactivation\x12\x0b\n\x03pin\x18\x01 \x01(\t"\x86\x01\n\x11SunroofBlindsMove\x12\x38\n\x13sunroof_blind_front\x18\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x37\n\x12sunroof_blind_rear\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32Value"\xb0\x01\n\x10WindowBlindsMove\x12/\n\nrear_blind\x18\x01 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x34\n\x0frear_left_blind\x18\x02 \x01(\x0b\x32\x1b.google.protobuf.Int32Value\x12\x35\n\x10rear_right_blind\x18\x03 \x01(\x0b\x32\x1b.google.protobuf.Int32Value"\'\n%ChildPresenceDetectionDeactivateAlarm"#\n!ChildPresenceDetectionTakePicture"\x1f\n\x1dInteriorMonitoringTakePicture"\x1f\n\x1d\x45xteriorMonitoringTakePicture";\n\x11RemoteUpdateStart\x12\x0e\n\x06pkg_id\x18\x01 \x01(\t\x12\x16\n\x0erelease_pkg_id\x18\x02 \x01(\t"\x1f\n\x1dTheftAlarmSelectPictureTaking"!\n\x1fTheftAlarmDeselectPictureTaking"\x10\n\x0eStagemodeStart"\x0f\n\rStagemodeStop"[\n\x13\x43lockTimerConfigure\x12\x44\n\x1b\x63lock_timer_configure_entry\x18\x01 \x03(\x0b\x32\x1f.proto.ClockTimerConfigureEntry"\x8c\x03\n\x18\x43lockTimerConfigureEntry\x12\x36\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32&.proto.ClockTimerConfigureEntry.Action\x12\x15\n\rend_time_hour\x18\x02 \x01(\x03\x12\x14\n\x0c\x65nd_time_min\x18\x03 \x01(\x03\x12\x17\n\x0fstart_time_hour\x18\x04 \x01(\x03\x12\x16\n\x0estart_time_min\x18\x05 \x01(\x03\x12\x10\n\x08timer_id\x18\x06 \x01(\x03\x12\x31\n\x04\x64\x61ys\x18\x07 \x03(\x0e\x32#.proto.ClockTimerConfigureEntry.Day"2\n\x06\x41\x63tion\x12\n\n\x06\x44\x45LETE\x10\x00\x12\x0e\n\nDEACTIVATE\x10\x01\x12\x0c\n\x08\x41\x43TIVATE\x10\x02"a\n\x03\x44\x61y\x12\n\n\x06MONDAY\x10\x00\x12\x0b\n\x07TUESDAY\x10\x01\x12\r\n\tWEDNESDAY\x10\x02\x12\x0c\n\x08THURSDAY\x10\x03\x12\n\n\x06\x46RIDAY\x10\x04\x12\x0c\n\x08SATURDAY\x10\x05\x12\n\n\x06SUNDAY\x10\x06*\xa5\x02\n\x04\x44oor\x12\x10\n\x0cunknown_door\x10\x00\x12\r\n\tfrontleft\x10\x01\x12\x0e\n\nfrontright\x10\x02\x12\x0c\n\x08rearleft\x10\x03\x12\r\n\trearright\x10\x04\x12\t\n\x05trunk\x10\x05\x12\x0c\n\x08\x66uelflap\x10\x06\x12\x0e\n\nchargeflap\x10\x07\x12\x11\n\rchargecoupler\x10\x08\x12\x10\n\x0cUNKNOWN_DOOR\x10\x00\x12\x0e\n\nFRONT_LEFT\x10\x01\x12\x0f\n\x0b\x46RONT_RIGHT\x10\x02\x12\r\n\tREAR_LEFT\x10\x03\x12\x0e\n\nREAR_RIGHT\x10\x04\x12\t\n\x05TRUNK\x10\x05\x12\r\n\tFUEL_FLAP\x10\x06\x12\x0f\n\x0b\x43HARGE_FLAP\x10\x07\x12\x12\n\x0e\x43HARGE_COUPLER\x10\x08\x1a\x02\x10\x01*\xf1\x01\n\x16ZEVPreconditioningType\x12,\n(unknown_zev_preconditioning_command_type\x10\x00\x12\r\n\timmediate\x10\x01\x12\r\n\tdeparture\x10\x02\x12\x07\n\x03now\x10\x03\x12\x13\n\x0f\x64\x65partureWeekly\x10\x04\x12,\n(UNKNOWN_ZEV_PRECONDITIONING_COMMAND_TYPE\x10\x00\x12\r\n\tIMMEDIATE\x10\x01\x12\r\n\tDEPARTURE\x10\x02\x12\x07\n\x03NOW\x10\x03\x12\x14\n\x10\x44\x45PARTURE_WEEKLY\x10\x04\x1a\x02\x10\x01*\xa8\x01\n\x0eTimeProfileDay\x12\x06\n\x02Mo\x10\x00\x12\x06\n\x02Tu\x10\x01\x12\x06\n\x02We\x10\x02\x12\x06\n\x02Th\x10\x03\x12\x06\n\x02\x46r\x10\x04\x12\x06\n\x02Sa\x10\x05\x12\x06\n\x02Su\x10\x06\x12\n\n\x06MONDAY\x10\x00\x12\x0b\n\x07TUESDAY\x10\x01\x12\r\n\tWEDNESDAY\x10\x02\x12\x0c\n\x08THURSDAY\x10\x03\x12\n\n\x06\x46RIDAY\x10\x04\x12\x0c\n\x08SATURDAY\x10\x05\x12\n\n\x06SUNDAY\x10\x06\x1a\x02\x10\x01*>\n\tDriveType\x12\x16\n\x12UNKNOWN_DRIVE_TYPE\x10\x00\x12\x0b\n\x07PICK_UP\x10\x01\x12\x0c\n\x08\x44ROP_OFF\x10\x02*J\n"ChargingBreakClockTimerEntryStatus\x12\n\n\x06\x44\x45LETE\x10\x00\x12\x0c\n\x08INACTIVE\x10\x01\x12\n\n\x06\x41\x43TIVE\x10\x02\x42 \n\x1a\x63om.daimler.mbcarkit.proto\xd0\xe1\x1e\x01\x62\x06proto3' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "vehicle_commands_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals["DESCRIPTOR"]._serialized_options = b"\n\032com.daimler.mbcarkit.proto\320\341\036\001" _globals["_DOOR"]._loaded_options = None _globals["_DOOR"]._serialized_options = b"\020\001" _globals["_ZEVPRECONDITIONINGTYPE"]._loaded_options = None _globals["_ZEVPRECONDITIONINGTYPE"]._serialized_options = b"\020\001" _globals["_TIMEPROFILEDAY"]._loaded_options = None _globals["_TIMEPROFILEDAY"]._serialized_options = b"\020\001" _globals["_TEMPERATURECONFIGURE_TEMPERATUREPOINT_ZONE"]._loaded_options = None _globals["_TEMPERATURECONFIGURE_TEMPERATUREPOINT_ZONE"]._serialized_options = b"\020\001" _globals["_DOOR"]._serialized_start = 12763 _globals["_DOOR"]._serialized_end = 13056 _globals["_ZEVPRECONDITIONINGTYPE"]._serialized_start = 13059 _globals["_ZEVPRECONDITIONINGTYPE"]._serialized_end = 13300 _globals["_TIMEPROFILEDAY"]._serialized_start = 13303 _globals["_TIMEPROFILEDAY"]._serialized_end = 13471 _globals["_DRIVETYPE"]._serialized_start = 13473 _globals["_DRIVETYPE"]._serialized_end = 13535 _globals["_CHARGINGBREAKCLOCKTIMERENTRYSTATUS"]._serialized_start = 13537 _globals["_CHARGINGBREAKCLOCKTIMERENTRYSTATUS"]._serialized_end = 13611 _globals["_ACKNOWLEDGECOMMANDREQUEST"]._serialized_start = 77 _globals["_ACKNOWLEDGECOMMANDREQUEST"]._serialized_end = 124 _globals["_COMMANDREQUEST"]._serialized_start = 127 _globals["_COMMANDREQUEST"]._serialized_end = 4169 _globals["_COMMANDREQUEST_BACKEND"]._serialized_start = 4124 _globals["_COMMANDREQUEST_BACKEND"]._serialized_end = 4158 _globals["_CHARGINGCONFIGURE"]._serialized_start = 4172 _globals["_CHARGINGCONFIGURE"]._serialized_end = 5128 _globals["_CHARGINGCONFIGURE_ACTION"]._serialized_start = 4719 _globals["_CHARGINGCONFIGURE_ACTION"]._serialized_end = 4795 _globals["_CHARGINGCONFIGURE_DCCHARGINGPROFILE"]._serialized_start = 4798 _globals["_CHARGINGCONFIGURE_DCCHARGINGPROFILE"]._serialized_end = 4944 _globals["_CHARGINGCONFIGURE_CHARGEPROGRAM"]._serialized_start = 4946 _globals["_CHARGINGCONFIGURE_CHARGEPROGRAM"]._serialized_end = 5039 _globals["_CHARGINGCONFIGURE_SOHCALIBRATIONACTIVATION"]._serialized_start = 5041 _globals["_CHARGINGCONFIGURE_SOHCALIBRATIONACTIVATION"]._serialized_end = 5128 _globals["_HVBATTERYSTARTCONDITIONING"]._serialized_start = 5130 _globals["_HVBATTERYSTARTCONDITIONING"]._serialized_end = 5158 _globals["_HVBATTERYSTOPCONDITIONING"]._serialized_start = 5160 _globals["_HVBATTERYSTOPCONDITIONING"]._serialized_end = 5187 _globals["_REMOTESEATBALLETTCONFIGURE"]._serialized_start = 5189 _globals["_REMOTESEATBALLETTCONFIGURE"]._serialized_end = 5217 _globals["_DEACTIVATEVEHICLEKEYS"]._serialized_start = 5220 _globals["_DEACTIVATEVEHICLEKEYS"]._serialized_end = 5385 _globals["_ACTIVATEVEHICLEKEYS"]._serialized_start = 5388 _globals["_ACTIVATEVEHICLEKEYS"]._serialized_end = 5551 _globals["_AUXHEATSTART"]._serialized_start = 5553 _globals["_AUXHEATSTART"]._serialized_end = 5567 _globals["_AUXHEATSTOP"]._serialized_start = 5569 _globals["_AUXHEATSTOP"]._serialized_end = 5582 _globals["_AUXHEATCONFIGURE"]._serialized_start = 5585 _globals["_AUXHEATCONFIGURE"]._serialized_end = 5841 _globals["_AUXHEATCONFIGURE_SELECTION"]._serialized_start = 5776 _globals["_AUXHEATCONFIGURE_SELECTION"]._serialized_end = 5841 _globals["_DOORSLOCK"]._serialized_start = 5843 _globals["_DOORSLOCK"]._serialized_end = 5882 _globals["_DOORSUNLOCK"]._serialized_start = 5884 _globals["_DOORSUNLOCK"]._serialized_end = 5938 _globals["_ENGINESTART"]._serialized_start = 5940 _globals["_ENGINESTART"]._serialized_end = 5966 _globals["_ENGINESTOP"]._serialized_start = 5968 _globals["_ENGINESTOP"]._serialized_end = 5980 _globals["_SUNROOFOPEN"]._serialized_start = 5982 _globals["_SUNROOFOPEN"]._serialized_end = 6008 _globals["_SUNROOFCLOSE"]._serialized_start = 6010 _globals["_SUNROOFCLOSE"]._serialized_end = 6024 _globals["_SUNROOFLIFT"]._serialized_start = 6026 _globals["_SUNROOFLIFT"]._serialized_end = 6052 _globals["_SUNROOFMOVE"]._serialized_start = 6055 _globals["_SUNROOFMOVE"]._serialized_end = 6288 _globals["_WINDOWSOPEN"]._serialized_start = 6290 _globals["_WINDOWSOPEN"]._serialized_end = 6316 _globals["_WINDOWSCLOSE"]._serialized_start = 6318 _globals["_WINDOWSCLOSE"]._serialized_end = 6332 _globals["_WINDOWSVENTILATE"]._serialized_start = 6334 _globals["_WINDOWSVENTILATE"]._serialized_end = 6365 _globals["_WINDOWSMOVE"]._serialized_start = 6368 _globals["_WINDOWSMOVE"]._serialized_end = 6876 _globals["_SPEEDALERTSTART"]._serialized_start = 6878 _globals["_SPEEDALERTSTART"]._serialized_end = 6978 _globals["_SPEEDALERTSTOP"]._serialized_start = 6980 _globals["_SPEEDALERTSTOP"]._serialized_end = 6996 _globals["_ZEVPRECONDITIONINGSTART"]._serialized_start = 6998 _globals["_ZEVPRECONDITIONINGSTART"]._serialized_end = 7113 _globals["_ZEVPRECONDITIONINGSTOP"]._serialized_start = 7115 _globals["_ZEVPRECONDITIONINGSTOP"]._serialized_end = 7190 _globals["_ZEVPRECONDITIONINGCONFIGURE"]._serialized_start = 7193 _globals["_ZEVPRECONDITIONINGCONFIGURE"]._serialized_end = 7442 _globals["_ZEVPRECONDITIONINGCONFIGURE_DEPARTURETIMEMODE"]._serialized_start = 7365 _globals["_ZEVPRECONDITIONINGCONFIGURE_DEPARTURETIMEMODE"]._serialized_end = 7442 _globals["_ZEVPRECONDITIONINGCONFIGURESEATS"]._serialized_start = 7445 _globals["_ZEVPRECONDITIONINGCONFIGURESEATS"]._serialized_end = 7647 _globals["_BATTERYCHARGEPROGRAMCONFIGURE"]._serialized_start = 7650 _globals["_BATTERYCHARGEPROGRAMCONFIGURE"]._serialized_end = 7815 _globals["_BATTERYCHARGEPROGRAMCONFIGURE_CHARGEPROGRAM"]._serialized_start = 7774 _globals["_BATTERYCHARGEPROGRAMCONFIGURE_CHARGEPROGRAM"]._serialized_end = 7815 _globals["_BATTERYMAXSOCCONFIGURE"]._serialized_start = 7817 _globals["_BATTERYMAXSOCCONFIGURE"]._serialized_end = 7866 _globals["_CHARGEPROGRAMCONFIGURE"]._serialized_start = 7869 _globals["_CHARGEPROGRAMCONFIGURE"]._serialized_end = 8395 _globals["_CHARGEPROGRAMCONFIGURE_CHARGEPROGRAM"]._serialized_start = 4946 _globals["_CHARGEPROGRAMCONFIGURE_CHARGEPROGRAM"]._serialized_end = 5039 _globals["_CHARGECONTROLCONFIGURE"]._serialized_start = 8398 _globals["_CHARGECONTROLCONFIGURE"]._serialized_end = 8622 _globals["_CHARGEOPTCONFIGURE"]._serialized_start = 8625 _globals["_CHARGEOPTCONFIGURE"]._serialized_end = 8957 _globals["_CHARGEOPTCONFIGURE_TARIFF"]._serialized_start = 8794 _globals["_CHARGEOPTCONFIGURE_TARIFF"]._serialized_end = 8957 _globals["_CHARGEOPTCONFIGURE_TARIFF_RATE"]._serialized_start = 8883 _globals["_CHARGEOPTCONFIGURE_TARIFF_RATE"]._serialized_end = 8957 _globals["_CHARGEOPTSTART"]._serialized_start = 8959 _globals["_CHARGEOPTSTART"]._serialized_end = 8975 _globals["_CHARGEOPTSTOP"]._serialized_start = 8977 _globals["_CHARGEOPTSTOP"]._serialized_end = 8992 _globals["_TEMPERATURECONFIGURE"]._serialized_start = 8995 _globals["_TEMPERATURECONFIGURE"]._serialized_end = 9584 _globals["_TEMPERATURECONFIGURE_TEMPERATUREPOINT"]._serialized_start = 9113 _globals["_TEMPERATURECONFIGURE_TEMPERATUREPOINT"]._serialized_end = 9584 _globals["_TEMPERATURECONFIGURE_TEMPERATUREPOINT_ZONE"]._serialized_start = 9243 _globals["_TEMPERATURECONFIGURE_TEMPERATUREPOINT_ZONE"]._serialized_end = 9578 _globals["_WEEKPROFILECONFIGURE"]._serialized_start = 9587 _globals["_WEEKPROFILECONFIGURE"]._serialized_end = 9884 _globals["_WEEKPROFILECONFIGURE_WEEKLYSETHU"]._serialized_start = 9689 _globals["_WEEKPROFILECONFIGURE_WEEKLYSETHU"]._serialized_end = 9884 _globals["_WEEKPROFILECONFIGURE_WEEKLYSETHU_DAY"]._serialized_start = 9787 _globals["_WEEKPROFILECONFIGURE_WEEKLYSETHU_DAY"]._serialized_end = 9884 _globals["_WEEKPROFILECONFIGUREV2"]._serialized_start = 9886 _globals["_WEEKPROFILECONFIGUREV2"]._serialized_end = 9967 _globals["_TIMEPROFILE"]._serialized_start = 9970 _globals["_TIMEPROFILE"]._serialized_end = 10276 _globals["_SIGPOSSTART"]._serialized_start = 10279 _globals["_SIGPOSSTART"]._serialized_end = 10770 _globals["_SIGPOSSTART_HORNTYPE"]._serialized_start = 10551 _globals["_SIGPOSSTART_HORNTYPE"]._serialized_end = 10618 _globals["_SIGPOSSTART_LIGHTTYPE"]._serialized_start = 10620 _globals["_SIGPOSSTART_LIGHTTYPE"]._serialized_end = 10688 _globals["_SIGPOSSTART_SIGPOSTYPE"]._serialized_start = 10690 _globals["_SIGPOSSTART_SIGPOSTYPE"]._serialized_end = 10770 _globals["_THEFTALARMCONFIRMDAMAGEDETECTION"]._serialized_start = 10772 _globals["_THEFTALARMCONFIRMDAMAGEDETECTION"]._serialized_end = 10806 _globals["_THEFTALARMDESELECTDAMAGEDETECTION"]._serialized_start = 10808 _globals["_THEFTALARMDESELECTDAMAGEDETECTION"]._serialized_end = 10843 _globals["_THEFTALARMDESELECTINTERIOR"]._serialized_start = 10845 _globals["_THEFTALARMDESELECTINTERIOR"]._serialized_end = 10873 _globals["_THEFTALARMDESELECTTOW"]._serialized_start = 10875 _globals["_THEFTALARMDESELECTTOW"]._serialized_end = 10898 _globals["_THEFTALARMSELECTDAMAGEDETECTION"]._serialized_start = 10900 _globals["_THEFTALARMSELECTDAMAGEDETECTION"]._serialized_end = 10933 _globals["_THEFTALARMSELECTINTERIOR"]._serialized_start = 10935 _globals["_THEFTALARMSELECTINTERIOR"]._serialized_end = 10961 _globals["_THEFTALARMSELECTTOW"]._serialized_start = 10963 _globals["_THEFTALARMSELECTTOW"]._serialized_end = 10984 _globals["_THEFTALARMSTART"]._serialized_start = 10986 _globals["_THEFTALARMSTART"]._serialized_end = 11053 _globals["_THEFTALARMSTOP"]._serialized_start = 11055 _globals["_THEFTALARMSTOP"]._serialized_end = 11071 _globals["_AUTOMATICVALETPARKINGACTIVATE"]._serialized_start = 11073 _globals["_AUTOMATICVALETPARKINGACTIVATE"]._serialized_end = 11184 _globals["_CHARGEFLAPUNLOCK"]._serialized_start = 11186 _globals["_CHARGEFLAPUNLOCK"]._serialized_end = 11217 _globals["_CHARGECOUPLERUNLOCK"]._serialized_start = 11219 _globals["_CHARGECOUPLERUNLOCK"]._serialized_end = 11240 _globals["_CHARGINGBREAKCLOCKTIMERCONFIGURE"]._serialized_start = 11243 _globals["_CHARGINGBREAKCLOCKTIMERCONFIGURE"]._serialized_end = 11373 _globals["_CHARGINGBREAKCLOCKTIMERCONFIGUREENTRY"]._serialized_start = 11376 _globals["_CHARGINGBREAKCLOCKTIMERCONFIGUREENTRY"]._serialized_end = 11583 _globals["_WIPERHEALTHRESET"]._serialized_start = 11585 _globals["_WIPERHEALTHRESET"]._serialized_end = 11603 _globals["_SELECTIVEKEYDEACTIVATION"]._serialized_start = 11605 _globals["_SELECTIVEKEYDEACTIVATION"]._serialized_end = 11644 _globals["_SUNROOFBLINDSMOVE"]._serialized_start = 11647 _globals["_SUNROOFBLINDSMOVE"]._serialized_end = 11781 _globals["_WINDOWBLINDSMOVE"]._serialized_start = 11784 _globals["_WINDOWBLINDSMOVE"]._serialized_end = 11960 _globals["_CHILDPRESENCEDETECTIONDEACTIVATEALARM"]._serialized_start = 11962 _globals["_CHILDPRESENCEDETECTIONDEACTIVATEALARM"]._serialized_end = 12001 _globals["_CHILDPRESENCEDETECTIONTAKEPICTURE"]._serialized_start = 12003 _globals["_CHILDPRESENCEDETECTIONTAKEPICTURE"]._serialized_end = 12038 _globals["_INTERIORMONITORINGTAKEPICTURE"]._serialized_start = 12040 _globals["_INTERIORMONITORINGTAKEPICTURE"]._serialized_end = 12071 _globals["_EXTERIORMONITORINGTAKEPICTURE"]._serialized_start = 12073 _globals["_EXTERIORMONITORINGTAKEPICTURE"]._serialized_end = 12104 _globals["_REMOTEUPDATESTART"]._serialized_start = 12106 _globals["_REMOTEUPDATESTART"]._serialized_end = 12165 _globals["_THEFTALARMSELECTPICTURETAKING"]._serialized_start = 12167 _globals["_THEFTALARMSELECTPICTURETAKING"]._serialized_end = 12198 _globals["_THEFTALARMDESELECTPICTURETAKING"]._serialized_start = 12200 _globals["_THEFTALARMDESELECTPICTURETAKING"]._serialized_end = 12233 _globals["_STAGEMODESTART"]._serialized_start = 12235 _globals["_STAGEMODESTART"]._serialized_end = 12251 _globals["_STAGEMODESTOP"]._serialized_start = 12253 _globals["_STAGEMODESTOP"]._serialized_end = 12268 _globals["_CLOCKTIMERCONFIGURE"]._serialized_start = 12270 _globals["_CLOCKTIMERCONFIGURE"]._serialized_end = 12361 _globals["_CLOCKTIMERCONFIGUREENTRY"]._serialized_start = 12364 _globals["_CLOCKTIMERCONFIGUREENTRY"]._serialized_end = 12760 _globals["_CLOCKTIMERCONFIGUREENTRY_ACTION"]._serialized_start = 12611 _globals["_CLOCKTIMERCONFIGUREENTRY_ACTION"]._serialized_end = 12661 _globals["_CLOCKTIMERCONFIGUREENTRY_DAY"]._serialized_start = 9787 _globals["_CLOCKTIMERCONFIGUREENTRY_DAY"]._serialized_end = 9884 # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/proto/vehicle_events_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: vehicle-events.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 import custom_components.mbapi2020.proto.protos_pb2 as protos__pb2 import custom_components.mbapi2020.proto.service_activation_pb2 as service__activation__pb2 import custom_components.mbapi2020.proto.user_events_pb2 as user__events__pb2 import custom_components.mbapi2020.proto.vehicle_commands_pb2 as vehicle__commands__pb2 import custom_components.mbapi2020.proto.vehicleapi_pb2 as vehicleapi__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\x14vehicle-events.proto\x12\x05proto\x1a\x18service-activation.proto\x1a\x11user-events.proto\x1a\x16vehicle-commands.proto\x1a\x0cprotos.proto\x1a\x10vehicleapi.proto\x1a\x1fgoogle/protobuf/timestamp.proto"\x84\x02\n\tVEPUpdate\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05\x12\x0b\n\x03vin\x18\x02 \x01(\t\x12\x13\n\x0b\x66ull_update\x18\x0f \x01(\x08\x12\x16\n\x0e\x65mit_timestamp\x18\n \x01(\x03\x12\x1c\n\x14\x65mit_timestamp_in_ms\x18\x0e \x01(\x03\x12\x34\n\nattributes\x18\x0b \x03(\x0b\x32 .proto.VEPUpdate.AttributesEntry\x1aP\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12,\n\x05value\x18\x02 \x01(\x0b\x32\x1d.proto.VehicleAttributeStatus:\x02\x38\x01"\xb8>\n\x16VehicleAttributeStatus\x12\x15\n\ttimestamp\x18\x01 \x01(\x03\x42\x02\x18\x01\x12\x17\n\x0ftimestamp_in_ms\x18\n \x01(\x03\x12\x0f\n\x07\x63hanged\x18\x02 \x01(\x08\x12\x0e\n\x06status\x18\x03 \x01(\x05\x12\x13\n\x0bservice_ids\x18\x1e \x03(\x05\x12\x15\n\rdisplay_value\x18\x0b \x01(\t\x12^\n\x1b\x63ombustion_consumption_unit\x18\x0c \x01(\x0e\x32\x37.proto.VehicleAttributeStatus.CombustionConsumptionUnitH\x00\x12P\n\x14gas_consumption_unit\x18\r \x01(\x0e\x32\x30.proto.VehicleAttributeStatus.GasConsumptionUnitH\x00\x12`\n\x1c\x65lectricity_consumption_unit\x18\x0e \x01(\x0e\x32\x38.proto.VehicleAttributeStatus.ElectricityConsumptionUnitH\x00\x12R\n\x13speed_distance_unit\x18\x0f \x01(\x0e\x32/.proto.VehicleAttributeStatus.SpeedDistanceUnitB\x02\x18\x01H\x00\x12=\n\nspeed_unit\x18\x19 \x01(\x0e\x32\'.proto.VehicleAttributeStatus.SpeedUnitH\x00\x12\x43\n\rdistance_unit\x18\x1a \x01(\x0e\x32*.proto.VehicleAttributeStatus.DistanceUnitH\x00\x12I\n\x10temperature_unit\x18\x10 \x01(\x0e\x32-.proto.VehicleAttributeStatus.TemperatureUnitH\x00\x12\x43\n\rpressure_unit\x18\x11 \x01(\x0e\x32*.proto.VehicleAttributeStatus.PressureUnitH\x00\x12=\n\nratio_unit\x18\x12 \x01(\x0e\x32\'.proto.VehicleAttributeStatus.RatioUnitH\x00\x12\x46\n\x0f\x63lock_hour_unit\x18\x13 \x01(\x0e\x32+.proto.VehicleAttributeStatus.ClockHourUnitH\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x01\x12\x14\n\nbool_value\x18\x05 \x01(\x08H\x01\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x01\x12\x16\n\x0c\x64ouble_value\x18\x07 \x01(\x01H\x01\x12\x13\n\tnil_value\x18\x08 \x01(\x08H\x01\x12\x1b\n\x11unsupported_value\x18\t \x01(\tH\x01\x12\x41\n\x18temperature_points_value\x18\x14 \x01(\x0b\x32\x1d.proto.TemperaturePointsValueH\x01\x12\x39\n\x14weekday_tariff_value\x18\x15 \x01(\x0b\x32\x19.proto.WeekdayTariffValueH\x01\x12\x39\n\x14weekend_tariff_value\x18\x16 \x01(\x0b\x32\x19.proto.WeekendTariffValueH\x01\x12I\n\x1dstate_of_charge_profile_value\x18\x17 \x01(\x0b\x32 .proto.StateOfChargeProfileValueH\x01\x12M\n\x1fweekly_settings_head_unit_value\x18\x18 \x01(\x0b\x32".proto.WeeklySettingsHeadUnitValueH\x01\x12N\n\x1fspeed_alert_configuration_value\x18\x1b \x01(\x0b\x32#.proto.SpeedAlertConfigurationValueH\x01\x12\x37\n\x13\x65\x63o_histogram_value\x18\x1c \x01(\x0b\x32\x18.proto.EcoHistogramValueH\x01\x12\x39\n\x14weekly_profile_value\x18\x1d \x01(\x0b\x32\x19.proto.WeeklyProfileValueH\x01\x12;\n\x15\x63harge_programs_value\x18\x1f \x01(\x0b\x32\x1a.proto.ChargeProgramsValueH\x01\x12M\n\x1e\x63hargingbreak_clocktimer_value\x18 \x01(\x0b\x32#.proto.ChargingBreakClockTimerValueH\x01\x12=\n\x16\x63harging_power_control\x18! \x01(\x0b\x32\x1b.proto.ChargingPowerControlH\x01\x12L\n\x1ekeyline_activation_state_value\x18$ \x01(\x0b\x32".proto.KeylineActivationStateValueH\x01\x12\x42\n\x19next_departure_time_value\x18% \x01(\x0b\x32\x1d.proto.NextDepartureTimeValueH\x01\x12l\n tcu_connection_state_low_channel\x18& \x01(\x0e\x32@.proto.VehicleAttributeStatus.TcuConnectionStateLowChannelStatusH\x01\x12\x45\n\x1bturn_off_engine_pre_warning\x18\' \x01(\x0e\x32\x1e.proto.TurnOffEnginePreWarningH\x01\x12\x64\n+child_presence_detection_warning_last_event\x18( \x01(\x0e\x32-.proto.ChildPresenceDetectionWarningLastEventH\x01\x12[\n&child_presence_detection_warning_level\x18) \x01(\x0e\x32).proto.ChildPresenceDetectionWarningLevelH\x01\x12T\n"performance_limitation_mode_status\x18* \x01(\x0e\x32&.proto.PerformanceLimitationModeStatusH\x01\x12.\n\x0e\x62\x61ttery_health\x18+ \x01(\x0e\x32\x14.proto.BatteryHealthH\x01\x12,\n\rprecond_state\x18, \x01(\x0b\x32\x13.proto.PrecondStateH\x01\x12\x45\n\x1a\x65xterior_monitoring_status\x18- \x01(\x0e\x32\x1f.proto.ExteriorMonitoringStatusH\x01\x12\x45\n\x1ainterior_monitoring_status\x18. \x01(\x0e\x32\x1f.proto.InteriorMonitoringStatusH\x01\x12\x44\n\x1aremote_update_start_status\x18/ \x01(\x0b\x32\x1e.proto.RemoteUpdateStartStatusH\x01\x12\x41\n\x18soh_calibration_required\x18\x30 \x01(\x0e\x32\x1d.proto.SohCalibrationRequiredH\x01\x12?\n\x17soc_calibration_request\x18\x31 \x01(\x0e\x32\x1c.proto.SocCalibrationRequestH\x01\x12?\n\x17soh_calibration_request\x18\x32 \x01(\x0e\x32\x1c.proto.SohCalibrationRequestH\x01\x12;\n\x15soh_calibration_state\x18\x33 \x01(\x0e\x32\x1a.proto.SohCalibrationStateH\x01\x12?\n\x17soh_calibration_planned\x18\x34 \x01(\x0e\x32\x1c.proto.SohCalibrationPlannedH\x01\x12\x41\n\x18soh_favorable_conditions\x18\x35 \x01(\x0e\x32\x1d.proto.SohFavorableConditionsH\x01\x12K\n\x1dsoh_calibration_notifications\x18\x36 \x01(\x0e\x32".proto.SohCalibrationNotificationsH\x01\x12G\n\x1b\x63harging_power_restrictions\x18\x37 \x01(\x0b\x32 .proto.ChargingPowerRestrictionsH\x01\x12\x63\n\x1e\x63harging_coupler_error_details\x18\x38 \x01(\x0e\x32\x39.proto.VehicleAttributeStatus.ChargingCouplerErrorDetailsH\x01\x12\x46\n\x1b\x63harging_stop_error_details\x18\x39 \x01(\x0e\x32\x1f.proto.ChargingStopErrorDetailsH\x01\x12q\n&charging_error_vehicle_no_support_400v\x18: \x01(\x0e\x32?.proto.VehicleAttributeStatus.ChargingErrorVehicleNoSupport400VH\x01\x12u\n(charging_error_impossible_change_to_400v\x18; \x01(\x0e\x32\x41.proto.VehicleAttributeStatus.ChargingErrorImpossibleChangeTo400VH\x01\x12u\n(charging_error_impossible_change_to_800v\x18< \x01(\x0e\x32\x41.proto.VehicleAttributeStatus.ChargingErrorImpossibleChangeTo800VH\x01\x12\x43\n\x19precond_operability_state\x18= \x01(\x0b\x32\x1e.proto.PrecondOperabilityStateH\x01\x12\x41\n\x18picture_recording_status\x18> \x01(\x0e\x32\x1d.proto.PictureRecordingStatusH\x01\x12U\n#park_event_picture_selection_status\x18? \x01(\x0e\x32&.proto.ParkEventPictureSelectionStatusH\x01\x12\x35\n\x12panic_alarm_active\x18@ \x01(\x0e\x32\x17.proto.PanicAlarmActiveH\x01\x12X\n$interior_protection_selection_status\x18\x41 \x01(\x0e\x32(.proto.InteriorProtectionSelectionStatusH\x01\x12Z\n%interior_protection_activation_status\x18\x42 \x01(\x0e\x32).proto.InteriorProtectionActivationStatusH\x01\x12N\n\x1ftow_protection_selection_status\x18\x43 \x01(\x0e\x32#.proto.TowProtectionSelectionStatusH\x01\x12P\n tow_protection_activation_status\x18\x44 \x01(\x0e\x32$.proto.TowProtectionActivationStatusH\x01\x12U\n#vehicle_theft_alarm_inactive_reason\x18\x45 \x01(\x0e\x32&.proto.VehicleTheftAlarmInactiveReasonH\x01\x12N\n\x1fpark_collision_selection_status\x18\x46 \x01(\x0e\x32#.proto.ParkCollisionSelectionStatusH\x01\x12P\n park_collision_activation_status\x18G \x01(\x0e\x32$.proto.ParkCollisionActivationStatusH\x01\x12L\n\x1epark_collision_inactive_reason\x18H \x01(\x0e\x32".proto.ParkCollisionInactiveReasonH\x01\x12[\n&park_collision_picture_transfer_status\x18I \x01(\x0e\x32).proto.ParkCollisionPictureTransferStatusH\x01\x12=\n\x16\x65mergency_power_supply\x18N \x01(\x0e\x32\x1b.proto.EmergencyPowerSupplyH\x01\x12\x35\n\x12\x65vse_pairing_state\x18O \x01(\x0e\x32\x17.proto.EvsePairingStateH\x01\x12?\n\x17\x63harging_prediction_soc\x18P \x01(\x0b\x32\x1c.proto.ChargingPredictionSocH\x01\x12T\n"charging_prediction_departure_time\x18Q \x01(\x0b\x32&.proto.ChargingPredictionDepartureTimeH\x01\x12\x41\n\x18\x63harging_schedule_active\x18R \x01(\x0b\x32\x1d.proto.ChargingScheduleActiveH\x01\x12\x37\n\x13\x64\x63_charging_profile\x18S \x01(\x0e\x32\x18.proto.DcChargingProfileH\x01\x12*\n\x0c\x63harge_flaps\x18T \x01(\x0b\x32\x12.proto.ChargeFlapsH\x01\x12,\n\rcharge_inlets\x18U \x01(\x0b\x32\x13.proto.ChargeInletsH\x01\x12.\n\x0e\x63harging_timer\x18V \x01(\x0b\x32\x14.proto.ChargingTimerH\x01\x12[\n&park_event_picture_transmission_status\x18W \x01(\x0e\x32).proto.ParkEventPictureTransmissionStatusH\x01\x12G\n\x1b\x63harging_schedule_requested\x18X \x01(\x0b\x32 .proto.ChargingScheduleRequestedH\x01\x12\x46\n\x1b\x63harging_flap_error_details\x18Y \x01(\x0e\x32\x1f.proto.ChargingFlapErrorDetailsH\x01\x12I\n\x1c\x63harging_compatibility_error\x18Z \x01(\x0e\x32!.proto.ChargingCompatibilityErrorH\x01\x12N\n\x1fhv_battery_precond_availability\x18[ \x01(\x0e\x32#.proto.HvBatteryPrecondAvailabilityH\x01\x12O\n hv_battery_precond_request_state\x18\\ \x01(\x0b\x32#.proto.HvBatteryPrecondRequestStateH\x01\x12@\n\x18hv_battery_precond_state\x18] \x01(\x0b\x32\x1c.proto.HvBatteryPrecondStateH\x01\x12\x38\n\x14\x61mg_stage_mode_state\x18^ \x01(\x0e\x32\x18.proto.AmgStageModeStateH\x01\x12\x38\n\x14\x61mg_stage_mode_error\x18_ \x01(\x0b\x32\x18.proto.AmgStageModeErrorH\x01"\x87\x01\n\x19\x43ombustionConsumptionUnit\x12+\n\'UNSPECIFIED_COMBUSTION_CONSUMPTION_UNIT\x10\x00\x12\x13\n\x0fLITER_PER_100KM\x10\x01\x12\x10\n\x0cKM_PER_LITER\x10\x02\x12\n\n\x06MPG_UK\x10\x03\x12\n\n\x06MPG_US\x10\x04"\x99\x01\n\x1a\x45lectricityConsumptionUnit\x12,\n(UNSPECIFIED_ELECTRICITY_CONSUMPTION_UNIT\x10\x00\x12\x11\n\rKWH_PER_100KM\x10\x01\x12\x0e\n\nKM_PER_KWH\x10\x02\x12\x11\n\rKWH_PER_100MI\x10\x03\x12\r\n\tM_PER_KWH\x10\x04\x12\x08\n\x04MPGE\x10\x05"i\n\x12GasConsumptionUnit\x12$\n UNSPECIFIED_GAS_CONSUMPTION_UNIT\x10\x00\x12\x10\n\x0cKG_PER_100KM\x10\x01\x12\r\n\tKM_PER_KG\x10\x02\x12\x0c\n\x08M_PER_KG\x10\x03"W\n\x11SpeedDistanceUnit\x12#\n\x1fUNSPECIFIED_SPEED_DISTANCE_UNIT\x10\x00\x12\x0c\n\x08KM_PER_H\x10\x01\x12\x0b\n\x07M_PER_H\x10\x02\x1a\x02\x18\x01"H\n\tSpeedUnit\x12\x1a\n\x16UNSPECIFIED_SPEED_UNIT\x10\x00\x12\x0f\n\x0bKM_PER_HOUR\x10\x01\x12\x0e\n\nM_PER_HOUR\x10\x02"H\n\x0c\x44istanceUnit\x12\x1d\n\x19UNSPECIFIED_DISTANCE_UNIT\x10\x00\x12\x0e\n\nKILOMETERS\x10\x01\x12\t\n\x05MILES\x10\x02"P\n\x0fTemperatureUnit\x12 \n\x1cUNSPECIFIED_TEMPERATURE_UNIT\x10\x00\x12\x0b\n\x07\x43\x45LSIUS\x10\x01\x12\x0e\n\nFAHRENHEIT\x10\x02"H\n\x0cPressureUnit\x12\x1d\n\x19UNSPECIFIED_PRESSURE_UNIT\x10\x00\x12\x07\n\x03KPA\x10\x01\x12\x07\n\x03\x42\x41R\x10\x02\x12\x07\n\x03PSI\x10\x03"4\n\tRatioUnit\x12\x1a\n\x16UNSPECIFIED_RATIO_UNIT\x10\x00\x12\x0b\n\x07PERCENT\x10\x01"D\n\rClockHourUnit\x12\x1f\n\x1bUNSPECIFIED_CLOCK_HOUR_UNIT\x10\x00\x12\x08\n\x04T12H\x10\x01\x12\x08\n\x04T24H\x10\x02"\x9e\x01\n"TcuConnectionStateLowChannelStatus\x12 \n\x1cUNKNOWN_TCU_CONNECTION_STATE\x10\x00\x12\x17\n\x13INITIALLY_CONNECTED\x10\x01\x12\x0f\n\x0bRECONNECTED\x10\x02\x12\x10\n\x0c\x44ISCONNECTED\x10\x03\x12\x1a\n\x16UNPLANNED_DISCONNECTED\x10\x04"\xef\x02\n\x1b\x43hargingCouplerErrorDetails\x12:\n6CHARING_COUPLER_ERROR_DETAILS_NO_INFO_OR_ERROR_MESSAGE\x10\x00\x12\x42\n>CHARING_COUPLER_ERROR_DETAILS_RELIEVE_CHARGE_COUPLER_AND_RETRY\x10\x01\x12N\nJCHARING_COUPLER_ERROR_DETAILS_CONTACT_SERVICE_HOTLINE_FOR_EMERGENCY_UNLOCK\x10\x02\x12\x42\n>CHARING_COUPLER_ERROR_DETAILS_UNPLUG_AND_REPLUG_CHARGE_COUPLER\x10\x03\x12<\n8CHARING_COUPLER_ERROR_DETAILS_CHARGE_COUPLER_LOCK_DEFECT\x10\x04"\xa7\x01\n#ChargingErrorImpossibleChangeTo400V\x12\x34\n0CHARGING_ERROR_IMPOSSIBLE_CHANGE_TO_400V_NO_INFO\x10\x00\x12J\nFCHARGING_ERROR_IMPOSSIBLE_CHANGE_TO_400V_400V_IMPOSSIBLE_STUCK_TO_800V\x10\x01"\xa7\x01\n#ChargingErrorImpossibleChangeTo800V\x12\x34\n0CHARGING_ERROR_IMPOSSIBLE_CHANGE_TO_800V_NO_INFO\x10\x00\x12J\nFCHARGING_ERROR_IMPOSSIBLE_CHANGE_TO_800V_800V_IMPOSSIBLE_STUCK_TO_400V\x10\x01"\x9e\x01\n!ChargingErrorVehicleNoSupport400V\x12\x32\n.CHARGING_ERROR_VEHICLE_NO_SUPPORT_400V_NO_INFO\x10\x00\x12\x45\nACHARGING_ERROR_VEHICLE_NO_SUPPORT_400V_400V_CHARGING_NOT_POSSIBLE\x10\x01\x42\x0e\n\x0c\x64isplay_unitB\x10\n\x0e\x61ttribute_type"\xa8\x01\n\x11\x41mgStageModeError\x12\x14\n\x0crear_spoiler\x18\x01 \x01(\x08\x12\x10\n\x08\x62ow_wave\x18\x02 \x01(\x08\x12\x10\n\x08\x64iffuser\x18\x03 \x01(\x08\x12\r\n\x05light\x18\x04 \x01(\x08\x12\x0e\n\x06mirror\x18\x05 \x01(\x08\x12\r\n\x05sound\x18\x06 \x01(\x08\x12\x1a\n\x12\x61ir_control_system\x18\x07 \x01(\x08\x12\x0f\n\x07venturi\x18\x08 \x01(\x08"e\n\x1bKeylineActivationStateValue\x12-\n\x05state\x18\x01 \x01(\x0e\x32\x1e.proto.KeylineActivationStates\x12\x17\n\x0f\x61\x63tive_keylines\x18\x02 \x03(\x03"6\n\x16NextDepartureTimeValue\x12\x0c\n\x04hour\x18\x01 \x01(\x03\x12\x0e\n\x06minute\x18\x02 \x01(\x03"\x8d\x01\n\x17RemoteUpdateStartStatus\x12\x1e\n\x16\x64uration_after_runtime\x18\x01 \x01(\x05\x12\x12\n\npackage_id\x18\x02 \x01(\t\x12*\n\rupdate_status\x18\x03 \x01(\x0e\x32\x13.proto.UpdateStatus\x12\x12\n\nrelease_id\x18\x04 \x01(\t"\xf0\x15\n\x16\x43hargingScheduleActive\x12"\n\x16schedule_id_deprecated\x18\x01 \x01(\x03\x42\x02\x18\x01\x12\x61\n\x16use_case_id_deprecated\x18\x02 \x01(\x0e\x32=.proto.ChargingScheduleActive.ChargingScheduleActiveUseCaseIdB\x02\x18\x01\x12.\n\nstart_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12U\n\x0coffline_mode\x18\x04 \x01(\x0e\x32?.proto.ChargingScheduleActive.ChargingScheduleActiveOfflineMode\x12N\n\x08schedule\x18\x05 \x03(\x0b\x32<.proto.ChargingScheduleActive.ChargingScheduleActiveSchedule\x12\x35\n\x0buse_case_id\x18\x06 \x01(\x0e\x32 .proto.ChargingScheduleUseCaseId\x12\x33\n\x12schedule_id_status\x18\x07 \x01(\x0e\x32\x17.proto.ScheduleIdStatus\x1aO\n\x1e\x43hargingScheduleActiveSchedule\x12\x14\n\x0cpower_values\x18\x01 \x01(\x01\x12\x17\n\x0f\x64uration_values\x18\x02 \x01(\x03"\x84\x10\n\x1f\x43hargingScheduleActiveUseCaseId\x12\x37\n3CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_SMART_CHARGING\x10\x00\x12\x46\nBCHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_MERCEDES_INTELLIGENT_CHARGING\x10\x01\x12@\n\n:CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_ECO_FRIENDLY_CHARGING\x10\r\x12=\n9CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_SUSTAINABLE_CHARGING\x10\x0e\x12=\n9CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_INTELLIGENT_CHARGING\x10\x0f\x12@\nCHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_BATTERY_FRIENDLY_CHARGING\x10\x14\x12J\nFCHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_EXTERNAL_NOISE_OPTIMIZED_CHARGING\x10\x15\x12J\nFCHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_VIDEO_WATCHING_OPTIMIZED_CHARGING\x10\x16\x12\x41\n=CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_TIME_CONTROLLED_CHARGING\x10\x17\x12>\n:CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_PEAK_SHAVING_CHARGING\x10\x18\x12G\nCCHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_DYNAMIC_LOAD_BALANCED_CHARGING\x10\x19\x12\x43\n?CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_BUSINESS_SPECIFIC_CHARGING\x10\x1a\x12\x41\n=CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_PREFERRED_CHARGING_TIMES\x10\x1b\x12.\n*CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_ENPAL\x10\x64\x12/\n+CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_TIBBER\x10\x65\x12;\n7CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_THE_MOBILITY_HOUSE\x10\x66\x12\x30\n,CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_AWATTAR\x10g\x12\x30\n,CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_TRONITY\x10h\x12-\n(CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_DPD\x10\xc8\x01\x12\x37\n2CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_DEUTSCHE_POST\x10\xc9\x01\x12\x33\n.CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_HACKATHON\x10\xfa\x01\x12\x36\n1CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_SANDBOX_MODE\x10\xfb\x01\x12\x38\n3CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_DEVELOPER_MODE\x10\xfc\x01\x12\x33\n.CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_TEST_MODE\x10\xfd\x01\x12\x34\n/CHARGING_SCHEDULE_ACTIVE_USE_CASE_ID_DEBUG_MODE\x10\xfe\x01\x1a\x02\x18\x01"\xb3\x01\n!ChargingScheduleActiveOfflineMode\x12\x31\n-CHARGING_SCHEDULE_ACTIVE_OFFLINE_MODE_UNKNOWN\x10\x00\x12-\n)CHARGING_SCHEDULE_ACTIVE_OFFLINE_MODE_OFF\x10\x01\x12,\n(CHARGING_SCHEDULE_ACTIVE_OFFLINE_MODE_ON\x10\x02"\x8f\x01\n\x15HvBatteryPrecondState\x12\x37\n\x08\x63harging\x18\x01 \x01(\x0e\x32%.proto.HvBatteryPrecondStatesCharging\x12=\n\x0b\x64ischarging\x18\x02 \x01(\x0e\x32(.proto.HvBatteryPrecondStatesDischarging"\xe6\x01\n\x1cHvBatteryPrecondRequestState\x12*\n\rmain_category\x18\x01 \x01(\x0e\x32\x13.proto.MainCategory\x12(\n\x0csub_category\x18\x02 \x01(\x0e\x32\x12.proto.SubCategory\x12\x32\n\x11specific_category\x18\x03 \x01(\x0e\x32\x17.proto.SpecificCategory\x12\x1d\n\x06method\x18\x04 \x01(\x0e\x32\r.proto.Method\x12\x1d\n\x06status\x18\x05 \x01(\x0e\x32\r.proto.Status"\xd1\x03\n\x17PrecondOperabilityState\x12\x19\n\x11precond_available\x18\x01 \x01(\x08\x12M\n\x13precond_error_state\x18\x02 \x01(\x0e\x32\x30.proto.PrecondOperabilityState.PrecondErrorState"\xcb\x02\n\x11PrecondErrorState\x12 \n\x1cPRECOND_ERROR_STATE_NO_ERROR\x10\x00\x12\'\n#PRECOND_ERROR_STATE_PLAY_PROTECTION\x10\x01\x12\x32\n.PRECOND_ERROR_STATE_NO_ENERGY_BUDGET_AVAILABLE\x10\x02\x12"\n\x1ePRECOND_ERROR_STATE_LOW_BUDGET\x10\x03\x12,\n(PRECOND_ERROR_STATE_SYSTEM_NOT_AVAILABLE\x10\x04\x12/\n+PRECOND_ERROR_STATE_PRECONDITIONING_ABORTED\x10\x05\x12\x34\n0PRECOND_ERROR_STATE_REGULAR_CLIMATIZATION_ACTIVE\x10\x06"\x9e\x10\n\x19\x43hargingScheduleRequested\x12M\n\x12schedule_id_status\x18\x01 \x01(\x0e\x32\x31.proto.ChargingScheduleRequested.ScheduleIdStatus\x12O\n\x0buse_case_id\x18\x02 \x01(\x0e\x32:.proto.ChargingScheduleRequested.ChargingScheduleUseCaseId"R\n\x10ScheduleIdStatus\x12\x1e\n\x1aSCHEDULE_ID_STATUS_DELETED\x10\x00\x12\x1e\n\x1aSCHEDULE_ID_STATUS_INITIAL\x10\x01"\x8c\x0e\n\x19\x43hargingScheduleUseCaseId\x12\x30\n,CHARGING_SCHEDULE_USE_CASE_ID_SMART_CHARGING\x10\x00\x12?\n;CHARGING_SCHEDULE_USE_CASE_ID_MERCEDES_INTELLIGENT_CHARGING\x10\x01\x12\x39\n5CHARGING_SCHEDULE_USE_CASE_ID_BETA_COMMUNITY_CHARGING\x10\x02\x12\x30\n,CHARGING_SCHEDULE_USE_CASE_ID_SOLAR_CHARGING\x10\x03\x12\x30\n,CHARGING_SCHEDULE_USE_CASE_ID_GREEN_CHARGING\x10\x04\x12\x34\n0CHARGING_SCHEDULE_USE_CASE_ID_EFFICIENT_CHARGING\x10\x05\x12\x37\n3CHARGING_SCHEDULE_USE_CASE_ID_ECO_FRIENDLY_CHARGING\x10\x06\x12\x36\n2CHARGING_SCHEDULE_USE_CASE_ID_SUSTAINABLE_CHARGING\x10\x07\x12\x36\n2CHARGING_SCHEDULE_USE_CASE_ID_INTELLIGENT_CHARGING\x10\x08\x12\x39\n5CHARGING_SCHEDULE_USE_CASE_ID_WORKPLACE_CHARGING_PLAN\x10\t\x12\x34\n0CHARGING_SCHEDULE_USE_CASE_ID_HOME_CHARGING_PLAN\x10\n\x12\x38\n4CHARGING_SCHEDULE_USE_CASE_ID_FLEET_MANAGED_CHARGING\x10\x0b\x12:\n6CHARGING_SCHEDULE_USE_CASE_ID_PRICE_OPTIMIZED_CHARGING\x10\x0c\x12;\n7CHARGING_SCHEDULE_USE_CASE_ID_BATTERY_FRIENDLY_CHARGING\x10\r\x12\x43\n?CHARGING_SCHEDULE_USE_CASE_ID_EXTERNAL_NOISE_OPTIMIZED_CHARGING\x10\x0e\x12\x43\n?CHARGING_SCHEDULE_USE_CASE_ID_VIDEO_WATCHING_OPTIMIZED_CHARGING\x10\x0f\x12:\n6CHARGING_SCHEDULE_USE_CASE_ID_TIME_CONTROLLED_CHARGING\x10\x10\x12\x37\n3CHARGING_SCHEDULE_USE_CASE_ID_PEAK_SHAVING_CHARGING\x10\x11\x12@\n\n\x04unit\x18\x03 \x01(\x0e\x32\x30.proto.VehicleAttributeStatus.GasConsumptionUnit\x12\x15\n\rdisplay_value\x18\x04 \x01(\t"\x98\x01\n\x13Int64RatioAttribute\x12\r\n\x05value\x18\x01 \x01(\x03\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata\x12\x35\n\x04unit\x18\x03 \x01(\x0e\x32\'.proto.VehicleAttributeStatus.RatioUnit\x12\x15\n\rdisplay_value\x18\x04 \x01(\t"\x99\x01\n\x14\x44oubleRatioAttribute\x12\r\n\x05value\x18\x01 \x01(\x01\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata\x12\x35\n\x04unit\x18\x03 \x01(\x0e\x32\'.proto.VehicleAttributeStatus.RatioUnit\x12\x15\n\rdisplay_value\x18\x04 \x01(\t"\xa5\x01\n\x1a\x44oubleTemperatureAttribute\x12\r\n\x05value\x18\x01 \x01(\x01\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata\x12;\n\x04unit\x18\x03 \x01(\x0e\x32-.proto.VehicleAttributeStatus.TemperatureUnit\x12\x15\n\rdisplay_value\x18\x04 \x01(\t"\xa0\x01\n\x17Int64ClockHourAttribute\x12\r\n\x05value\x18\x01 \x01(\x03\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata\x12\x39\n\x04unit\x18\x03 \x01(\x0e\x32+.proto.VehicleAttributeStatus.ClockHourUnit\x12\x15\n\rdisplay_value\x18\x04 \x01(\t"\xa4\x01\n\x1bTimestampClockHourAttribute\x12\r\n\x05value\x18\x01 \x01(\x03\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata\x12\x39\n\x04unit\x18\x03 \x01(\x0e\x32+.proto.VehicleAttributeStatus.ClockHourUnit\x12\x15\n\rdisplay_value\x18\x04 \x01(\t"o\n\x1e\x41mgStageModeStateEnumAttribute\x12\'\n\x05value\x18\x01 \x01(\x0e\x32\x18.proto.AmgStageModeState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"o\n\x1e\x41ssystOilQuantityEnumAttribute\x12\'\n\x05value\x18\x01 \x01(\x0e\x32\x18.proto.AssystOilQuantity\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"m\n\x1d\x41ssystOilWarningEnumAttribute\x12&\n\x05value\x18\x01 \x01(\x0e\x32\x17.proto.AssystOilWarning\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1a\x41uxheatstatusEnumAttribute\x12#\n\x05value\x18\x01 \x01(\x0e\x32\x14.proto.Auxheatstatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"u\n!AuxheattimeselectionEnumAttribute\x12*\n\x05value\x18\x01 \x01(\x0e\x32\x1b.proto.Auxheattimeselection\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1a\x42\x61tteryHealthEnumAttribute\x12#\n\x05value\x18\x01 \x01(\x0e\x32\x14.proto.BatteryHealth\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"q\n\x1f\x43\x61librationRequestEnumAttribute\x12(\n\x05value\x18\x01 \x01(\x0e\x32\x19.proto.CalibrationRequest\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"{\n$ChargeCouplerLockStatusEnumAttribute\x12-\n\x05value\x18\x01 \x01(\x0e\x32\x1e.proto.ChargeCouplerLockStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n ChargeCouplerStatusEnumAttribute\x12)\n\x05value\x18\x01 \x01(\x0e\x32\x1a.proto.ChargeCouplerStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"m\n\x1d\x43hargeFlapStatusEnumAttribute\x12&\n\x05value\x18\x01 \x01(\x0e\x32\x17.proto.ChargeFlapStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x81\x01\n\'ChargingCompatibilityErrorEnumAttribute\x12\x30\n\x05value\x18\x01 \x01(\x0e\x32!.proto.ChargingCompatibilityError\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x9a\x01\n(ChargingCouplerErrorDetailsEnumAttribute\x12H\n\x05value\x18\x01 \x01(\x0e\x32\x39.proto.VehicleAttributeStatus.ChargingCouplerErrorDetails\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"u\n!ChargingErrorDetailsEnumAttribute\x12*\n\x05value\x18\x01 \x01(\x0e\x32\x1b.proto.ChargingErrorDetails\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\xaa\x01\n0ChargingErrorImpossibleChangeTo400VEnumAttribute\x12P\n\x05value\x18\x01 \x01(\x0e\x32\x41.proto.VehicleAttributeStatus.ChargingErrorImpossibleChangeTo400V\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\xaa\x01\n0ChargingErrorImpossibleChangeTo800VEnumAttribute\x12P\n\x05value\x18\x01 \x01(\x0e\x32\x41.proto.VehicleAttributeStatus.ChargingErrorImpossibleChangeTo800V\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\xa6\x01\n.ChargingErrorVehicleNoSupport400VEnumAttribute\x12N\n\x05value\x18\x01 \x01(\x0e\x32?.proto.VehicleAttributeStatus.ChargingErrorVehicleNoSupport400V\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"}\n%ChargingFlapErrorDetailsEnumAttribute\x12.\n\x05value\x18\x01 \x01(\x0e\x32\x1f.proto.ChargingFlapErrorDetails\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"e\n\x19\x43hargingModeEnumAttribute\x12"\n\x05value\x18\x01 \x01(\x0e\x32\x13.proto.ChargingMode\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"i\n\x1b\x43hargingstatusEnumAttribute\x12$\n\x05value\x18\x01 \x01(\x0e\x32\x15.proto.Chargingstatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"}\n%ChargingStopErrorDetailsEnumAttribute\x12.\n\x05value\x18\x01 \x01(\x0e\x32\x1f.proto.ChargingStopErrorDetails\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x99\x01\n3ChildPresenceDetectionWarningLastEventEnumAttribute\x12<\n\x05value\x18\x01 \x01(\x0e\x32-.proto.ChildPresenceDetectionWarningLastEvent\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x91\x01\n/ChildPresenceDetectionWarningLevelEnumAttribute\x12\x38\n\x05value\x18\x01 \x01(\x0e\x32).proto.ChildPresenceDetectionWarningLevel\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"o\n\x1e\x44\x63\x43hargingProfileEnumAttribute\x12\'\n\x05value\x18\x01 \x01(\x0e\x32\x18.proto.DcChargingProfile\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"o\n\x1e\x44\x65partureTimeModeEnumAttribute\x12\'\n\x05value\x18\x01 \x01(\x0e\x32\x18.proto.DepartureTimeMode\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"i\n\x1b\x44oorlockstatusEnumAttribute\x12$\n\x05value\x18\x01 \x01(\x0e\x32\x15.proto.Doorlockstatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"w\n"DoorlockstatusvehicleEnumAttribute\x12+\n\x05value\x18\x01 \x01(\x0e\x32\x1c.proto.Doorlockstatusvehicle\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"a\n\x17\x44oorstatusEnumAttribute\x12 \n\x05value\x18\x01 \x01(\x0e\x32\x11.proto.Doorstatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"o\n\x1e\x44oorStatusOverallEnumAttribute\x12\'\n\x05value\x18\x01 \x01(\x0e\x32\x18.proto.DoorStatusOverall\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1a\x44oorstatusgasEnumAttribute\x12#\n\x05value\x18\x01 \x01(\x0e\x32\x14.proto.Doorstatusgas\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"c\n\x18\x44rivingModeEnumAttribute\x12!\n\x05value\x18\x01 \x01(\x0e\x32\x12.proto.DrivingMode\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"u\n!EmergencyPowerSupplyEnumAttribute\x12*\n\x05value\x18\x01 \x01(\x0e\x32\x1b.proto.EmergencyPowerSupply\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"m\n\x1d\x45ngineHoodStatusEnumAttribute\x12&\n\x05value\x18\x01 \x01(\x0e\x32\x17.proto.EngineHoodStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"c\n\x18\x45ngineStateEnumAttribute\x12!\n\x05value\x18\x01 \x01(\x0e\x32\x12.proto.EngineState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"m\n\x1d\x45vsePairingStateEnumAttribute\x12&\n\x05value\x18\x01 \x01(\x0e\x32\x17.proto.EvsePairingState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"}\n%ExteriorMonitoringStatusEnumAttribute\x12.\n\x05value\x18\x01 \x01(\x0e\x32\x1f.proto.ExteriorMonitoringStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"w\n"FilterParticleLoadingEnumAttribute\x12+\n\x05value\x18\x01 \x01(\x0e\x32\x1c.proto.FilterParticleLoading\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"m\n\x1d\x46lipWindowStatusEnumAttribute\x12&\n\x05value\x18\x01 \x01(\x0e\x32\x17.proto.FlipWindowStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x85\x01\n)HvBatteryPrecondAvailabilityEnumAttribute\x12\x32\n\x05value\x18\x01 \x01(\x0e\x32#.proto.HvBatteryPrecondAvailability\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x8d\x01\n-HvBatteryThermalPropagationEventEnumAttribute\x12\x36\n\x05value\x18\x01 \x01(\x0e\x32\'.proto.HvBatteryThermalPropagationEvent\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"i\n\x1bHybridWarningsEnumAttribute\x12$\n\x05value\x18\x01 \x01(\x0e\x32\x15.proto.HybridWarnings\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1aIgnitionstateEnumAttribute\x12#\n\x05value\x18\x01 \x01(\x0e\x32\x14.proto.Ignitionstate\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"}\n%InteriorMonitoringStatusEnumAttribute\x12.\n\x05value\x18\x01 \x01(\x0e\x32\x1f.proto.InteriorMonitoringStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x8f\x01\n.InteriorProtectionSelectionStatusEnumAttribute\x12\x37\n\x05value\x18\x01 \x01(\x0e\x32(.proto.InteriorProtectionSelectionStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"q\n\x1fKeyActivationStateEnumAttribute\x12(\n\x05value\x18\x01 \x01(\x0e\x32\x19.proto.KeyActivationState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"a\n\x17LanguageHUEnumAttribute\x12 \n\x05value\x18\x01 \x01(\x0e\x32\x11.proto.LanguageHU\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"y\n#LastTheftWarningReasonEnumAttribute\x12,\n\x05value\x18\x01 \x01(\x0e\x32\x1d.proto.LastTheftWarningReason\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1cOilWarningLevelEnumAttribute\x12%\n\x05value\x18\x01 \x01(\x0e\x32\x16.proto.OilWarningLevel\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1cParkbrakestatusEnumAttribute\x12%\n\x05value\x18\x01 \x01(\x0e\x32\x16.proto.Parkbrakestatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x87\x01\n*ParkCollisionActivationStatusEnumAttribute\x12\x33\n\x05value\x18\x01 \x01(\x0e\x32$.proto.ParkCollisionActivationStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x83\x01\n(ParkCollisionInactiveReasonEnumAttribute\x12\x31\n\x05value\x18\x01 \x01(\x0e\x32".proto.ParkCollisionInactiveReason\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x91\x01\n/ParkCollisionPictureTransferStatusEnumAttribute\x12\x38\n\x05value\x18\x01 \x01(\x0e\x32).proto.ParkCollisionPictureTransferStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x85\x01\n)ParkCollisionSelectionStatusEnumAttribute\x12\x32\n\x05value\x18\x01 \x01(\x0e\x32#.proto.ParkCollisionSelectionStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"i\n\x1bParkEventLevelEnumAttribute\x12$\n\x05value\x18\x01 \x01(\x0e\x32\x15.proto.ParkEventLevel\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x8b\x01\n,ParkEventPictureSelectionStatusEnumAttribute\x12\x35\n\x05value\x18\x01 \x01(\x0e\x32&.proto.ParkEventPictureSelectionStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x91\x01\n/ParkEventPictureTransmissionStatusEnumAttribute\x12\x38\n\x05value\x18\x01 \x01(\x0e\x32).proto.ParkEventPictureTransmissionStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"w\n"ParkEventSensorStatusEnumAttribute\x12+\n\x05value\x18\x01 \x01(\x0e\x32\x1c.proto.ParkEventSensorStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1aParkEventTypeEnumAttribute\x12#\n\x05value\x18\x01 \x01(\x0e\x32\x14.proto.ParkEventType\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x8b\x01\n,PerformanceLimitationModeStatusEnumAttribute\x12\x35\n\x05value\x18\x01 \x01(\x0e\x32&.proto.PerformanceLimitationModeStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"y\n#PictureRecordingStatusEnumAttribute\x12,\n\x05value\x18\x01 \x01(\x0e\x32\x1d.proto.PictureRecordingStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x89\x01\n+PictureTransferSelectionStatusEnumAttribute\x12\x34\n\x05value\x18\x01 \x01(\x0e\x32%.proto.PictureTransferSelectionStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"q\n\x1fPrecondatdepartureEnumAttribute\x12(\n\x05value\x18\x01 \x01(\x0e\x32\x19.proto.Precondatdeparture\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"e\n\x19PrecondErrorEnumAttribute\x12"\n\x05value\x18\x01 \x01(\x0e\x32\x13.proto.PrecondError\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"a\n\x17PrecondNowEnumAttribute\x12 \n\x05value\x18\x01 \x01(\x0e\x32\x11.proto.PrecondNow\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"u\n!PrecondOperatingModeEnumAttribute\x12*\n\x05value\x18\x01 \x01(\x0e\x32\x1b.proto.PrecondOperatingMode\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"c\n\x18PrecondSeatEnumAttribute\x12!\n\x05value\x18\x01 \x01(\x0e\x32\x12.proto.PrecondSeat\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x81\x01\n\'ProtectionActivationStatusEnumAttribute\x12\x30\n\x05value\x18\x01 \x01(\x0e\x32!.proto.ProtectionActivationStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"y\n#ProtectionSensorStatusEnumAttribute\x12,\n\x05value\x18\x01 \x01(\x0e\x32\x1d.proto.ProtectionSensorStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n RangeSkipIndicationEnumAttribute\x12)\n\x05value\x18\x01 \x01(\x0e\x32\x1a.proto.RangeSkipIndication\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1aRooftopstatusEnumAttribute\x12#\n\x05value\x18\x01 \x01(\x0e\x32\x14.proto.Rooftopstatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"w\n"SelectedChargeProgramEnumAttribute\x12+\n\x05value\x18\x01 \x01(\x0e\x32\x1c.proto.SelectedChargeProgram\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1aSmartChargingEnumAttribute\x12#\n\x05value\x18\x01 \x01(\x0e\x32\x14.proto.SmartCharging\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"}\n%SmartChargingAtDepartureEnumAttribute\x12.\n\x05value\x18\x01 \x01(\x0e\x32\x1f.proto.SmartChargingAtDeparture\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x83\x01\n(SohCalibrationNotificationsEnumAttribute\x12\x31\n\x05value\x18\x01 \x01(\x0e\x32".proto.SohCalibrationNotifications\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"w\n"SohCalibrationPlannedEnumAttribute\x12+\n\x05value\x18\x01 \x01(\x0e\x32\x1c.proto.SohCalibrationPlanned\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"y\n#SohCalibrationRequiredEnumAttribute\x12,\n\x05value\x18\x01 \x01(\x0e\x32\x1d.proto.SohCalibrationRequired\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n SohCalibrationStateEnumAttribute\x12)\n\x05value\x18\x01 \x01(\x0e\x32\x1a.proto.SohCalibrationState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"y\n#SohFavorableConditionsEnumAttribute\x12,\n\x05value\x18\x01 \x01(\x0e\x32\x1d.proto.SohFavorableConditions\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1cSpeedUnitFromICEnumAttribute\x12%\n\x05value\x18\x01 \x01(\x0e\x32\x16.proto.SpeedUnitFromIC\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n StarterBatteryStateEnumAttribute\x12)\n\x05value\x18\x01 \x01(\x0e\x32\x1a.proto.StarterBatteryState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"e\n\x19SunroofEventEnumAttribute\x12"\n\x05value\x18\x01 \x01(\x0e\x32\x13.proto.SunroofEvent\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1aSunroofstatusEnumAttribute\x12#\n\x05value\x18\x01 \x01(\x0e\x32\x14.proto.Sunroofstatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"q\n\x1fSunroofStatusBlindEnumAttribute\x12(\n\x05value\x18\x01 \x01(\x0e\x32\x19.proto.SunroofStatusBlind\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x85\x01\n)TcuConnectionStateLowChannelEnumAttribute\x12\x32\n\x05value\x18\x01 \x01(\x0e\x32#.proto.TcuConnectionStateLowChannel\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"o\n\x1eTcuThermoShutDownEnumAttribute\x12\'\n\x05value\x18\x01 \x01(\x0e\x32\x18.proto.TcuThermoShutDown\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"o\n\x1eTemperatureUnitHUEnumAttribute\x12\'\n\x05value\x18\x01 \x01(\x0e\x32\x18.proto.TemperatureUnitHU\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"e\n\x19TimeFormatHUEnumAttribute\x12"\n\x05value\x18\x01 \x01(\x0e\x32\x13.proto.TimeFormatHU\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"a\n\x17TireMarkerEnumAttribute\x12 \n\x05value\x18\x01 \x01(\x0e\x32\x11.proto.TireMarker\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n TireSensorAvailableEnumAttribute\x12)\n\x05value\x18\x01 \x01(\x0e\x32\x1a.proto.TireSensorAvailable\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n TireWarningLevelPrwEnumAttribute\x12)\n\x05value\x18\x01 \x01(\x0e\x32\x1a.proto.TireWarningLevelPrw\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1cTirewarninglampEnumAttribute\x12%\n\x05value\x18\x01 \x01(\x0e\x32\x16.proto.Tirewarninglamp\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1cTirewarningsprwEnumAttribute\x12%\n\x05value\x18\x01 \x01(\x0e\x32\x16.proto.Tirewarningsprw\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1cTirewarningsrdkEnumAttribute\x12%\n\x05value\x18\x01 \x01(\x0e\x32\x16.proto.Tirewarningsrdk\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x85\x01\n)TowProtectionSelectionStatusEnumAttribute\x12\x32\n\x05value\x18\x01 \x01(\x0e\x32#.proto.TowProtectionSelectionStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1cTrackingStateHuEnumAttribute\x12%\n\x05value\x18\x01 \x01(\x0e\x32\x16.proto.TrackingStateHu\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"{\n$TurnOffEnginePreWarningEnumAttribute\x12-\n\x05value\x18\x01 \x01(\x0e\x32\x1e.proto.TurnOffEnginePreWarning\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x81\x01\n\'VehicleDataConnectionStateEnumAttribute\x12\x30\n\x05value\x18\x01 \x01(\x0e\x32!.proto.VehicleDataConnectionState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n VehicleHealthStatusEnumAttribute\x12)\n\x05value\x18\x01 \x01(\x0e\x32\x1a.proto.VehicleHealthStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"}\n%VehiclePositionErrorCodeEnumAttribute\x12.\n\x05value\x18\x01 \x01(\x0e\x32\x1f.proto.VehiclePositionErrorCode\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x8b\x01\n,VehicleTheftAlarmInactiveReasonEnumAttribute\x12\x35\n\x05value\x18\x01 \x01(\x0e\x32&.proto.VehicleTheftAlarmInactiveReason\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"m\n\x1dWarningwashwaterEnumAttribute\x12&\n\x05value\x18\x01 \x01(\x0e\x32\x17.proto.Warningwashwater\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"[\n\x14WeekdayEnumAttribute\x12\x1d\n\x05value\x18\x01 \x01(\x0e\x32\x0e.proto.Weekday\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"e\n\x19WindowstatusEnumAttribute\x12"\n\x05value\x18\x01 \x01(\x0e\x32\x13.proto.Windowstatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"o\n\x1eWindowStatusBlindEnumAttribute\x12\'\n\x05value\x18\x01 \x01(\x0e\x32\x18.proto.WindowStatusBlind\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n WindowStatusOverallEnumAttribute\x12)\n\x05value\x18\x01 \x01(\x0e\x32\x1a.proto.WindowStatusOverall\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"q\n AmgStageModeErrorObjectAttribute\x12\'\n\x05value\x18\x01 \x01(\x0b\x32\x18.proto.AmgStageModeError\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x82\x01\n&ChargingBreakClockTimerObjectAttribute\x12\x32\n\x05value\x18\x01 \x01(\x0b\x32#.proto.ChargingBreakClockTimerValue\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x8d\x01\n.ChargingPredictionDepartureTimeObjectAttribute\x12\x35\n\x05value\x18\x01 \x01(\x0b\x32&.proto.ChargingPredictionDepartureTime\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"y\n$ChargingPredictionSocObjectAttribute\x12+\n\x05value\x18\x01 \x01(\x0b\x32\x1c.proto.ChargingPredictionSoc\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"{\n%ChargingScheduleActiveObjectAttribute\x12,\n\x05value\x18\x01 \x01(\x0b\x32\x1d.proto.ChargingScheduleActive\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x81\x01\n(ChargingScheduleRequestedObjectAttribute\x12/\n\x05value\x18\x01 \x01(\x0b\x32 .proto.ChargingScheduleRequested\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x87\x01\n+HvBatteryPrecondRequestStateObjectAttribute\x12\x32\n\x05value\x18\x01 \x01(\x0b\x32#.proto.HvBatteryPrecondRequestState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"y\n$HvBatteryPrecondStateObjectAttribute\x12+\n\x05value\x18\x01 \x01(\x0b\x32\x1c.proto.HvBatteryPrecondState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\x80\x01\n%KeylineActivationStateObjectAttribute\x12\x31\n\x05value\x18\x01 \x01(\x0b\x32".proto.KeylineActivationStateValue\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\xc8\x01\n NextDepartureTimeObjectAttribute\x12,\n\x05value\x18\x01 \x01(\x0b\x32\x1d.proto.NextDepartureTimeValue\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata\x12\x39\n\x04unit\x18\x03 \x01(\x0e\x32+.proto.VehicleAttributeStatus.ClockHourUnit\x12\x15\n\rdisplay_value\x18\x04 \x01(\t"}\n&PrecondOperabilityStateObjectAttribute\x12-\n\x05value\x18\x01 \x01(\x0b\x32\x1e.proto.PrecondOperabilityState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"g\n\x1bPrecondStateObjectAttribute\x12"\n\x05value\x18\x01 \x01(\x0b\x32\x13.proto.PrecondState\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"}\n&RemoteUpdateStartStatusObjectAttribute\x12-\n\x05value\x18\x01 \x01(\x0b\x32\x1e.proto.RemoteUpdateStartStatus\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"n\n\x1cWeeklyProfileObjectAttribute\x12(\n\x05value\x18\x01 \x01(\x0b\x32\x19.proto.WeeklyProfileValue\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1d\x41uxheatwarningsArrayAttribute\x12$\n\x05value\x18\x01 \x03(\x0e\x32\x15.proto.Auxheatwarning\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"i\n\x19\x43hargeFlapsArrayAttribute\x12&\n\x05value\x18\x01 \x03(\x0b\x32\x17.proto.ChargeFlapsEntry\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"k\n\x1a\x43hargeInletsArrayAttribute\x12\'\n\x05value\x18\x01 \x03(\x0b\x32\x18.proto.ChargeInletsEntry\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n\x1c\x43hargeProgramsArrayAttribute\x12-\n\x05value\x18\x01 \x03(\x0b\x32\x1e.proto.ChargeProgramParameters\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"~\n&ChargingPowerRestrictionArrayAttribute\x12.\n\x05value\x18\x01 \x03(\x0e\x32\x1f.proto.ChargingPowerRestriction\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"m\n\x1b\x43hargingTimerArrayAttribute\x12(\n\x05value\x18\x01 \x03(\x0b\x32\x19.proto.ChargingTimerEntry\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"e\n\x18SocprofileArrayAttribute\x12#\n\x05value\x18\x01 \x03(\x0b\x32\x14.proto.StateOfCharge\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"s\n\x1cSpeedAlertConfArrayAttribute\x12-\n\x05value\x18\x01 \x03(\x0b\x32\x1e.proto.SpeedAlertConfiguration\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"o\n\x1fTemperaturePointsArrayAttribute\x12&\n\x05value\x18\x01 \x03(\x0b\x32\x17.proto.TemperaturePoint\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"f\n\x19WeeklySetHUArrayAttribute\x12#\n\x05value\x18\x01 \x03(\x0b\x32\x14.proto.WeeklySetting\x12$\n\x08metadata\x18\x02 \x01(\x0b\x32\x12.proto.VSUMetadata"\xf5\x8f\x01\n\x13VehicleStatusUpdate\x12\x12\n\nfin_or_vin\x18\x01 \x01(\t\x12\x13\n\x0b\x66ull_update\x18\x02 \x01(\x08\x12\x45\n\x14\x61mg_stage_mode_error\x18\x03 \x01(\x0b\x32\'.proto.AmgStageModeErrorObjectAttribute\x12\x43\n\x14\x61mg_stage_mode_state\x18\x04 \x01(\x0b\x32%.proto.AmgStageModeStateEnumAttribute\x12\x42\n\x13\x61ssyst_oil_quantity\x18\x05 \x01(\x0b\x32%.proto.AssystOilQuantityEnumAttribute\x12@\n\x12\x61ssyst_oil_warning\x18\x06 \x01(\x0b\x32$.proto.AssystOilWarningEnumAttribute\x12,\n\x0e\x61uxheat_active\x18\x07 \x01(\x0b\x32\x14.proto.BoolAttribute\x12-\n\x0e\x61uxheatruntime\x18\x08 \x01(\x0b\x32\x15.proto.Int64Attribute\x12\x38\n\rauxheatstatus\x18\t \x01(\x0b\x32!.proto.AuxheatstatusEnumAttribute\x12\x34\n\x0c\x61uxheattime1\x18\n \x01(\x0b\x32\x1e.proto.Int64ClockHourAttribute\x12\x34\n\x0c\x61uxheattime2\x18\x0b \x01(\x0b\x32\x1e.proto.Int64ClockHourAttribute\x12\x34\n\x0c\x61uxheattime3\x18\x0c \x01(\x0b\x32\x1e.proto.Int64ClockHourAttribute\x12\x46\n\x14\x61uxheattimeselection\x18\r \x01(\x0b\x32(.proto.AuxheattimeselectionEnumAttribute\x12=\n\x0f\x61uxheatwarnings\x18\x0e \x01(\x0b\x32$.proto.AuxheatwarningsArrayAttribute\x12\x38\n\x13\x61verage_speed_reset\x18\x0f \x01(\x0b\x32\x1b.proto.DoubleSpeedAttribute\x12\x38\n\x13\x61verage_speed_start\x18\x10 \x01(\x0b\x32\x1b.proto.DoubleSpeedAttribute\x12\x39\n\x0e\x62\x61ttery_health\x18\x11 \x01(\x0b\x32!.proto.BatteryHealthEnumAttribute\x12;\n\x1d\x62idirectional_charging_active\x18\x12 \x01(\x0b\x32\x14.proto.BoolAttribute\x12S\n\x1e\x63harge_coupler_a_c_lock_status\x18\x13 \x01(\x0b\x32+.proto.ChargeCouplerLockStatusEnumAttribute\x12J\n\x19\x63harge_coupler_a_c_status\x18\x14 \x01(\x0b\x32\'.proto.ChargeCouplerStatusEnumAttribute\x12S\n\x1e\x63harge_coupler_d_c_lock_status\x18\x15 \x01(\x0b\x32+.proto.ChargeCouplerLockStatusEnumAttribute\x12J\n\x19\x63harge_coupler_d_c_status\x18\x16 \x01(\x0b\x32\'.proto.ChargeCouplerStatusEnumAttribute\x12\x44\n\x16\x63harge_flap_a_c_status\x18\x17 \x01(\x0b\x32$.proto.ChargeFlapStatusEnumAttribute\x12\x44\n\x16\x63harge_flap_d_c_status\x18\x18 \x01(\x0b\x32$.proto.ChargeFlapStatusEnumAttribute\x12\x36\n\x0c\x63harge_flaps\x18\x19 \x01(\x0b\x32 .proto.ChargeFlapsArrayAttribute\x12\x38\n\rcharge_inlets\x18\x1a \x01(\x0b\x32!.proto.ChargeInletsArrayAttribute\x12<\n\x0f\x63harge_programs\x18\x1b \x01(\x0b\x32#.proto.ChargeProgramsArrayAttribute\x12Q\n\x1a\x63harging_break_clock_timer\x18\x1c \x01(\x0b\x32-.proto.ChargingBreakClockTimerObjectAttribute\x12T\n\x1c\x63harging_compatibility_error\x18\x1d \x01(\x0b\x32..proto.ChargingCompatibilityErrorEnumAttribute\x12W\n\x1e\x63harging_coupler_error_details\x18\x1e \x01(\x0b\x32/.proto.ChargingCouplerErrorDetailsEnumAttribute\x12H\n\x16\x63harging_error_details\x18\x1f \x01(\x0b\x32(.proto.ChargingErrorDetailsEnumAttribute\x12i\n(charging_error_impossible_change_to400_v\x18 \x01(\x0b\x32\x37.proto.ChargingErrorImpossibleChangeTo400VEnumAttribute\x12i\n(charging_error_impossible_change_to800_v\x18! \x01(\x0b\x32\x37.proto.ChargingErrorImpossibleChangeTo800VEnumAttribute\x12\x65\n&charging_error_vehicle_no_support400_v\x18" \x01(\x0b\x32\x35.proto.ChargingErrorVehicleNoSupport400VEnumAttribute\x12Q\n\x1b\x63harging_flap_error_details\x18# \x01(\x0b\x32,.proto.ChargingFlapErrorDetailsEnumAttribute\x12\x37\n\rcharging_mode\x18$ \x01(\x0b\x32 .proto.ChargingModeEnumAttribute\x12.\n\x0e\x63harging_power\x18% \x01(\x0b\x32\x16.proto.DoubleAttribute\x12\x37\n\x18\x63harging_power_eco_limit\x18& \x01(\x0b\x32\x15.proto.Int64Attribute\x12Q\n\x1a\x63harging_power_restriction\x18\' \x01(\x0b\x32-.proto.ChargingPowerRestrictionArrayAttribute\x12\x61\n"charging_prediction_departure_time\x18( \x01(\x0b\x32\x35.proto.ChargingPredictionDepartureTimeObjectAttribute\x12Q\n\x1c\x63harging_prediction_full_soc\x18) \x01(\x0b\x32+.proto.ChargingPredictionSocObjectAttribute\x12P\n\x1b\x63harging_prediction_max_soc\x18* \x01(\x0b\x32+.proto.ChargingPredictionSocObjectAttribute\x12P\n\x1b\x63harging_prediction_min_soc\x18+ \x01(\x0b\x32+.proto.ChargingPredictionSocObjectAttribute\x12S\n\x1e\x63harging_prediction_target_soc\x18, \x01(\x0b\x32+.proto.ChargingPredictionSocObjectAttribute\x12N\n\x18\x63harging_schedule_active\x18- \x01(\x0b\x32,.proto.ChargingScheduleActiveObjectAttribute\x12T\n\x1b\x63harging_schedule_requested\x18. \x01(\x0b\x32/.proto.ChargingScheduleRequestedObjectAttribute\x12Q\n\x1b\x63harging_stop_error_details\x18/ \x01(\x0b\x32,.proto.ChargingStopErrorDetailsEnumAttribute\x12:\n\x0e\x63harging_timer\x18\x30 \x01(\x0b\x32".proto.ChargingTimerArrayAttribute\x12,\n\x0e\x63hargingactive\x18\x31 \x01(\x0b\x32\x14.proto.BoolAttribute\x12:\n\x0e\x63hargingstatus\x18\x32 \x01(\x0b\x32".proto.ChargingstatusEnumAttribute\x12G\n(child_presence_detection_warning_counter\x18\x33 \x01(\x0b\x32\x15.proto.Int64Attribute\x12o\n+child_presence_detection_warning_last_event\x18\x34 \x01(\x0b\x32:.proto.ChildPresenceDetectionWarningLastEventEnumAttribute\x12\x66\n&child_presence_detection_warning_level\x18\x35 \x01(\x0b\x32\x36.proto.ChildPresenceDetectionWarningLevelEnumAttribute\x12\x42\n\x13\x64\x63_charging_profile\x18\x36 \x01(\x0b\x32%.proto.DcChargingProfileEnumAttribute\x12\x35\n\rdecklidstatus\x18\x37 \x01(\x0b\x32\x1e.proto.DoorstatusEnumAttribute\x12\x42\n\x13\x64\x65parture_time_mode\x18\x38 \x01(\x0b\x32%.proto.DepartureTimeModeEnumAttribute\x12;\n\x16\x64\x65parture_time_weekday\x18\x39 \x01(\x0b\x32\x1b.proto.WeekdayEnumAttribute\x12\x35\n\rdeparturetime\x18: \x01(\x0b\x32\x1e.proto.Int64ClockHourAttribute\x12\x34\n\x10\x64\x65parturetimesoc\x18; \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x41\n\x19\x64istance_electrical_reset\x18< \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12\x41\n\x19\x64istance_electrical_start\x18= \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12:\n\x12\x64istance_gas_reset\x18> \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12:\n\x12\x64istance_gas_start\x18? \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12\x36\n\x0e\x64istance_reset\x18@ \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12\x36\n\x0e\x64istance_start\x18\x41 \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12:\n\x12\x64istance_z_e_reset\x18\x42 \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12:\n\x12\x64istance_z_e_start\x18\x43 \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12\x41\n\x15\x64oorlockstatusdecklid\x18\x44 \x01(\x0b\x32".proto.DoorlockstatusEnumAttribute\x12\x43\n\x17\x64oorlockstatusfrontleft\x18\x45 \x01(\x0b\x32".proto.DoorlockstatusEnumAttribute\x12\x44\n\x18\x64oorlockstatusfrontright\x18\x46 \x01(\x0b\x32".proto.DoorlockstatusEnumAttribute\x12=\n\x11\x64oorlockstatusgas\x18G \x01(\x0b\x32".proto.DoorlockstatusEnumAttribute\x12\x42\n\x16\x64oorlockstatusrearleft\x18H \x01(\x0b\x32".proto.DoorlockstatusEnumAttribute\x12\x43\n\x17\x64oorlockstatusrearright\x18I \x01(\x0b\x32".proto.DoorlockstatusEnumAttribute\x12H\n\x15\x64oorlockstatusvehicle\x18J \x01(\x0b\x32).proto.DoorlockstatusvehicleEnumAttribute\x12;\n\x13\x64oorstatusfrontleft\x18K \x01(\x0b\x32\x1e.proto.DoorstatusEnumAttribute\x12<\n\x14\x64oorstatusfrontright\x18L \x01(\x0b\x32\x1e.proto.DoorstatusEnumAttribute\x12\x38\n\rdoorstatusgas\x18M \x01(\x0b\x32!.proto.DoorstatusgasEnumAttribute\x12:\n\x12\x64oorstatusrearleft\x18N \x01(\x0b\x32\x1e.proto.DoorstatusEnumAttribute\x12;\n\x13\x64oorstatusrearright\x18O \x01(\x0b\x32\x1e.proto.DoorstatusEnumAttribute\x12\x30\n\x11\x64riven_time_reset\x18P \x01(\x0b\x32\x15.proto.Int64Attribute\x12\x30\n\x11\x64riven_time_start\x18Q \x01(\x0b\x32\x15.proto.Int64Attribute\x12\x34\n\x15\x64riven_time_z_e_reset\x18R \x01(\x0b\x32\x15.proto.Int64Attribute\x12\x34\n\x15\x64riven_time_z_e_start\x18S \x01(\x0b\x32\x15.proto.Int64Attribute\x12\x31\n\recoscoreaccel\x18T \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12:\n\x12\x65\x63oscorebonusrange\x18U \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12\x31\n\recoscoreconst\x18V \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x33\n\x0f\x65\x63oscorefreewhl\x18W \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x31\n\recoscoretotal\x18X \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x39\n\x14\x65lectric_ratio_reset\x18Y \x01(\x0b\x32\x1b.proto.DoubleRatioAttribute\x12\x39\n\x14\x65lectric_ratio_start\x18Z \x01(\x0b\x32\x1b.proto.DoubleRatioAttribute\x12Q\n electrical_range_skip_indication\x18[ \x01(\x0b\x32\'.proto.RangeSkipIndicationEnumAttribute\x12N\n\x18\x65lectricconsumptionreset\x18\\ \x01(\x0b\x32,.proto.DoubleElectricityConsumptionAttribute\x12N\n\x18\x65lectricconsumptionstart\x18] \x01(\x0b\x32,.proto.DoubleElectricityConsumptionAttribute\x12H\n\x16\x65mergency_power_supply\x18^ \x01(\x0b\x32(.proto.EmergencyPowerSupplyEnumAttribute\x12>\n\x19\x65ndof_charge_time_weekday\x18_ \x01(\x0b\x32\x1b.proto.WeekdayEnumAttribute\x12\x37\n\x0f\x65ndofchargetime\x18` \x01(\x0b\x32\x1e.proto.Int64ClockHourAttribute\x12@\n\x12\x65ngine_hood_status\x18\x61 \x01(\x0b\x32$.proto.EngineHoodStatusEnumAttribute\x12\x35\n\x0c\x65ngine_state\x18\x62 \x01(\x0b\x32\x1f.proto.EngineStateEnumAttribute\x12\x42\n\x1e\x65v_range_assist_drive_on_s_o_c\x18\x63 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12<\n\x1d\x65v_range_assist_drive_on_time\x18\x64 \x01(\x0b\x32\x15.proto.Int64Attribute\x12@\n\x12\x65vse_pairing_state\x18\x65 \x01(\x0b\x32$.proto.EvsePairingStateEnumAttribute\x12\x41\n\x1e\x65xterior_monitoring_last_event\x18\x66 \x01(\x0b\x32\x19.proto.TimestampAttribute\x12P\n\x1a\x65xterior_monitoring_status\x18g \x01(\x0b\x32,.proto.ExteriorMonitoringStatusEnumAttribute\x12J\n\x17\x66ilter_particle_loading\x18h \x01(\x0b\x32).proto.FilterParticleLoadingEnumAttribute\x12@\n\x12\x66lip_window_status\x18i \x01(\x0b\x32$.proto.FlipWindowStatusEnumAttribute\x12K\n$gained_range_since_start_of_charging\x18j \x01(\x0b\x32\x1d.proto.Int64DistanceAttribute\x12.\n\x0egas_tank_level\x18k \x01(\x0b\x32\x16.proto.DoubleAttribute\x12;\n\x16gas_tank_level_percent\x18l \x01(\x0b\x32\x1b.proto.DoubleRatioAttribute\x12\x36\n\x0egas_tank_range\x18m \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12\x41\n\x13gasconsumptionreset\x18n \x01(\x0b\x32$.proto.DoubleGasConsumptionAttribute\x12\x41\n\x13gasconsumptionstart\x18o \x01(\x0b\x32$.proto.DoubleGasConsumptionAttribute\x12Y\n\x1fhv_battery_precond_availability\x18p \x01(\x0b\x32\x30.proto.HvBatteryPrecondAvailabilityEnumAttribute\x12:\n\x1bhv_battery_precond_duration\x18q \x01(\x0b\x32\x15.proto.Int64Attribute\x12\\\n hv_battery_precond_request_state\x18r \x01(\x0b\x32\x32.proto.HvBatteryPrecondRequestStateObjectAttribute\x12M\n\x18hv_battery_precond_state\x18s \x01(\x0b\x32+.proto.HvBatteryPrecondStateObjectAttribute\x12\x39\n\x1ahv_battery_state_of_health\x18t \x01(\x0b\x32\x15.proto.Int64Attribute\x12I\n*hv_battery_state_of_health_distance_update\x18u \x01(\x0b\x32\x15.proto.Int64Attribute\x12K\n+hv_battery_state_of_health_reserve_capacity\x18v \x01(\x0b\x32\x16.proto.DoubleAttribute\x12\x62\n$hv_battery_thermal_propagation_event\x18w \x01(\x0b\x32\x34.proto.HvBatteryThermalPropagationEventEnumAttribute\x12;\n\x0fhybrid_warnings\x18x \x01(\x0b\x32".proto.HybridWarningsEnumAttribute\x12\x38\n\rignitionstate\x18y \x01(\x0b\x32!.proto.IgnitionstateEnumAttribute\x12\x41\n\x1einterior_monitoring_last_event\x18z \x01(\x0b\x32\x19.proto.TimestampAttribute\x12P\n\x1ainterior_monitoring_status\x18{ \x01(\x0b\x32,.proto.InteriorMonitoringStatusEnumAttribute\x12]\n%interior_protection_activation_status\x18| \x01(\x0b\x32..proto.ProtectionActivationStatusEnumAttribute\x12\x63\n$interior_protection_selection_status\x18} \x01(\x0b\x32\x35.proto.InteriorProtectionSelectionStatusEnumAttribute\x12U\n!interior_protection_sensor_status\x18~ \x01(\x0b\x32*.proto.ProtectionSensorStatusEnumAttribute\x12\x44\n\x14key_activation_state\x18\x7f \x01(\x0b\x32&.proto.KeyActivationStateEnumAttribute\x12O\n\x18keyline_activation_state\x18\x80\x01 \x01(\x0b\x32,.proto.KeylineActivationStateObjectAttribute\x12\x35\n\x0clanguage_h_u\x18\x81\x01 \x01(\x0b\x32\x1e.proto.LanguageHUEnumAttribute\x12<\n\x0flast_park_event\x18\x82\x01 \x01(\x0b\x32".proto.TimestampClockHourAttribute\x12\x32\n\x12last_park_event_id\x18\x83\x01 \x01(\x0b\x32\x15.proto.Int64Attribute\x12<\n\x1dlast_park_event_not_confirmed\x18\x84\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12\x36\n\x12last_theft_warning\x18\x85\x01 \x01(\x0b\x32\x19.proto.TimestampAttribute\x12N\n\x19last_theft_warning_reason\x18\x86\x01 \x01(\x0b\x32*.proto.LastTheftWarningReasonEnumAttribute\x12N\n\x1cliquid_range_skip_indication\x18\x87\x01 \x01(\x0b\x32\'.proto.RangeSkipIndicationEnumAttribute\x12L\n\x16liquidconsumptionreset\x18\x88\x01 \x01(\x0b\x32+.proto.DoubleCombustionConsumptionAttribute\x12L\n\x16liquidconsumptionstart\x18\x89\x01 \x01(\x0b\x32+.proto.DoubleCombustionConsumptionAttribute\x12,\n\x07max_soc\x18\x8a\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x38\n\x13max_soc_lower_limit\x18\x8b\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x38\n\x13max_soc_upper_limit\x18\x8c\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x30\n\x08maxrange\x18\x8d\x01 \x01(\x0b\x32\x1d.proto.Int64DistanceAttribute\x12,\n\x07min_soc\x18\x8e\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x38\n\x13min_soc_lower_limit\x18\x8f\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x38\n\x13min_soc_upper_limit\x18\x90\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x45\n\x13next_departure_time\x18\x91\x01 \x01(\x0b\x32\'.proto.NextDepartureTimeObjectAttribute\x12\x41\n\x1bnext_departure_time_weekday\x18\x92\x01 \x01(\x0b\x32\x1b.proto.WeekdayEnumAttribute\x12+\n\x03odo\x18\x93\x01 \x01(\x0b\x32\x1d.proto.Int64DistanceAttribute\x12.\n\toil_level\x18\x94\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12?\n\x11oil_warning_level\x18\x95\x01 \x01(\x0b\x32#.proto.OilWarningLevelEnumAttribute\x12\x31\n\x12panic_alarm_active\x18\x96\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12\\\n park_collision_activation_status\x18\x97\x01 \x01(\x0b\x32\x31.proto.ParkCollisionActivationStatusEnumAttribute\x12X\n\x1epark_collision_inactive_reason\x18\x98\x01 \x01(\x0b\x32/.proto.ParkCollisionInactiveReasonEnumAttribute\x12g\n&park_collision_picture_transfer_status\x18\x99\x01 \x01(\x0b\x32\x36.proto.ParkCollisionPictureTransferStatusEnumAttribute\x12Z\n\x1fpark_collision_selection_status\x18\x9a\x01 \x01(\x0b\x32\x30.proto.ParkCollisionSelectionStatusEnumAttribute\x12=\n\x10park_event_level\x18\x9b\x01 \x01(\x0b\x32".proto.ParkEventLevelEnumAttribute\x12\x61\n#park_event_picture_selection_status\x18\x9c\x01 \x01(\x0b\x32\x33.proto.ParkEventPictureSelectionStatusEnumAttribute\x12g\n&park_event_picture_transmission_status\x18\x9d\x01 \x01(\x0b\x32\x36.proto.ParkEventPictureTransmissionStatusEnumAttribute\x12L\n\x18park_event_sensor_status\x18\x9e\x01 \x01(\x0b\x32).proto.ParkEventSensorStatusEnumAttribute\x12;\n\x0fpark_event_type\x18\x9f\x01 \x01(\x0b\x32!.proto.ParkEventTypeEnumAttribute\x12=\n\x0fparkbrakestatus\x18\xa0\x01 \x01(\x0b\x32#.proto.ParkbrakestatusEnumAttribute\x12`\n"performance_limitation_mode_status\x18\xa1\x01 \x01(\x0b\x32\x33.proto.PerformanceLimitationModeStatusEnumAttribute\x12M\n\x18picture_recording_status\x18\xa2\x01 \x01(\x0b\x32*.proto.PictureRecordingStatusEnumAttribute\x12^\n!picture_transfer_selection_status\x18\xa3\x01 \x01(\x0b\x32\x32.proto.PictureTransferSelectionStatusEnumAttribute\x12\x31\n\x10position_heading\x18\xa4\x01 \x01(\x0b\x32\x16.proto.DoubleAttribute\x12-\n\x0cposition_lat\x18\xa5\x01 \x01(\x0b\x32\x16.proto.DoubleAttribute\x12.\n\rposition_long\x18\xa6\x01 \x01(\x0b\x32\x16.proto.DoubleAttribute\x12-\n\x0eprecond_active\x18\xa7\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12;\n\x1cprecond_at_departure_disable\x18\xa8\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12\x30\n\x10precond_duration\x18\xa9\x01 \x01(\x0b\x32\x15.proto.Int64Attribute\x12\x38\n\rprecond_error\x18\xaa\x01 \x01(\x0b\x32 .proto.PrecondErrorEnumAttribute\x12\x34\n\x0bprecond_now\x18\xab\x01 \x01(\x0b\x32\x1e.proto.PrecondNowEnumAttribute\x12<\n\x11precond_now_error\x18\xac\x01 \x01(\x0b\x32 .proto.PrecondErrorEnumAttribute\x12Q\n\x19precond_operability_state\x18\xad\x01 \x01(\x0b\x32-.proto.PrecondOperabilityStateObjectAttribute\x12I\n\x16precond_operating_mode\x18\xae\x01 \x01(\x0b\x32(.proto.PrecondOperatingModeEnumAttribute\x12\x41\n\x17precond_seat_front_left\x18\xaf\x01 \x01(\x0b\x32\x1f.proto.PrecondSeatEnumAttribute\x12\x42\n\x18precond_seat_front_right\x18\xb0\x01 \x01(\x0b\x32\x1f.proto.PrecondSeatEnumAttribute\x12@\n\x16precond_seat_rear_left\x18\xb1\x01 \x01(\x0b\x32\x1f.proto.PrecondSeatEnumAttribute\x12\x41\n\x17precond_seat_rear_right\x18\xb2\x01 \x01(\x0b\x32\x1f.proto.PrecondSeatEnumAttribute\x12:\n\rprecond_state\x18\xb3\x01 \x01(\x0b\x32".proto.PrecondStateObjectAttribute\x12\x43\n\x12precondatdeparture\x18\xb4\x01 \x01(\x0b\x32&.proto.PrecondatdepartureEnumAttribute\x12\x35\n\rrange_ad_blue\x18\xb5\x01 \x01(\x0b\x32\x1d.proto.Int64DistanceAttribute\x12;\n\x13range_electric_wltp\x18\xb6\x01 \x01(\x0b\x32\x1d.proto.Int64DistanceAttribute\x12\x35\n\rrangeelectric\x18\xb7\x01 \x01(\x0b\x32\x1d.proto.Int64DistanceAttribute\x12\x33\n\x0brangeliquid\x18\xb8\x01 \x01(\x0b\x32\x1d.proto.Int64DistanceAttribute\x12\x32\n\x13remote_start_active\x18\xb9\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12\x34\n\x14remote_start_endtime\x18\xba\x01 \x01(\x0b\x32\x15.proto.Int64Attribute\x12\x44\n\x18remote_start_temperature\x18\xbb\x01 \x01(\x0b\x32!.proto.DoubleTemperatureAttribute\x12R\n\x1aremote_update_start_status\x18\xbc\x01 \x01(\x0b\x32-.proto.RemoteUpdateStartStatusObjectAttribute\x12\x39\n\rrooftopstatus\x18\xbd\x01 \x01(\x0b\x32!.proto.RooftopstatusEnumAttribute\x12K\n\x17selected_charge_program\x18\xbe\x01 \x01(\x0b\x32).proto.SelectedChargeProgramEnumAttribute\x12\x33\n\x13serviceintervaldays\x18\xbf\x01 \x01(\x0b\x32\x15.proto.Int64Attribute\x12?\n\x17serviceintervaldistance\x18\xc0\x01 \x01(\x0b\x32\x1d.proto.Int64DistanceAttribute\x12:\n\x0esmart_charging\x18\xc1\x01 \x01(\x0b\x32!.proto.SmartChargingEnumAttribute\x12R\n\x1bsmart_charging_at_departure\x18\xc2\x01 \x01(\x0b\x32,.proto.SmartChargingAtDepartureEnumAttribute\x12S\n\x1csmart_charging_at_departure2\x18\xc3\x01 \x01(\x0b\x32,.proto.SmartChargingAtDepartureEnumAttribute\x12(\n\x03soc\x18\xc4\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12H\n\x17soc_calibration_request\x18\xc5\x01 \x01(\x0b\x32&.proto.CalibrationRequestEnumAttribute\x12\x34\n\nsocprofile\x18\xc6\x01 \x01(\x0b\x32\x1f.proto.SocprofileArrayAttribute\x12W\n\x1dsoh_calibration_notifications\x18\xc7\x01 \x01(\x0b\x32/.proto.SohCalibrationNotificationsEnumAttribute\x12K\n\x17soh_calibration_planned\x18\xc8\x01 \x01(\x0b\x32).proto.SohCalibrationPlannedEnumAttribute\x12H\n\x17soh_calibration_request\x18\xc9\x01 \x01(\x0b\x32&.proto.CalibrationRequestEnumAttribute\x12M\n\x18soh_calibration_required\x18\xca\x01 \x01(\x0b\x32*.proto.SohCalibrationRequiredEnumAttribute\x12G\n\x15soh_calibration_state\x18\xcb\x01 \x01(\x0b\x32\'.proto.SohCalibrationStateEnumAttribute\x12\x39\n\x19soh_charge_time_extension\x18\xcc\x01 \x01(\x0b\x32\x15.proto.Int64Attribute\x12M\n\x18soh_favorable_conditions\x18\xcd\x01 \x01(\x0b\x32*.proto.SohFavorableConditionsEnumAttribute\x12>\n\x10speed_alert_conf\x18\xce\x01 \x01(\x0b\x32#.proto.SpeedAlertConfArrayAttribute\x12\x41\n\x13speed_unit_from_i_c\x18\xcf\x01 \x01(\x0b\x32#.proto.SpeedUnitFromICEnumAttribute\x12\x38\n\rsunroof_event\x18\xd0\x01 \x01(\x0b\x32 .proto.SunroofEventEnumAttribute\x12\x33\n\x14sunroof_event_active\x18\xd1\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12K\n\x1asunroof_status_front_blind\x18\xd2\x01 \x01(\x0b\x32&.proto.SunroofStatusBlindEnumAttribute\x12J\n\x19sunroof_status_rear_blind\x18\xd3\x01 \x01(\x0b\x32&.proto.SunroofStatusBlindEnumAttribute\x12\x39\n\rsunroofstatus\x18\xd4\x01 \x01(\x0b\x32!.proto.SunroofstatusEnumAttribute\x12\x37\n\x12tank_level_ad_blue\x18\xd5\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12\x35\n\x10tanklevelpercent\x18\xd6\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12/\n\ntarget_soc\x18\xd7\x01 \x01(\x0b\x32\x1a.proto.Int64RatioAttribute\x12[\n tcu_connection_state_low_channel\x18\xd8\x01 \x01(\x0b\x32\x30.proto.TcuConnectionStateLowChannelEnumAttribute\x12\x44\n\x14tcu_thermo_shut_down\x18\xd9\x01 \x01(\x0b\x32%.proto.TcuThermoShutDownEnumAttribute\x12>\n\x14teenage_driving_mode\x18\xda\x01 \x01(\x0b\x32\x1f.proto.DrivingModeEnumAttribute\x12\x43\n\x12temperature_points\x18\xdb\x01 \x01(\x0b\x32&.proto.TemperaturePointsArrayAttribute\x12\x44\n\x14temperature_unit_h_u\x18\xdc\x01 \x01(\x0b\x32%.proto.TemperatureUnitHUEnumAttribute\x12\x31\n\x12theft_alarm_active\x18\xdd\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12\x31\n\x12theft_system_armed\x18\xde\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12:\n\x0ftime_format_h_u\x18\xdf\x01 \x01(\x0b\x32 .proto.TimeFormatHUEnumAttribute\x12?\n\x16tire_marker_front_left\x18\xe0\x01 \x01(\x0b\x32\x1e.proto.TireMarkerEnumAttribute\x12@\n\x17tire_marker_front_right\x18\xe1\x01 \x01(\x0b\x32\x1e.proto.TireMarkerEnumAttribute\x12\x44\n\x1btire_marker_inner_rear_left\x18\xe2\x01 \x01(\x0b\x32\x1e.proto.TireMarkerEnumAttribute\x12\x45\n\x1ctire_marker_inner_rear_right\x18\xe3\x01 \x01(\x0b\x32\x1e.proto.TireMarkerEnumAttribute\x12>\n\x15tire_marker_rear_left\x18\xe4\x01 \x01(\x0b\x32\x1e.proto.TireMarkerEnumAttribute\x12?\n\x16tire_marker_rear_right\x18\xe5\x01 \x01(\x0b\x32\x1e.proto.TireMarkerEnumAttribute\x12\x46\n\x1dtire_pressure_inner_rear_left\x18\xe6\x01 \x01(\x0b\x32\x1e.proto.DoublePressureAttribute\x12G\n\x1etire_pressure_inner_rear_right\x18\xe7\x01 \x01(\x0b\x32\x1e.proto.DoublePressureAttribute\x12G\n\x15tire_sensor_available\x18\xe8\x01 \x01(\x0b\x32\'.proto.TireSensorAvailableEnumAttribute\x12H\n\x16tire_warning_level_prw\x18\xe9\x01 \x01(\x0b\x32\'.proto.TireWarningLevelPrwEnumAttribute\x12@\n\x17tirepressure_front_left\x18\xea\x01 \x01(\x0b\x32\x1e.proto.DoublePressureAttribute\x12\x41\n\x18tirepressure_front_right\x18\xeb\x01 \x01(\x0b\x32\x1e.proto.DoublePressureAttribute\x12?\n\x16tirepressure_rear_left\x18\xec\x01 \x01(\x0b\x32\x1e.proto.DoublePressureAttribute\x12@\n\x17tirepressure_rear_right\x18\xed\x01 \x01(\x0b\x32\x1e.proto.DoublePressureAttribute\x12=\n\x0ftirewarninglamp\x18\xee\x01 \x01(\x0b\x32#.proto.TirewarninglampEnumAttribute\x12=\n\x0ftirewarningsprw\x18\xef\x01 \x01(\x0b\x32#.proto.TirewarningsprwEnumAttribute\x12=\n\x0ftirewarningsrdk\x18\xf0\x01 \x01(\x0b\x32#.proto.TirewarningsrdkEnumAttribute\x12Y\n tow_protection_activation_status\x18\xf1\x01 \x01(\x0b\x32..proto.ProtectionActivationStatusEnumAttribute\x12Z\n\x1ftow_protection_selection_status\x18\xf2\x01 \x01(\x0b\x32\x30.proto.TowProtectionSelectionStatusEnumAttribute\x12Q\n\x1ctow_protection_sensor_status\x18\xf3\x01 \x01(\x0b\x32*.proto.ProtectionSensorStatusEnumAttribute\x12@\n\x12tracking_state_h_u\x18\xf4\x01 \x01(\x0b\x32#.proto.TrackingStateHuEnumAttribute\x12Q\n\x1bturn_off_engine_pre_warning\x18\xf5\x01 \x01(\x0b\x32+.proto.TurnOffEnginePreWarningEnumAttribute\x12@\n turn_off_engine_pre_warning_time\x18\xf6\x01 \x01(\x0b\x32\x15.proto.Int64Attribute\x12<\n\x12valet_driving_mode\x18\xf7\x01 \x01(\x0b\x32\x1f.proto.DrivingModeEnumAttribute\x12V\n\x1dvehicle_data_connection_state\x18\xf8\x01 \x01(\x0b\x32..proto.VehicleDataConnectionStateEnumAttribute\x12G\n\x15vehicle_health_status\x18\xf9\x01 \x01(\x0b\x32\'.proto.VehicleHealthStatusEnumAttribute\x12\x61\n#vehicle_theft_alarm_inactive_reason\x18\xfa\x01 \x01(\x0b\x32\x33.proto.VehicleTheftAlarmInactiveReasonEnumAttribute\x12%\n\x05vtime\x18\xfb\x01 \x01(\x0b\x32\x15.proto.Int64Attribute\x12\x30\n\x11warningbrakefluid\x18\xfc\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12\x35\n\x16warningbrakeliningwear\x18\xfd\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12\x35\n\x16warningcoolantlevellow\x18\xfe\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12\x31\n\x12warningenginelight\x18\xff\x01 \x01(\x0b\x32\x14.proto.BoolAttribute\x12?\n\x10warningwashwater\x18\x80\x02 \x01(\x0b\x32$.proto.WarningwashwaterEnumAttribute\x12<\n\x0eweekly_profile\x18\x81\x02 \x01(\x0b\x32#.proto.WeeklyProfileObjectAttribute\x12\x39\n\x0eweekly_set_h_u\x18\x82\x02 \x01(\x0b\x32 .proto.WeeklySetHUArrayAttribute\x12H\n\x18window_status_rear_blind\x18\x83\x02 \x01(\x0b\x32%.proto.WindowStatusBlindEnumAttribute\x12M\n\x1dwindow_status_rear_left_blind\x18\x84\x02 \x01(\x0b\x32%.proto.WindowStatusBlindEnumAttribute\x12N\n\x1ewindow_status_rear_right_blind\x18\x85\x02 \x01(\x0b\x32%.proto.WindowStatusBlindEnumAttribute\x12@\n\x15windowstatusfrontleft\x18\x86\x02 \x01(\x0b\x32 .proto.WindowstatusEnumAttribute\x12\x41\n\x16windowstatusfrontright\x18\x87\x02 \x01(\x0b\x32 .proto.WindowstatusEnumAttribute\x12?\n\x14windowstatusrearleft\x18\x88\x02 \x01(\x0b\x32 .proto.WindowstatusEnumAttribute\x12@\n\x15windowstatusrearright\x18\x89\x02 \x01(\x0b\x32 .proto.WindowstatusEnumAttribute\x12\x43\n\x13\x64oor_status_overall\x18\x8a\x02 \x01(\x0b\x32%.proto.DoorStatusOverallEnumAttribute\x12\x36\n\roverall_range\x18\x8b\x02 \x01(\x0b\x32\x1e.proto.DoubleDistanceAttribute\x12R\n3proximity_calculation_for_vehicle_position_required\x18\x8c\x02 \x01(\x0b\x32\x14.proto.BoolAttribute\x12G\n\x15starter_battery_state\x18\x8d\x02 \x01(\x0b\x32\'.proto.StarterBatteryStateEnumAttribute\x12\x39\n\x19tire_press_meas_timestamp\x18\x8e\x02 \x01(\x0b\x32\x15.proto.Int64Attribute\x12R\n\x1bvehicle_position_error_code\x18\x8f\x02 \x01(\x0b\x32,.proto.VehiclePositionErrorCodeEnumAttribute\x12G\n\x15window_status_overall\x18\x90\x02 \x01(\x0b\x32\'.proto.WindowStatusOverallEnumAttribute*\x9d\x02\n\x11\x41mgStageModeState\x12+\n\'AMG_STAGE_MODE_STATE_STAGING_NOT_ACTIVE\x10\x00\x12.\n*AMG_STAGE_MODE_STATE_REVERTING_IN_PROGRESS\x10\x01\x12>\n:AMG_STAGE_MODE_STATE_TRANSFORMING_FINISHED_TRANSFORMED_POS\x10\x02\x12:\n6AMG_STAGE_MODE_STATE_TRANSFORMING_FINISHED_DEFAULT_POS\x10\x03\x12/\n+AMG_STAGE_MODE_STATE_TRANSFORMATION_ABORTED\x10\x04*\xb4\x03\n"ChildPresenceDetectionWarningLevel\x12\x0e\n\nNO_WARNING\x10\x00\x12\x0b\n\x07INITIAL\x10\x01\x12\x0e\n\nESCALATION\x10\x02\x12\x15\n\x11SILENT_ESCALATION\x10\x03\x12#\n\x1fWARNING_LEVEL_DEACTIVATED_ERROR\x10\x04\x12#\n\x1fWARNING_LEVEL_ACTIVE_ECALL_SOON\x10\x05\x12*\n&WARNING_LEVEL_ACTIVE_ECALL_TRANSMITTED\x10\x06\x12,\n(WARNING_LEVEL_ACTIVE_ECALL_NOT_AVAILABLE\x10\x07\x12\x19\n\x15WARNING_LEVEL_DELAYED\x10\x08\x12)\n%WARNING_LEVEL_ACTIVE_NO_ECALL_SIL_ESC\x10\t\x12%\n!WARNING_LEVEL_ACTIVE_NO_ECALL_ESC\x10\n\x12\x39\n5WARNING_LEVEL_ACTIVE_ECALL_NOT_AVAILABLE_SECOND_STAGE\x10\x0b*\x9a\x04\n&ChildPresenceDetectionWarningLastEvent\x12\x16\n\x12NO_WARNING_INITIAL\x10\x00\x12\'\n#WARNING_ACTIVE_TEMPERATURE_DECREASE\x10\x01\x12\'\n#WARNING_ACTIVE_TEMPERATURE_INCREASE\x10\x02\x12\x1e\n\x1aWARNING_ACTIVE_BATTERY_LOW\x10\x03\x12\x1d\n\x19WARNING_ACTIVE_ECALL_SOON\x10\x04\x12$\n WARNING_ACTIVE_ECALL_TRANSMITTED\x10\x05\x12\x17\n\x13WARNING_DEACTIVATED\x10\x06\x12\x17\n\x13NO_WARNING_NO_EVENT\x10\x07\x12\x13\n\x0fWARNING_DELAYED\x10\x08\x12\x1f\n\x1bWARNING_DEACTIVATED_BATTERY\x10\t\x12\x1d\n\x19WARNING_DEACTIVATED_ERROR\x10\n\x12\x1e\n\x1aWARNING_DEACTIVATED_UNLOCK\x10\x0b\x12&\n"WARNING_ACTIVE_ECALL_NOT_AVAILABLE\x10\x0c\x12\x38\n4WARNING_ACTIVE_ECALL_NOT_AVAILABLE_PUSH_NOTIFICATION\x10\r\x12\x18\n\x14\x43\x41MERA_NOT_AVAILABLE\x10\x0e*\x7f\n\x17KeylineActivationStates\x12$\n UNKNOWN_KEYLINE_ACTIVATION_STATE\x10\x00\x12\x0e\n\nALL_ACTIVE\x10\x01\x12\x19\n\x15SELECTIVE_DEACTIVATED\x10\x02\x12\x13\n\x0f\x41LL_DEACTIVATED\x10\x03*\xb7\x01\n\x1fPerformanceLimitationModeStatus\x12\x12\n\x0ePLM_NO_WARNING\x10\x00\x12\x15\n\x11SVH_EVENT_MANAGED\x10\x01\x12\x11\n\rPLM_REQUESTED\x10\x02\x12\x1c\n\x18PLM_SUCCESSFUL_REQUESTED\x10\x03\x12\x16\n\x12PLM_NOT_AUTHORIZED\x10\x04\x12\r\n\tPLM_ERROR\x10\x05\x12\x11\n\rPLM_INCAPABLE\x10\x06*\xaa\x02\n\x18\x45xteriorMonitoringStatus\x12\x0c\n\x08\x45XM_IDLE\x10\x00\x12\x0f\n\x0b\x45XM_WAKE_UP\x10\x01\x12\x19\n\x15\x45XM_REQUEST_SUBMITTED\x10\x02\x12\x11\n\rEXM_RECORDING\x10\x03\x12\x10\n\x0c\x45XM_ANNOUNCE\x10\x04\x12\x11\n\rEXM_UPLOADING\x10\x05\x12\x11\n\rEXM_COMPLETED\x10\x06\x12\x19\n\x15\x45XM_AE_REQUEST_DENIED\x10\x65\x12\x14\n\x10\x45XM_AE_INCAPABLE\x10j\x12\x14\n\x10\x45XM_AE_OVERRULED\x10l\x12!\n\x1d\x45XM_AE_PLAY_PROTECTION_ACTIVE\x10n\x12\x1f\n\x1b\x45XM_AE_PRECONDITION_MISSING\x10o*\xc3\x02\n\x18InteriorMonitoringStatus\x12\x0c\n\x08INM_IDLE\x10\x00\x12\x0f\n\x0bINM_WAKE_UP\x10\x01\x12\x11\n\rINM_RECORDING\x10\x02\x12\x15\n\x11INM_PICTURE_TAKEN\x10\x03\x12\x10\n\x0cINM_ANNOUNCE\x10\x04\x12\x11\n\rINM_UPLOADING\x10\x05\x12\x11\n\rINM_COMPLETED\x10\x06\x12\x15\n\x11INM_CAMERA_BROKEN\x10\x65\x12\x13\n\x0fINM_MEMORY_FULL\x10g\x12\x1b\n\x17INM_PRIVACY_MODE_ACTIVE\x10i\x12\x1f\n\x1bINM_PICTURE_TAKING_DISABLED\x10j\x12\x18\n\x14INM_ACTIVE_BURSTMODE\x10l\x12"\n\x1eINM_PICTURE_TAKING_INTERRUPTED\x10n*\xd1\x01\n\x0cUpdateStatus\x12\x19\n\x15UPDATE_STATUS_UNKNOWN\x10\x00\x12\x17\n\x13\x41WAIT_REPROGRAMMING\x10\x01\x12!\n\x1d\x41WAIT_REPROGRAMMING_STARTABLE\x10\x02\x12\x11\n\rREPROG_ACTIVE\x10\x03\x12\r\n\tPOSTPONED\x10\x04\x12\x0e\n\nSUCCESSFUL\x10\x05\x12\x0b\n\x07\x46\x41ILURE\x10\x06\x12\t\n\x05PANIC\x10\x07\x12\t\n\x05\x45RROR\x10\x08\x12\x15\n\x11\x43ONFIRMED_STARTED\x10\t*U\n\x15SohCalibrationPlanned\x12\x1f\n\x1bSOH_CALIBRATION_NOT_PLANNED\x10\x00\x12\x1b\n\x17SOH_CALIBRATION_PLANNED\x10\x01*\x89\x02\n\x11\x44\x63\x43hargingProfile\x12\x1f\n\x1b\x44\x43_CHARGING_PROFILE_UNKNOWN\x10\x00\x12 \n\x1c\x44\x43_CHARGING_PROFILE_STANDARD\x10\x01\x12%\n!DC_CHARGING_PROFILE_SILENT_OR_ECO\x10\x02\x12!\n\x1d\x44\x43_CHARGING_PROFILE_ULTRAFAST\x10\x03\x12\x1f\n\x1b\x44\x43_CHARGING_PROFILE_PITSTOP\x10\x04\x12"\n\x1e\x44\x43_CHARGING_PROFILE_FAST_ECO_1\x10\x05\x12"\n\x1e\x44\x43_CHARGING_PROFILE_FAST_ECO_2\x10\x06*\x9e\x03\n"ParkEventPictureTransmissionStatus\x12/\n+PARK_EVENT_PICTURE_TRANSMISSION_STATUS_IDLE\x10\x00\x12\x32\n.PARK_EVENT_PICTURE_TRANSMISSION_STATUS_WAKE_UP\x10\x01\x12<\n8PARK_EVENT_PICTURE_TRANSMISSION_STATUS_REQUEST_SUBMITTED\x10\x02\x12\x34\n0PARK_EVENT_PICTURE_TRANSMISSION_STATUS_RECORDING\x10\x03\x12\x33\n/PARK_EVENT_PICTURE_TRANSMISSION_STATUS_ANNOUNCE\x10\x04\x12\x34\n0PARK_EVENT_PICTURE_TRANSMISSION_STATUS_UPLOADING\x10\x05\x12\x34\n0PARK_EVENT_PICTURE_TRANSMISSION_STATUS_COMPLETED\x10\x06*\x93\x0e\n\x19\x43hargingScheduleUseCaseId\x12\x30\n,CHARGING_SCHEDULE_USE_CASE_ID_SMART_CHARGING\x10\x00\x12?\n;CHARGING_SCHEDULE_USE_CASE_ID_MERCEDES_INTELLIGENT_CHARGING\x10\x01\x12\x39\n5CHARGING_SCHEDULE_USE_CASE_ID_BETA_COMMUNITY_CHARGING\x10\x02\x12\x30\n,CHARGING_SCHEDULE_USE_CASE_ID_SOLAR_CHARGING\x10\n\x12\x30\n,CHARGING_SCHEDULE_USE_CASE_ID_GREEN_CHARGING\x10\x0b\x12\x34\n0CHARGING_SCHEDULE_USE_CASE_ID_EFFICIENT_CHARGING\x10\x0c\x12\x37\n3CHARGING_SCHEDULE_USE_CASE_ID_ECO_FRIENDLY_CHARGING\x10\r\x12\x36\n2CHARGING_SCHEDULE_USE_CASE_ID_SUSTAINABLE_CHARGING\x10\x0e\x12\x36\n2CHARGING_SCHEDULE_USE_CASE_ID_INTELLIGENT_CHARGING\x10\x0f\x12\x39\n5CHARGING_SCHEDULE_USE_CASE_ID_WORKPLACE_CHARGING_PLAN\x10\x10\x12\x34\n0CHARGING_SCHEDULE_USE_CASE_ID_HOME_CHARGING_PLAN\x10\x11\x12\x38\n4CHARGING_SCHEDULE_USE_CASE_ID_FLEET_MANAGED_CHARGING\x10\x12\x12:\n6CHARGING_SCHEDULE_USE_CASE_ID_PRICE_OPTIMIZED_CHARGING\x10\x13\x12;\n7CHARGING_SCHEDULE_USE_CASE_ID_BATTERY_FRIENDLY_CHARGING\x10\x14\x12\x43\n?CHARGING_SCHEDULE_USE_CASE_ID_EXTERNAL_NOISE_OPTIMIZED_CHARGING\x10\x15\x12\x43\n?CHARGING_SCHEDULE_USE_CASE_ID_VIDEO_WATCHING_OPTIMIZED_CHARGING\x10\x16\x12:\n6CHARGING_SCHEDULE_USE_CASE_ID_TIME_CONTROLLED_CHARGING\x10\x17\x12\x37\n3CHARGING_SCHEDULE_USE_CASE_ID_PEAK_SHAVING_CHARGING\x10\x18\x12@\n\n:SOH_CALIBRATION_NOTIFICATIONS_NO_SOH_CALIBRATION_NECESSARY\x10\x00\x12;\n7SOH_CALIBRATION_NOTIFICATIONS_SEND_NOTIFICATION_LEVEL_1\x10\x01\x12;\n7SOH_CALIBRATION_NOTIFICATIONS_SEND_NOTIFICATION_LEVEL_2\x10\x02\x12;\n7SOH_CALIBRATION_NOTIFICATIONS_SEND_NOTIFICATION_LEVEL_3\x10\x03\x12;\n7SOH_CALIBRATION_NOTIFICATIONS_SEND_NOTIFICATION_LEVEL_4\x10\x04*\xe5\x02\n!HvBatteryPrecondStatesDischarging\x12\x18\n\x14\x44ISCHARGING_INACTIVE\x10\x00\x12\x1e\n\x1a\x44ISCHARGING_HEATING_ACTIVE\x10\x01\x12"\n\x1e\x44ISCHARGING_HEATING_SUCCESSFUL\x10\x02\x12&\n"DISCHARGING_HEATING_NOT_SUFFICIENT\x10\x03\x12&\n"DISCHARGING_HEATING_RECOMMENDATION\x10\x04\x12\x1e\n\x1a\x44ISCHARGING_COOLING_ACTIVE\x10\x05\x12"\n\x1e\x44ISCHARGING_COOLING_SUCCESSFUL\x10\x06\x12&\n"DISCHARGING_COOLING_NOT_SUFFICIENT\x10\x07\x12&\n"DISCHARGING_COOLING_RECOMMENDATION\x10\x08*\xcf\x02\n\x1eHvBatteryPrecondStatesCharging\x12\x1d\n\x19\x43HARGING_HEATING_INACTIVE\x10\x00\x12\x1b\n\x17\x43HARGING_HEATING_ACTIVE\x10\x01\x12\x1f\n\x1b\x43HARGING_HEATING_SUCCESSFUL\x10\x02\x12#\n\x1f\x43HARGING_HEATING_NOT_SUFFICIENT\x10\x03\x12#\n\x1f\x43HARGING_HEATING_RECOMMENDATION\x10\x04\x12\x1b\n\x17\x43HARGING_COOLING_ACTIVE\x10\x05\x12\x1f\n\x1b\x43HARGING_COOLING_SUCCESSFUL\x10\x06\x12#\n\x1f\x43HARGING_COOLING_NOT_SUFFICIENT\x10\x07\x12#\n\x1f\x43HARGING_COOLING_RECOMMENDATION\x10\x08*\xc3\x01\n\x0cMainCategory\x12\x18\n\x14MAIN_CATEGORY_SERVER\x10\x00\x12\x15\n\x11MAIN_CATEGORY_HMI\x10\x01\x12 \n\x1cMAIN_CATEGORY_VEHICLE_SYSTEM\x10\x02\x12\x1d\n\x19MAIN_CATEGORY_DIAGNOSTICS\x10\x03\x12\x18\n\x14MAIN_CATEGORY_REMOTE\x10\x04\x12\'\n#MAIN_CATEGORY_CONTAINER_APPLICATION\x10\x05*N\n\x0bSubCategory\x12\x18\n\x14SUB_CATEGORY_UNKNOWN\x10\x00\x12%\n!SUB_CATEGORY_BATTERY_CONDITIONING\x10\x01*_\n\x10SpecificCategory\x12\x1d\n\x19SPECIFIC_CATEGORY_UNKNOWN\x10\x00\x12,\n(SPECIFIC_CATEGORY_PRECONDITIONING_BUTTON\x10\x01*\xa1\x01\n\x06Method\x12(\n$METHOD_COND_REQ_TO_REACH_TARGET_TEMP\x10\x00\x12)\n%METHOD_COND_REQ_TO_REACH_TARGET_POWER\x10\x01\x12$\n METHOD_OMIT_CONDITIONING_REQUEST\x10\x02\x12\x1c\n\x18METHOD_SET_CONFIGURATION\x10\x03*\x95\x01\n\x06Status\x12\x0c\n\x08STATE_OK\x10\x00\x12\x1b\n\x17STATE_UNSPECIFIED_ERROR\x10\x01\x12$\n STATE_CONDITIONING_NOT_NECESSARY\x10\x02\x12\x1d\n\x19STATE_TIME_NOT_SUFFICIENT\x10\x03\x12\x1b\n\x17STATE_BATTERY_LEVEL_LOW\x10\x04*\xba\x04\n\x1cHvBatteryPrecondAvailability\x12\x31\n-HV_BATTERY_PRECOND_AVAILABILITY_NOT_AVAILABLE\x10\x00\x12\x33\n/HV_BATTERY_PRECOND_AVAILABILITY_FULLY_AVAILABLE\x10\x01\x12\x45\nAHV_BATTERY_PRECOND_AVAILABILITY_TEMPORARILY_NOT_AVAILABLE_LOW_SOC\x10\x02\x12J\nFHV_BATTERY_PRECOND_AVAILABILITY_TEMPORARILY_NOT_AVAILABLE_MECHATRONICS\x10\x03\x12Q\nMHV_BATTERY_PRECOND_AVAILABILITY_TEMPORARILY_NOT_AVAILABLE_BATTERY_TEMPERATURE\x10\x04\x12=\n9HV_BATTERY_PRECOND_AVAILABILITY_LIMITED_AVAILABLE_LOW_SOC\x10\x05\x12\x42\n>HV_BATTERY_PRECOND_AVAILABILITY_LIMITED_AVAILABLE_MECHATRONICS\x10\x06\x12I\nEHV_BATTERY_PRECOND_AVAILABILITY_LIMITED_AVAILABLE_BATTERY_TEMPERATURE\x10\x07*\xe1\x03\n\x10\x45vsePairingState\x12\x1b\n\x17\x45VSE_PAIRING_STATE_IDLE\x10\x00\x12\x1f\n\x1b\x45VSE_PAIRING_STATE_FINISHED\x10\x01\x12\'\n#EVSE_PAIRING_STATE_FAILED_TLS_ERROR\x10\x02\x12%\n!EVSE_PAIRING_STATE_FAILED_TIMEOUT\x10\x03\x12\x30\n,EVSE_PAIRING_STATE_FAILED_NO_INDEX_AVAILABLE\x10\x04\x12&\n"EVSE_PAIRING_STATE_PROCESS_ONGOING\x10\x05\x12&\n"EVSE_PAIRING_STATE_PROCESS_STOPPED\x10\x06\x12\x30\n,EVSE_PAIRING_STATE_CERTIFICATE_NOT_INSTALLED\x10\x07\x12:\n6EVSE_PAIRING_STATE_PAIRING_SERVICE_NOT_OFFERED_BY_EVSE\x10\x08\x12O\nKEVSE_PAIRING_STATE_BIDIRECTIONAL_POWER_TRANSFER_SERVICE_NOT_OFFERED_BY_EVSE\x10\t*U\n\x14\x45mergencyPowerSupply\x12\x1e\n\x1a\x45MERGENCY_POWER_SUPPLY_OFF\x10\x00\x12\x1d\n\x19\x45MERGENCY_POWER_SUPPLY_ON\x10\x01*\x8f\x01\n"ParkCollisionPictureTransferStatus\x12\x34\n0PARK_COLLISION_PICTURE_TRANSFER_STATUS_DESELETED\x10\x00\x12\x33\n/PARK_COLLISION_PICTURE_TRANSFER_STATUS_SELECTED\x10\x01*f\n\x16PictureRecordingStatus\x12\'\n#PICTURE_RECORDING_STATUS_NOT_ACTIVE\x10\x00\x12#\n\x1fPICTURE_RECORDING_STATUS_ACTIVE\x10\x01*\x96\x04\n\x1bParkCollisionInactiveReason\x12+\n\'PARK_COLLISION_INACTIVE_REASON_DISABLED\x10\x00\x12=\n9PARK_COLLISION_INACTIVE_REASON_WAIT_FOR_SYSTEM_ACTIVATION\x10\x01\x12\x30\n,PARK_COLLISION_INACTIVE_REASON_SYSTEM_ACTIVE\x10\x02\x12\x35\n1PARK_COLLISION_INACTIVE_REASON_TRUNK_OR_DOOR_OPEN\x10\x03\x12-\n)PARK_COLLISION_INACTIVE_REASON_DESELECTED\x10\x04\x12\x32\n.PARK_COLLISION_INACTIVE_REASON_COLLISION_LIMIT\x10\x05\x12\x32\n.PARK_COLLISION_INACTIVE_REASON_MONITORING_TIME\x10\x06\x12\x37\n3PARK_COLLISION_INACTIVE_REASON_CONVERTIBLE_TOP_OPEN\x10\x07\x12(\n$PARK_COLLISION_INACTIVE_REASON_TEST1\x10\x08\x12(\n$PARK_COLLISION_INACTIVE_REASON_TEST2\x10\t*{\n\x1cParkCollisionSelectionStatus\x12-\n)PARK_COLLISION_SELECTION_STATUS_DESELETED\x10\x00\x12,\n(PARK_COLLISION_SELECTION_STATUS_SELECTED\x10\x01*\xe9\x01\n\x1fVehicleTheftAlarmInactiveReason\x12\x30\n,VEHICLE_THEFT_ALARM_INACTIVE_REASON_NO_ERROR\x10\x00\x12\x31\n-VEHICLE_THEFT_ALARM_INACTIVE_REASON_SIREN_COM\x10\x01\x12\x31\n-VEHICLE_THEFT_ALARM_INACTIVE_REASON_SIREN_BAT\x10\x02\x12.\n*VEHICLE_THEFT_ALARM_INACTIVE_REASON_SENSOR\x10\x03*\x9d\x01\n\x1dTowProtectionActivationStatus\x12(\n$TOW_PROTECTION_ACTIVATION_STATUS_OFF\x10\x00\x12\'\n#TOW_PROTECTION_ACTIVATION_STATUS_ON\x10\x01\x12)\n%TOW_PROTECTION_ACTIVATION_STATUS_INIT\x10\x02*{\n\x1cTowProtectionSelectionStatus\x12-\n)TOW_PROTECTION_SELECTION_STATUS_DESELETED\x10\x00\x12,\n(TOW_PROTECTION_SELECTION_STATUS_SELECTED\x10\x01*\xb1\x01\n"InteriorProtectionActivationStatus\x12-\n)INTERIOR_PROTECTION_ACTIVATION_STATUS_OFF\x10\x00\x12,\n(INTERIOR_PROTECTION_ACTIVATION_STATUS_ON\x10\x01\x12.\n*INTERIOR_PROTECTION_ACTIVATION_STATUS_INIT\x10\x02*\x8a\x01\n!InteriorProtectionSelectionStatus\x12\x32\n.INTERIOR_PROTECTION_SELECTION_STATUS_DESELETED\x10\x00\x12\x31\n-INTERIOR_PROTECTION_SELECTION_STATUS_SELECTED\x10\x01*^\n\x10PanicAlarmActive\x12 \n\x1cPANIC_ALARM_ACTIVE_CONFIRMED\x10\x00\x12(\n$PANIC_ALARM_ACTIVE_NOT_YET_CONFIRMED\x10\x01*\x89\x01\n\x1fParkEventPictureSelectionStatus\x12\x34\n0PARK_EVENT_PICTURE_SELECTION_STATUS_NOT_SELECTED\x10\x00\x12\x30\n,PARK_EVENT_PICTURE_SELECTION_STATUS_SELECTED\x10\x01*\x9d\x01\n\x1dParkCollisionActivationStatus\x12(\n$PARK_COLLISION_ACTIVATION_STATUS_OFF\x10\x00\x12\'\n#PARK_COLLISION_ACTIVATION_STATUS_ON\x10\x01\x12)\n%PARK_COLLISION_ACTIVATION_STATUS_INIT\x10\x02*\xf7\x02\n\x1a\x43hargingCompatibilityError\x12(\n$CHARGING_COMPATIBILITY_ERROR_DEFAULT\x10\x00\x12\x33\n/CHARGING_COMPATIBILITY_ERROR_FULL_COMPATIBILITY\x10\x01\x12L\nHCHARGING_COMPATIBILITY_ERROR_FULL_COMPATIBILITY_WITH_ADDITIONAL_HARDWARE\x10\x02\x12\x30\n,CHARGING_COMPATIBILITY_PARTIAL_COMPATIBILITY\x10\x03\x12G\nCCHARGING_COMPATIBILITY_PARTIAL_COMPATIBILITY_WITH_ADDITIONAL_DEVICE\x10\x04\x12\x31\n-CHARGING_COMPATIBILITY_ERROR_NO_COMPATIBILITY\x10\x05*\xa6\x03\n\x18\x43hargingFlapErrorDetails\x12\x38\n4CHARGING_FLAP_ERROR_DETAILS_NO_INFO_OR_ERROR_MESSAGE\x10\x00\x12>\n:CHARGING_FLAP_ERROR_DETAILS_OPENING_DEFECT_SEARCH_WORKSHOP\x10\x01\x12\'\n#CHARGING_FLAP_ERROR_DETAILS_BLOCKED\x10\x02\x12<\n8CHARGING_FLAP_ERROR_DETAILS_DRIVING_POSITION_NOT_PARKING\x10\x03\x12-\n)CHARGING_FLAP_ERROR_DETAILS_STATE_UNKNOWN\x10\x04\x12\x38\n4CHARGING_FLAP_ERROR_DETAILS_PRESSED_DETECTION_DEFECT\x10\x05\x12@\n\n:CHARGING_POWER_RESTRICTION_REDUCED_DUE_TO_CUSTOMER_SETTING\x10\x02\x12\x45\nACHARGING_POWER_RESTRICTION_REDUCED_DUE_TO_VEHICLE_CHARGING_SYSTEM\x10\x03\x12<\n8CHARGING_POWER_RESTRICTION_REDUCED_DUE_TO_REMOTE_CONTROL\x10\x04\x12\x45\nACHARGING_POWER_RESTRICTION_REDUCED_DUE_TO_CHARGING_INFRASTRUCTURE\x10\x05\x12?\n;CHARGING_POWER_RESTRICTION_REDUCED_DUE_TO_CHARGING_STRATEGY\x10\x06\x12\x36\n2CHARGING_POWER_RESTRICTION_STATE_OF_CHARGE_TOO_LOW\x10\x07\x12\x37\n3CHARGING_POWER_RESTRICTION_STATE_OF_CHARGE_TOO_HIGH\x10\x08\x12:\n6CHARGING_POWER_RESTRICTION_BATTERY_TEMPERATURE_TOO_LOW\x10\t\x12;\n7CHARGING_POWER_RESTRICTION_BATTERY_TEMPERATURE_TOO_HIGH\x10\n*\xce\x02\n\rBatteryHealth\x12\x17\n\x13\x42\x41TTERY_GREEN_STATE\x10\x00\x12\x18\n\x14\x42\x41TTERY_YELLOW_STATE\x10\x01\x12\x15\n\x11\x42\x41TTERY_RED_STATE\x10\x02\x12\x1e\n\x1aISSUE_WITH_DATA_EVALUATION\x10\x03\x12\x1a\n\x16NO_EVALUATION_POSSIBLE\x10\x04\x12\x13\n\x0f\x42\x41TTERY_CHANGED\x10\x05\x12\'\n#BATTERY_HEALTH_CANNOT_BE_CALCULATED\x10\x06\x12\x1a\n\x16NO_MB_ORIGINAL_BATTERY\x10\x07\x12%\n!TECHNICAL_LIMITATION_FROM_VEHICLE\x10\x08\x12\x1b\n\x17GENERAL_TECHNICAL_ERROR\x10\t\x12\x19\n\x15GENERAL_PROCESS_ERROR\x10\n*\xb1\x01\n\x10PrecondStateType\x12 \n\x1cPRECOND_STATE_TYPE_ON_UNLOCK\x10\x00\x12(\n$PRECOND_STATE_TYPE_AT_DEPARTURE_TIME\x10\x01\x12 \n\x1cPRECOND_STATE_TYPE_IMMEDIATE\x10\x02\x12/\n+PRECOND_STATE_TYPE_CHILD_PRESENCE_DETECTION\x10\x03*y\n\rChargeProgram\x12\x1a\n\x16\x44\x45\x46\x41ULT_CHARGE_PROGRAM\x10\x00\x12\x1a\n\x16INSTANT_CHARGE_PROGRAM\x10\x01\x12\x17\n\x13HOME_CHARGE_PROGRAM\x10\x02\x12\x17\n\x13WORK_CHARGE_PROGRAM\x10\x03*f\n\x0f\x41ttributeStatus\x12\x0f\n\x0bVALUE_VALID\x10\x00\x12\x16\n\x12VALUE_NOT_RECEIVED\x10\x01\x12\x11\n\rVALUE_INVALID\x10\x03\x12\x17\n\x13VALUE_NOT_AVAILABLE\x10\x04*g\n\x05Scope\x12\x08\n\x04USER\x10\x00\x12\x12\n\x0eONBOARD_FENCES\x10\x01\x12\x0c\n\x08USER_PIN\x10\x03\x12\x18\n\x14SERVICE_PREREQUISITE\x10\x04\x12\x18\n\x14USER_PROFILE_PICTURE\x10\x05*8\n\nDoorstatus\x12\x15\n\x11\x44OORSTATUS_CLOSED\x10\x00\x12\x13\n\x0f\x44OORSTATUS_OPEN\x10\x01*H\n\x0e\x44oorlockstatus\x12\x19\n\x15\x44OORLOCKSTATUS_LOCKED\x10\x00\x12\x1b\n\x17\x44OORLOCKSTATUS_UNLOCKED\x10\x01*\xbf\x01\n\x15\x44oorlockstatusvehicle\x12"\n\x1e\x44OORLOCKSTATUSVEHICLE_UNLOCKED\x10\x00\x12)\n%DOORLOCKSTATUSVEHICLE_INTERNAL_LOCKED\x10\x01\x12)\n%DOORLOCKSTATUSVEHICLE_EXTERNAL_LOCKED\x10\x02\x12,\n(DOORLOCKSTATUSVEHICLE_SELECTIVE_UNLOCKED\x10\x03*\x85\x01\n\x11\x44oorStatusOverall\x12%\n!DOOR_STATUS_OVERALL_ANY_DOOR_OPEN\x10\x00\x12(\n$DOOR_STATUS_OVERALL_ALL_DOORS_CLOSED\x10\x01\x12\x1f\n\x1b\x44OOR_STATUS_OVERALL_UNKNOWN\x10\x03*Z\n\rDoorstatusgas\x12\x18\n\x14\x44OORSTATUSGAS_CLOSED\x10\x00\x12\x16\n\x12\x44OORSTATUSGAS_OPEN\x10\x01\x12\x17\n\x13\x44OORSTATUSGAS_ERROR\x10\x02*\xd3\x05\n\x0e\x43hargingstatus\x12\x1b\n\x17\x43HARGINGSTATUS_CHARGING\x10\x00\x12 \n\x1c\x43HARGINGSTATUS_END_OF_CHARGE\x10\x01\x12\x1f\n\x1b\x43HARGINGSTATUS_CHARGE_BREAK\x10\x02\x12)\n%CHARGINGSTATUS_CHARGE_CABLE_UNPLUGGED\x10\x03\x12!\n\x1d\x43HARGINGSTATUS_CHARGING_ERROR\x10\x04\x12 \n\x1c\x43HARGINGSTATUS_SLOW_CHARGING\x10\x05\x12 \n\x1c\x43HARGINGSTATUS_FAST_CHARGING\x10\x06\x12\x1e\n\x1a\x43HARGINGSTATUS_DISCHARGING\x10\x07\x12\x1e\n\x1a\x43HARGINGSTATUS_NO_CHARGING\x10\x08\x12;\n7CHARGINGSTATUS_SLOW_CHARGING_AFTER_REACHING_TRIP_TARGET\x10\t\x12\x36\n2CHARGINGSTATUS_CHARGING_AFTER_REACHING_TRIP_TARGET\x10\n\x12;\n7CHARGINGSTATUS_FAST_CHARGING_AFTER_REACHING_TRIP_TARGET\x10\x0b\x12@\n\n\nPrecondNow\x12\x18\n\x14PRECOND_NOW_INACTIVE\x10\x00\x12\x16\n\x12PRECOND_NOW_ACTIVE\x10\x01*\x9e\x01\n\x14PrecondOperatingMode\x12\x1e\n\x1aPRECOND_OPERATING_MODE_OFF\x10\x00\x12\x1f\n\x1bPRECOND_OPERATING_MODE_HEAT\x10\x01\x12\x1f\n\x1bPRECOND_OPERATING_MODE_COOL\x10\x02\x12$\n PRECOND_OPERATING_MODE_VENTILATE\x10\x03*T\n\x12Precondatdeparture\x12\x1f\n\x1bPRECONDATDEPARTURE_INACTIVE\x10\x00\x12\x1d\n\x19PRECONDATDEPARTURE_ACTIVE\x10\x01*8\n\x0bPrecondSeat\x12\x14\n\x10PRECOND_SEAT_OFF\x10\x00\x12\x13\n\x0fPRECOND_SEAT_ON\x10\x01*\x93\x02\n\rAuxheatstatus\x12\x1a\n\x16\x41UXHEATSTATUS_INACTIVE\x10\x00\x12%\n!AUXHEATSTATUS_HEATING_NORMAL_MODE\x10\x01\x12)\n%AUXHEATSTATUS_VENTILATING_NORMAL_MODE\x10\x02\x12 \n\x1c\x41UXHEATSTATUS_HEATING_MANUAL\x10\x03\x12&\n"AUXHEATSTATUS_POST_RUNNING_HEATING\x10\x04\x12*\n&AUXHEATSTATUS_POST_RUNNING_VENTILATING\x10\x05\x12\x1e\n\x1a\x41UXHEATSTATUS_HEATING_AUTO\x10\x06*\x9f\x01\n\x14\x41uxheattimeselection\x12!\n\x1d\x41UXHEATTIMESELECTION_NO_TIMER\x10\x00\x12 \n\x1c\x41UXHEATTIMESELECTION_TIMER_1\x10\x01\x12 \n\x1c\x41UXHEATTIMESELECTION_TIMER_2\x10\x02\x12 \n\x1c\x41UXHEATTIMESELECTION_TIMER_3\x10\x03*m\n\x0e\x41uxheatwarning\x12\x17\n\x13\x41UXHEATWARNING_NONE\x10\x00\x12\x1f\n\x1b\x41UXHEATWARNING_CONFIRMATION\x10\x01\x12!\n\x1d\x41UXHEATWARNING_CONFIRMATION_2\x10\x02*\xd6\x01\n\x11\x44\x65partureTimeMode\x12 \n\x1c\x44\x45PARTURE_TIME_MODE_INACTIVE\x10\x00\x12$\n DEPARTURE_TIME_MODE_ADHOC_ACTIVE\x10\x01\x12(\n$DEPARTURE_TIME_MODE_WEEKLYSET_ACTIVE\x10\x02\x12"\n\x1e\x44\x45PARTURE_TIME_MODE_TIMER_ACTV\x10\x03\x12+\n\'DEPARTURE_TIME_MODE_INTELLIGENT_DP_ACTV\x10\x04*\x9d\x01\n\x07Weekday\x12\x12\n\x0eWEEKDAY_MONDAY\x10\x00\x12\x13\n\x0fWEEKDAY_TUESDAY\x10\x01\x12\x15\n\x11WEEKDAY_WEDNESDAY\x10\x02\x12\x14\n\x10WEEKDAY_THURSDAY\x10\x03\x12\x12\n\x0eWEEKDAY_FRIDAY\x10\x04\x12\x14\n\x10WEEKDAY_SATURDAY\x10\x05\x12\x12\n\x0eWEEKDAY_SUNDAY\x10\x06*X\n\x13RangeSkipIndication\x12!\n\x1dRANGE_SKIP_INDICATION_DISPLAY\x10\x00\x12\x1e\n\x1aRANGE_SKIP_INDICATION_SKIP\x10\x01*~\n\x15\x46ilterParticleLoading\x12 \n\x1c\x46ILTER_PARTICLE_LOADING_HIGH\x10\x00\x12"\n\x1e\x46ILTER_PARTICLE_LOADING_MEDIUM\x10\x01\x12\x1f\n\x1b\x46ILTER_PARTICLE_LOADING_LOW\x10\x02*\xec\x07\n\nLanguageHU\x12\x16\n\x12LANGUAGE_HU_GERMAN\x10\x00\x12\x1b\n\x17LANGUAGE_HU_ENGLISH_IMP\x10\x01\x12\x16\n\x12LANGUAGE_HU_FRENCH\x10\x02\x12\x17\n\x13LANGUAGE_HU_ITALIAN\x10\x03\x12\x17\n\x13LANGUAGE_HU_SPANISH\x10\x04\x12\x18\n\x14LANGUAGE_HU_JAPANESE\x10\x05\x12\x1b\n\x17LANGUAGE_HU_ENGLISH_MET\x10\x06\x12\x15\n\x11LANGUAGE_HU_DUTCH\x10\x07\x12\x16\n\x12LANGUAGE_HU_DANISH\x10\x08\x12\x17\n\x13LANGUAGE_HU_SWEDISH\x10\t\x12\x17\n\x13LANGUAGE_HU_TURKISH\x10\n\x12\x1a\n\x16LANGUAGE_HU_PORTUGUESE\x10\x0b\x12\x17\n\x13LANGUAGE_HU_RUSSIAN\x10\x0c\x12\x16\n\x12LANGUAGE_HU_ARABIC\x10\r\x12\x17\n\x13LANGUAGE_HU_CHINESE\x10\x0e\x12\x1a\n\x16LANGUAGE_HU_ENGLISH_AM\x10\x0f\x12\x1c\n\x18LANGUAGE_HU_TRAD_CHINESE\x10\x10\x12\x16\n\x12LANGUAGE_HU_KOREAN\x10\x11\x12\x17\n\x13LANGUAGE_HU_FINNISH\x10\x12\x12\x16\n\x12LANGUAGE_HU_POLISH\x10\x13\x12\x15\n\x11LANGUAGE_HU_CZECH\x10\x14\x12!\n\x1dLANGUAGE_HU_PORTUGUESE_BRAZIL\x10\x15\x12\x19\n\x15LANGUAGE_HU_NORWEGIAN\x10\x16\x12\x14\n\x10LANGUAGE_HU_THAI\x10\x17\x12\x1a\n\x16LANGUAGE_HU_INDONESIAN\x10\x18\x12\x19\n\x15LANGUAGE_HU_BULGARIAN\x10\x19\x12\x19\n\x15LANGUAGE_HU_SLOVAKIAN\x10\x1a\x12\x18\n\x14LANGUAGE_HU_CROATIAN\x10\x1b\x12\x17\n\x13LANGUAGE_HU_SERBIAN\x10\x1c\x12\x19\n\x15LANGUAGE_HU_HUNGARIAN\x10\x1d\x12\x19\n\x15LANGUAGE_HU_UKRAINIAN\x10\x1e\x12\x17\n\x13LANGUAGE_HU_MALAYAN\x10\x1f\x12\x1a\n\x16LANGUAGE_HU_VIETNAMESE\x10 \x12\x18\n\x14LANGUAGE_HU_ROMANIAN\x10!\x12\x1f\n\x1bLANGUAGE_HU_TRAD_CHINESE_TW\x10"\x12\x16\n\x12LANGUAGE_HU_HEBREW\x10#\x12\x15\n\x11LANGUAGE_HU_GREEK\x10$\x12\x19\n\x15LANGUAGE_HU_SLOVENIAN\x10%*J\n\x0fSpeedUnitFromIC\x12\x1b\n\x17SPEED_UNIT_FROM_IC_KM_H\x10\x00\x12\x1a\n\x16SPEED_UNIT_FROM_IC_MPH\x10\x01*X\n\x11TemperatureUnitHU\x12\x1f\n\x1bTEMPERATURE_UNIT_HU_CELSIUS\x10\x00\x12"\n\x1eTEMPERATURE_UNIT_HU_FAHRENHEIT\x10\x01*H\n\x0cTimeFormatHU\x12\x1b\n\x17TIME_FORMAT_HU_12_HOURS\x10\x00\x12\x1b\n\x17TIME_FORMAT_HU_24_HOURS\x10\x01*F\n\x0fTrackingStateHu\x12\x19\n\x15TRACKING_STATE_HU_OFF\x10\x00\x12\x18\n\x14TRACKING_STATE_HU_ON\x10\x01*y\n\x1aVehicleDataConnectionState\x12.\n*VEHICLE_DATA_CONNECTION_STATE_DISCONNECTED\x10\x00\x12+\n\'VEHICLE_DATA_CONNECTION_STATE_CONNECTED\x10\x01*w\n\x13VehicleHealthStatus\x12\x1f\n\x1bVEHICLE_HEALTH_STATUS_GREEN\x10\x00\x12 \n\x1cVEHICLE_HEALTH_STATUS_YELLOW\x10\x01\x12\x1d\n\x19VEHICLE_HEALTH_STATUS_RED\x10\x02*\xa5\x01\n\x0b\x44rivingMode\x12\x18\n\x14\x44RIVING_MODE_UNKNOWN\x10\x00\x12\x14\n\x10\x44RIVING_MODE_OFF\x10\x01\x12\x13\n\x0f\x44RIVING_MODE_ON\x10\x02\x12\x1c\n\x18\x44RIVING_MODE_PENDING_OFF\x10\x03\x12\x1b\n\x17\x44RIVING_MODE_PENDING_ON\x10\x04\x12\x16\n\x12\x44RIVING_MODE_ERROR\x10\x05*\x91\x01\n\x0fOilWarningLevel\x12\x1e\n\x1aOIL_WARNING_LEVEL_OVERFILL\x10\x00\x12\x18\n\x14OIL_WARNING_LEVEL_OK\x10\x01\x12\x1f\n\x1bOIL_WARNING_LEVEL_UNDERFILL\x10\x02\x12#\n\x1fOIL_WARNING_LEVEL_NOT_AVAILABLE\x10\x03*b\n\x0eParkEventLevel\x12\x18\n\x14PARK_EVENT_LEVEL_LOW\x10\x00\x12\x1b\n\x17PARK_EVENT_LEVEL_MEDIUM\x10\x01\x12\x19\n\x15PARK_EVENT_LEVEL_HIGH\x10\x02*\xc8\x02\n\rParkEventType\x12\x18\n\x14PARK_EVENT_TYPE_IDLE\x10\x00\x12\x1e\n\x1aPARK_EVENT_TYPE_FRONT_LEFT\x10\x01\x12 \n\x1cPARK_EVENT_TYPE_FRONT_MIDDLE\x10\x02\x12\x1f\n\x1bPARK_EVENT_TYPE_FRONT_RIGHT\x10\x03\x12\x19\n\x15PARK_EVENT_TYPE_RIGHT\x10\x04\x12\x1e\n\x1aPARK_EVENT_TYPE_REAR_RIGHT\x10\x05\x12\x1f\n\x1bPARK_EVENT_TYPE_REAR_MIDDLE\x10\x06\x12\x1d\n\x19PARK_EVENT_TYPE_REAR_LEFT\x10\x07\x12\x18\n\x14PARK_EVENT_TYPE_LEFT\x10\x08\x12%\n!PARK_EVENT_TYPE_DIRECTION_UNKNOWN\x10\t*\xa2\x01\n\x15ParkEventSensorStatus\x12\x30\n,PARK_EVENT_SENSOR_STATUS_NOT_ACTIVE_SELECTED\x10\x00\x12\x32\n.PARK_EVENT_SENSOR_STATUS_NOT_ACTIVE_UNSELECTED\x10\x01\x12#\n\x1fPARK_EVENT_SENSOR_STATUS_ACTIVE\x10\x02*Q\n\x10Warningwashwater\x12\x1d\n\x19WARNINGWASHWATER_INACTIVE\x10\x00\x12\x1e\n\x1aWARNINGWASHWATER_TRIGGERED\x10\x01*\xf3\x02\n\x0eHybridWarnings\x12\x18\n\x14HYBRID_WARNINGS_NONE\x10\x00\x12 \n\x1cHYBRID_WARNINGS_SEEK_SERVICE\x10\x01\x12&\n"HYBRID_WARNINGS_HIGH_VOLTAGE_FAULT\x10\x02\x12%\n!HYBRID_WARNINGS_POWER_TRAIN_FAULT\x10\x03\x12#\n\x1fHYBRID_WARNINGS_STARTER_BATTERY\x10\x04\x12 \n\x1cHYBRID_WARNINGS_STOP_VEHICLE\x10\x05\x12\x1f\n\x1bHYBRID_WARNINGS_PLUGIN_ONLY\x10\x06\x12\'\n#HYBRID_WARNINGS_PLUGIN_STILL_ACTIVE\x10\x07\x12 \n\x1cHYBRID_WARNINGS_POWER_REDUCE\x10\x08\x12#\n\x1fHYBRID_WARNINGS_STOP_ENGINE_OFF\x10\t*\xcd\t\n\x16LastTheftWarningReason\x12&\n"LAST_THEFT_WARNING_REASON_NO_ALARM\x10\x00\x12)\n%LAST_THEFT_WARNING_REASON_BASIS_ALARM\x10\x10\x12-\n)LAST_THEFT_WARNING_REASON_DOOR_FRONT_LEFT\x10\x11\x12.\n*LAST_THEFT_WARNING_REASON_DOOR_FRONT_RIGHT\x10\x12\x12,\n(LAST_THEFT_WARNING_REASON_DOOR_REAR_LEFT\x10\x13\x12-\n)LAST_THEFT_WARNING_REASON_DOOR_REAR_RIGHT\x10\x14\x12"\n\x1eLAST_THEFT_WARNING_REASON_HOOD\x10\x15\x12%\n!LAST_THEFT_WARNING_REASON_DECKLID\x10\x16\x12+\n\'LAST_THEFT_WARNING_REASON_COMMON_ALM_IN\x10\x17\x12#\n\x1fLAST_THEFT_WARNING_REASON_PANIC\x10\x1a\x12&\n"LAST_THEFT_WARNING_REASON_GLOVEBOX\x10\x1b\x12\'\n#LAST_THEFT_WARNING_REASON_CENTERBOX\x10\x1c\x12%\n!LAST_THEFT_WARNING_REASON_REARBOX\x10\x1d\x12)\n%LAST_THEFT_WARNING_REASON_FLIP_WINDOW\x10\x1e\x12(\n$LAST_THEFT_WARNING_REASON_SENSOR_VTA\x10 \x12!\n\x1dLAST_THEFT_WARNING_REASON_ITS\x10!\x12%\n!LAST_THEFT_WARNING_REASON_ITS_SLV\x10"\x12!\n\x1dLAST_THEFT_WARNING_REASON_TPS\x10#\x12#\n\x1fLAST_THEFT_WARNING_REASON_SIREN\x10$\x12&\n"LAST_THEFT_WARNING_REASON_HOLD_COM\x10%\x12$\n LAST_THEFT_WARNING_REASON_REMOTE\x10&\x12\'\n#LAST_THEFT_WARNING_REASON_EXT_ITS_1\x10*\x12\'\n#LAST_THEFT_WARNING_REASON_EXT_ITS_2\x10+\x12\'\n#LAST_THEFT_WARNING_REASON_EXT_ITS_3\x10,\x12\'\n#LAST_THEFT_WARNING_REASON_EXT_ITS_4\x10-\x12.\n*LAST_THEFT_WARNING_REASON_CHILD_PRESENCE_1\x10.\x12.\n*LAST_THEFT_WARNING_REASON_CHILD_PRESENCE_2\x10/\x12-\n)LAST_THEFT_WARNING_REASON_CENTRAL_LOCKING\x10\x30\x12\'\n#LAST_THEFT_WARNING_REASON_AMBIGUOUS\x10<*\xad\x01\n HvBatteryThermalPropagationEvent\x12-\n)HV_BATTERY_THERMAL_PROPAGATION_NO_WARNING\x10\x00\x12,\n(HV_BATTERY_THERMAL_PROPAGATION_WARNING_1\x10\x01\x12,\n(HV_BATTERY_THERMAL_PROPAGATION_WARNING_2\x10\x02*\xc1\x01\n\x13StarterBatteryState\x12\x1f\n\x1bSTARTER_BATTERY_STATE_GREEN\x10\x00\x12 \n\x1cSTARTER_BATTERY_STATE_YELLOW\x10\x01\x12\x1d\n\x19STARTER_BATTERY_STATE_RED\x10\x02\x12 \n\x1cSTARTER_BATTERY_STATE_ORANGE\x10\x03\x12&\n"STARTER_BATTERY_STATE_GREEN_YELLOW\x10\x04*\xa1\x02\n\x18VehiclePositionErrorCode\x12\'\n#VEHICLE_POSITION_ERROR_CODE_UNKNOWN\x10\x00\x12\x30\n,VEHICLE_POSITION_ERROR_CODE_SERVICE_INACTIVE\x10\x01\x12\x31\n-VEHICLE_POSITION_ERROR_CODE_TRACKING_INACTIVE\x10\x02\x12&\n"VEHICLE_POSITION_ERROR_CODE_PARKED\x10\x03\x12+\n\'VEHICLE_POSITION_ERROR_CODE_IGNITION_ON\x10\x04\x12"\n\x1eVEHICLE_POSITION_ERROR_CODE_OK\x10\x05*s\n\x12\x43\x61librationRequest\x12"\n\x1e\x43\x41LIBRATION_REQUEST_NO_REQUEST\x10\x00\x12\x1b\n\x17\x43\x41LIBRATION_REQUEST_LOW\x10\x01\x12\x1c\n\x18\x43\x41LIBRATION_REQUEST_HIGH\x10\x02*\x88\x05\n\x11\x41ssystOilQuantity\x12&\n"ASSYST_OIL_QUANTITY_NO_MEASUREMENT\x10\x00\x12\x35\n1ASSYST_OIL_QUANTITY_NO_MEASUREMENT_ENGINE_RUNNING\x10\x01\x12/\n+ASSYST_OIL_QUANTITY_MEASUREMENT_IGNITION_ON\x10\x02\x12\x1c\n\x18\x41SSYST_OIL_QUANTITY_WAIT\x10\x03\x12*\n&ASSYST_OIL_QUANTITY_MEASUREMENT_ACTIVE\x10\x04\x12\x1e\n\x1a\x41SSYST_OIL_QUANTITY_OIL_OK\x10\x05\x12#\n\x1f\x41SSYST_OIL_QUANTITY_OIL_REDUCED\x10\x06\x12#\n\x1f\x41SSYST_OIL_QUANTITY_REFILL_1LTR\x10\x07\x12%\n!ASSYST_OIL_QUANTITY_REFILL_1_5LTR\x10\x08\x12#\n\x1f\x41SSYST_OIL_QUANTITY_REFILL_2LTR\x10\t\x12%\n!ASSYST_OIL_QUANTITY_REFILL_0_5LTR\x10\n\x12-\n)ASSYST_OIL_QUANTITY_ENGINE_START_REQUIRED\x10\x0b\x12.\n*ASSYST_OIL_QUANTITY_ENGINE_WARMUP_REQUIRED\x10\x0c\x12.\n*ASSYST_OIL_QUANTITY_VEHICLE_NOT_HORIZONTAL\x10\r\x12-\n)ASSYST_OIL_QUANTITY_NO_MEASUREMENT_RESULT\x10\x0e*\x81\x02\n\x10\x41ssystOilWarning\x12\x1b\n\x17\x41SSYST_OIL_WARNING_IDLE\x10\x00\x12!\n\x1d\x41SSYST_OIL_WARNING_REFILL_LTR\x10\x01\x12"\n\x1e\x41SSYST_OIL_WARNING_NOT_DEFINED\x10\x02\x12!\n\x1d\x41SSYST_OIL_WARNING_OVERFILL_1\x10\x03\x12#\n\x1f\x41SSYST_OIL_WARNING_SENSOR_FAULT\x10\x04\x12 \n\x1c\x41SSYST_OIL_WARNING_SWTCH_MIN\x10\x05\x12\x1f\n\x1b\x41SSYST_OIL_WARNING_ENG_STOP\x10\x06*\x8e\x01\n\x1aProtectionActivationStatus\x12$\n PROTECTION_ACTIVATION_STATUS_OFF\x10\x00\x12#\n\x1fPROTECTION_ACTIVATION_STATUS_ON\x10\x01\x12%\n!PROTECTION_ACTIVATION_STATUS_INIT\x10\x02*f\n\x16ProtectionSensorStatus\x12\'\n#PROTECTION_SENSOR_STATUS_NOT_ACTIVE\x10\x00\x12#\n\x1fPROTECTION_SENSOR_STATUS_ACTIVE\x10\x01*\xa8\x02\n\x1cTcuConnectionStateLowChannel\x12,\n(TCU_CONNECTION_STATE_LOW_CHANNEL_UNKNOWN\x10\x00\x12\x38\n4TCU_CONNECTION_STATE_LOW_CHANNEL_INITIALLY_CONNECTED\x10\x01\x12\x30\n,TCU_CONNECTION_STATE_LOW_CHANNEL_RECONNECTED\x10\x02\x12\x31\n-TCU_CONNECTION_STATE_LOW_CHANNEL_DISCONNECTED\x10\x03\x12;\n7TCU_CONNECTION_STATE_LOW_CHANNEL_UNPLANNED_DISCONNECTED\x10\x04*{\n\x11TcuThermoShutDown\x12 \n\x1cTCU_THERMO_SHUT_DOWN_UNKNOWN\x10\x00\x12#\n\x1fTCU_THERMO_SHUT_DOWN_NOT_ACTIVE\x10\x01\x12\x1f\n\x1bTCU_THERMO_SHUT_DOWN_ACTIVE\x10\x02*\xb5\x01\n\x12KeyActivationState\x12 \n\x1cKEY_ACTIVATION_STATE_UNKNOWN\x10\x00\x12#\n\x1fKEY_ACTIVATION_STATE_ALL_ACTIVE\x10\x01\x12.\n*KEY_ACTIVATION_STATE_SELECTIVE_DEACTIVATED\x10\x02\x12(\n$KEY_ACTIVATION_STATE_ALL_DEACTIVATED\x10\x03*\x84\x01\n\x1ePictureTransferSelectionStatus\x12\x32\n.PICTURE_TRANSFER_SELECTION_STATUS_NOT_SELECTED\x10\x00\x12.\n*PICTURE_TRANSFER_SELECTION_STATUS_SELECTED\x10\x01\x42\x1c\n\x1a\x63om.daimler.mbcarkit.protob\x06proto3' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "vehicle_events_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals["DESCRIPTOR"]._serialized_options = b"\n\032com.daimler.mbcarkit.proto" _globals["_VEPUPDATE_ATTRIBUTESENTRY"]._loaded_options = None _globals["_VEPUPDATE_ATTRIBUTESENTRY"]._serialized_options = b"8\001" _globals["_VEHICLEATTRIBUTESTATUS_SPEEDDISTANCEUNIT"]._loaded_options = None _globals["_VEHICLEATTRIBUTESTATUS_SPEEDDISTANCEUNIT"]._serialized_options = b"\030\001" _globals["_VEHICLEATTRIBUTESTATUS"].fields_by_name["timestamp"]._loaded_options = None _globals["_VEHICLEATTRIBUTESTATUS"].fields_by_name["timestamp"]._serialized_options = b"\030\001" _globals["_VEHICLEATTRIBUTESTATUS"].fields_by_name["speed_distance_unit"]._loaded_options = None _globals["_VEHICLEATTRIBUTESTATUS"].fields_by_name["speed_distance_unit"]._serialized_options = b"\030\001" _globals["_CHARGINGSCHEDULEACTIVE_CHARGINGSCHEDULEACTIVEUSECASEID"]._loaded_options = None _globals["_CHARGINGSCHEDULEACTIVE_CHARGINGSCHEDULEACTIVEUSECASEID"]._serialized_options = b"\030\001" _globals["_CHARGINGSCHEDULEACTIVE"].fields_by_name["schedule_id_deprecated"]._loaded_options = None _globals["_CHARGINGSCHEDULEACTIVE"].fields_by_name["schedule_id_deprecated"]._serialized_options = b"\030\001" _globals["_CHARGINGSCHEDULEACTIVE"].fields_by_name["use_case_id_deprecated"]._loaded_options = None _globals["_CHARGINGSCHEDULEACTIVE"].fields_by_name["use_case_id_deprecated"]._serialized_options = b"\030\001" _globals["_VEPUPDATESBYVIN_UPDATESENTRY"]._loaded_options = None _globals["_VEPUPDATESBYVIN_UPDATESENTRY"]._serialized_options = b"8\001" _globals["_VEHICLESTATUS_ATTRIBUTESENTRY"]._loaded_options = None _globals["_VEHICLESTATUS_ATTRIBUTESENTRY"]._serialized_options = b"8\001" _globals["_TRACKINGEVENT_PAYLOADENTRY"]._loaded_options = None _globals["_TRACKINGEVENT_PAYLOADENTRY"]._serialized_options = b"8\001" _globals["_ACKNOWLEDGEVEPREQUEST"]._loaded_options = None _globals["_ACKNOWLEDGEVEPREQUEST"]._serialized_options = b"\030\001" _globals["_SCOPES_ADDITIONALRESOURCESENTRY"]._loaded_options = None _globals["_SCOPES_ADDITIONALRESOURCESENTRY"]._serialized_options = b"8\001" _globals["_VEHICLESTATUSUPDATES_VEHICLESTATUSUPDATESENTRY"]._loaded_options = None _globals["_VEHICLESTATUSUPDATES_VEHICLESTATUSUPDATESENTRY"]._serialized_options = b"8\001" _globals["_AMGSTAGEMODESTATE"]._serialized_start = 58203 _globals["_AMGSTAGEMODESTATE"]._serialized_end = 58488 _globals["_CHILDPRESENCEDETECTIONWARNINGLEVEL"]._serialized_start = 58491 _globals["_CHILDPRESENCEDETECTIONWARNINGLEVEL"]._serialized_end = 58927 _globals["_CHILDPRESENCEDETECTIONWARNINGLASTEVENT"]._serialized_start = 58930 _globals["_CHILDPRESENCEDETECTIONWARNINGLASTEVENT"]._serialized_end = 59468 _globals["_KEYLINEACTIVATIONSTATES"]._serialized_start = 59470 _globals["_KEYLINEACTIVATIONSTATES"]._serialized_end = 59597 _globals["_PERFORMANCELIMITATIONMODESTATUS"]._serialized_start = 59600 _globals["_PERFORMANCELIMITATIONMODESTATUS"]._serialized_end = 59783 _globals["_EXTERIORMONITORINGSTATUS"]._serialized_start = 59786 _globals["_EXTERIORMONITORINGSTATUS"]._serialized_end = 60084 _globals["_INTERIORMONITORINGSTATUS"]._serialized_start = 60087 _globals["_INTERIORMONITORINGSTATUS"]._serialized_end = 60410 _globals["_UPDATESTATUS"]._serialized_start = 60413 _globals["_UPDATESTATUS"]._serialized_end = 60622 _globals["_SOHCALIBRATIONPLANNED"]._serialized_start = 60624 _globals["_SOHCALIBRATIONPLANNED"]._serialized_end = 60709 _globals["_DCCHARGINGPROFILE"]._serialized_start = 60712 _globals["_DCCHARGINGPROFILE"]._serialized_end = 60977 _globals["_PARKEVENTPICTURETRANSMISSIONSTATUS"]._serialized_start = 60980 _globals["_PARKEVENTPICTURETRANSMISSIONSTATUS"]._serialized_end = 61394 _globals["_CHARGINGSCHEDULEUSECASEID"]._serialized_start = 61397 _globals["_CHARGINGSCHEDULEUSECASEID"]._serialized_end = 63208 _globals["_SCHEDULEIDSTATUS"]._serialized_start = 63210 _globals["_SCHEDULEIDSTATUS"]._serialized_end = 63293 _globals["_SOCCALIBRATIONREQUEST"]._serialized_start = 63296 _globals["_SOCCALIBRATIONREQUEST"]._serialized_end = 63442 _globals["_SOHFAVORABLECONDITIONS"]._serialized_start = 63445 _globals["_SOHFAVORABLECONDITIONS"]._serialized_end = 63611 _globals["_CHARGINGSTOPERRORDETAILS"]._serialized_start = 63614 _globals["_CHARGINGSTOPERRORDETAILS"]._serialized_end = 63757 _globals["_SOHCALIBRATIONSTATE"]._serialized_start = 63760 _globals["_SOHCALIBRATIONSTATE"]._serialized_end = 64398 _globals["_SOHCALIBRATIONREQUIRED"]._serialized_start = 64400 _globals["_SOHCALIBRATIONREQUIRED"]._serialized_end = 64488 _globals["_SOHCALIBRATIONREQUEST"]._serialized_start = 64491 _globals["_SOHCALIBRATIONREQUEST"]._serialized_end = 64637 _globals["_TURNOFFENGINEPREWARNING"]._serialized_start = 64640 _globals["_TURNOFFENGINEPREWARNING"]._serialized_end = 64783 _globals["_SOHCALIBRATIONNOTIFICATIONS"]._serialized_start = 64786 _globals["_SOHCALIBRATIONNOTIFICATIONS"]._serialized_end = 65123 _globals["_HVBATTERYPRECONDSTATESDISCHARGING"]._serialized_start = 65126 _globals["_HVBATTERYPRECONDSTATESDISCHARGING"]._serialized_end = 65483 _globals["_HVBATTERYPRECONDSTATESCHARGING"]._serialized_start = 65486 _globals["_HVBATTERYPRECONDSTATESCHARGING"]._serialized_end = 65821 _globals["_MAINCATEGORY"]._serialized_start = 65824 _globals["_MAINCATEGORY"]._serialized_end = 66019 _globals["_SUBCATEGORY"]._serialized_start = 66021 _globals["_SUBCATEGORY"]._serialized_end = 66099 _globals["_SPECIFICCATEGORY"]._serialized_start = 66101 _globals["_SPECIFICCATEGORY"]._serialized_end = 66196 _globals["_METHOD"]._serialized_start = 66199 _globals["_METHOD"]._serialized_end = 66360 _globals["_STATUS"]._serialized_start = 66363 _globals["_STATUS"]._serialized_end = 66512 _globals["_HVBATTERYPRECONDAVAILABILITY"]._serialized_start = 66515 _globals["_HVBATTERYPRECONDAVAILABILITY"]._serialized_end = 67085 _globals["_EVSEPAIRINGSTATE"]._serialized_start = 67088 _globals["_EVSEPAIRINGSTATE"]._serialized_end = 67569 _globals["_EMERGENCYPOWERSUPPLY"]._serialized_start = 67571 _globals["_EMERGENCYPOWERSUPPLY"]._serialized_end = 67656 _globals["_PARKCOLLISIONPICTURETRANSFERSTATUS"]._serialized_start = 67659 _globals["_PARKCOLLISIONPICTURETRANSFERSTATUS"]._serialized_end = 67802 _globals["_PICTURERECORDINGSTATUS"]._serialized_start = 67804 _globals["_PICTURERECORDINGSTATUS"]._serialized_end = 67906 _globals["_PARKCOLLISIONINACTIVEREASON"]._serialized_start = 67909 _globals["_PARKCOLLISIONINACTIVEREASON"]._serialized_end = 68443 _globals["_PARKCOLLISIONSELECTIONSTATUS"]._serialized_start = 68445 _globals["_PARKCOLLISIONSELECTIONSTATUS"]._serialized_end = 68568 _globals["_VEHICLETHEFTALARMINACTIVEREASON"]._serialized_start = 68571 _globals["_VEHICLETHEFTALARMINACTIVEREASON"]._serialized_end = 68804 _globals["_TOWPROTECTIONACTIVATIONSTATUS"]._serialized_start = 68807 _globals["_TOWPROTECTIONACTIVATIONSTATUS"]._serialized_end = 68964 _globals["_TOWPROTECTIONSELECTIONSTATUS"]._serialized_start = 68966 _globals["_TOWPROTECTIONSELECTIONSTATUS"]._serialized_end = 69089 _globals["_INTERIORPROTECTIONACTIVATIONSTATUS"]._serialized_start = 69092 _globals["_INTERIORPROTECTIONACTIVATIONSTATUS"]._serialized_end = 69269 _globals["_INTERIORPROTECTIONSELECTIONSTATUS"]._serialized_start = 69272 _globals["_INTERIORPROTECTIONSELECTIONSTATUS"]._serialized_end = 69410 _globals["_PANICALARMACTIVE"]._serialized_start = 69412 _globals["_PANICALARMACTIVE"]._serialized_end = 69506 _globals["_PARKEVENTPICTURESELECTIONSTATUS"]._serialized_start = 69509 _globals["_PARKEVENTPICTURESELECTIONSTATUS"]._serialized_end = 69646 _globals["_PARKCOLLISIONACTIVATIONSTATUS"]._serialized_start = 69649 _globals["_PARKCOLLISIONACTIVATIONSTATUS"]._serialized_end = 69806 _globals["_CHARGINGCOMPATIBILITYERROR"]._serialized_start = 69809 _globals["_CHARGINGCOMPATIBILITYERROR"]._serialized_end = 70184 _globals["_CHARGINGFLAPERRORDETAILS"]._serialized_start = 70187 _globals["_CHARGINGFLAPERRORDETAILS"]._serialized_end = 70609 _globals["_CHARGEFLAPSPOSITIONSTATE"]._serialized_start = 70612 _globals["_CHARGEFLAPSPOSITIONSTATE"]._serialized_end = 70844 _globals["_CHARGINGPOWERRESTRICTION"]._serialized_start = 70847 _globals["_CHARGINGPOWERRESTRICTION"]._serialized_end = 71539 _globals["_BATTERYHEALTH"]._serialized_start = 71542 _globals["_BATTERYHEALTH"]._serialized_end = 71876 _globals["_PRECONDSTATETYPE"]._serialized_start = 71879 _globals["_PRECONDSTATETYPE"]._serialized_end = 72056 _globals["_CHARGEPROGRAM"]._serialized_start = 72058 _globals["_CHARGEPROGRAM"]._serialized_end = 72179 _globals["_ATTRIBUTESTATUS"]._serialized_start = 72181 _globals["_ATTRIBUTESTATUS"]._serialized_end = 72283 _globals["_SCOPE"]._serialized_start = 72285 _globals["_SCOPE"]._serialized_end = 72388 _globals["_DOORSTATUS"]._serialized_start = 72390 _globals["_DOORSTATUS"]._serialized_end = 72446 _globals["_DOORLOCKSTATUS"]._serialized_start = 72448 _globals["_DOORLOCKSTATUS"]._serialized_end = 72520 _globals["_DOORLOCKSTATUSVEHICLE"]._serialized_start = 72523 _globals["_DOORLOCKSTATUSVEHICLE"]._serialized_end = 72714 _globals["_DOORSTATUSOVERALL"]._serialized_start = 72717 _globals["_DOORSTATUSOVERALL"]._serialized_end = 72850 _globals["_DOORSTATUSGAS"]._serialized_start = 72852 _globals["_DOORSTATUSGAS"]._serialized_end = 72942 _globals["_CHARGINGSTATUS"]._serialized_start = 72945 _globals["_CHARGINGSTATUS"]._serialized_end = 73668 _globals["_CHARGINGMODE"]._serialized_start = 73671 _globals["_CHARGINGMODE"]._serialized_end = 73898 _globals["_SELECTEDCHARGEPROGRAM"]._serialized_start = 73901 _globals["_SELECTEDCHARGEPROGRAM"]._serialized_end = 74605 _globals["_SMARTCHARGING"]._serialized_start = 74608 _globals["_SMARTCHARGING"]._serialized_end = 74746 _globals["_SMARTCHARGINGATDEPARTURE"]._serialized_start = 74748 _globals["_SMARTCHARGINGATDEPARTURE"]._serialized_end = 74858 _globals["_CHARGECOUPLERSTATUS"]._serialized_start = 74861 _globals["_CHARGECOUPLERSTATUS"]._serialized_end = 75109 _globals["_CHARGECOUPLERLOCKSTATUS"]._serialized_start = 75112 _globals["_CHARGECOUPLERLOCKSTATUS"]._serialized_end = 75259 _globals["_CHARGEFLAPSTATUS"]._serialized_start = 75261 _globals["_CHARGEFLAPSTATUS"]._serialized_end = 75376 _globals["_CHARGINGERRORDETAILS"]._serialized_start = 75379 _globals["_CHARGINGERRORDETAILS"]._serialized_end = 75516 _globals["_IGNITIONSTATE"]._serialized_start = 75519 _globals["_IGNITIONSTATE"]._serialized_end = 75657 _globals["_ENGINESTATE"]._serialized_start = 75659 _globals["_ENGINESTATE"]._serialized_end = 75728 _globals["_PARKBRAKESTATUS"]._serialized_start = 75730 _globals["_PARKBRAKESTATUS"]._serialized_end = 75809 _globals["_ENGINEHOODSTATUS"]._serialized_start = 75811 _globals["_ENGINEHOODSTATUS"]._serialized_end = 75889 _globals["_ROOFTOPSTATUS"]._serialized_start = 75891 _globals["_ROOFTOPSTATUS"]._serialized_end = 76006 _globals["_WINDOWSTATUS"]._serialized_start = 76009 _globals["_WINDOWSTATUS"]._serialized_end = 76160 _globals["_WINDOWSTATUSBLIND"]._serialized_start = 76163 _globals["_WINDOWSTATUSBLIND"]._serialized_end = 76306 _globals["_WINDOWSTATUSOVERALL"]._serialized_start = 76309 _globals["_WINDOWSTATUSOVERALL"]._serialized_end = 76473 _globals["_SUNROOFSTATUS"]._serialized_start = 76476 _globals["_SUNROOFSTATUS"]._serialized_end = 76609 _globals["_SUNROOFSTATUSBLIND"]._serialized_start = 76612 _globals["_SUNROOFSTATUSBLIND"]._serialized_end = 76793 _globals["_SUNROOFEVENT"]._serialized_start = 76796 _globals["_SUNROOFEVENT"]._serialized_end = 76955 _globals["_FLIPWINDOWSTATUS"]._serialized_start = 76957 _globals["_FLIPWINDOWSTATUS"]._serialized_end = 77035 _globals["_TIREMARKER"]._serialized_start = 77038 _globals["_TIREMARKER"]._serialized_end = 77187 _globals["_TIRESENSORAVAILABLE"]._serialized_start = 77190 _globals["_TIRESENSORAVAILABLE"]._serialized_end = 77421 _globals["_TIREWARNINGLEVELPRW"]._serialized_start = 77424 _globals["_TIREWARNINGLEVELPRW"]._serialized_end = 77563 _globals["_TIREWARNINGLAMP"]._serialized_start = 77566 _globals["_TIREWARNINGLAMP"]._serialized_end = 77701 _globals["_TIREWARNINGSPRW"]._serialized_start = 77703 _globals["_TIREWARNINGSPRW"]._serialized_end = 77781 _globals["_TIREWARNINGSRDK"]._serialized_start = 77784 _globals["_TIREWARNINGSRDK"]._serialized_end = 77932 _globals["_PRECONDERROR"]._serialized_start = 77935 _globals["_PRECONDERROR"]._serialized_end = 78250 _globals["_PRECONDNOW"]._serialized_start = 78252 _globals["_PRECONDNOW"]._serialized_end = 78314 _globals["_PRECONDOPERATINGMODE"]._serialized_start = 78317 _globals["_PRECONDOPERATINGMODE"]._serialized_end = 78475 _globals["_PRECONDATDEPARTURE"]._serialized_start = 78477 _globals["_PRECONDATDEPARTURE"]._serialized_end = 78561 _globals["_PRECONDSEAT"]._serialized_start = 78563 _globals["_PRECONDSEAT"]._serialized_end = 78619 _globals["_AUXHEATSTATUS"]._serialized_start = 78622 _globals["_AUXHEATSTATUS"]._serialized_end = 78897 _globals["_AUXHEATTIMESELECTION"]._serialized_start = 78900 _globals["_AUXHEATTIMESELECTION"]._serialized_end = 79059 _globals["_AUXHEATWARNING"]._serialized_start = 79061 _globals["_AUXHEATWARNING"]._serialized_end = 79170 _globals["_DEPARTURETIMEMODE"]._serialized_start = 79173 _globals["_DEPARTURETIMEMODE"]._serialized_end = 79387 _globals["_WEEKDAY"]._serialized_start = 79390 _globals["_WEEKDAY"]._serialized_end = 79547 _globals["_RANGESKIPINDICATION"]._serialized_start = 79549 _globals["_RANGESKIPINDICATION"]._serialized_end = 79637 _globals["_FILTERPARTICLELOADING"]._serialized_start = 79639 _globals["_FILTERPARTICLELOADING"]._serialized_end = 79765 _globals["_LANGUAGEHU"]._serialized_start = 79768 _globals["_LANGUAGEHU"]._serialized_end = 80772 _globals["_SPEEDUNITFROMIC"]._serialized_start = 80774 _globals["_SPEEDUNITFROMIC"]._serialized_end = 80848 _globals["_TEMPERATUREUNITHU"]._serialized_start = 80850 _globals["_TEMPERATUREUNITHU"]._serialized_end = 80938 _globals["_TIMEFORMATHU"]._serialized_start = 80940 _globals["_TIMEFORMATHU"]._serialized_end = 81012 _globals["_TRACKINGSTATEHU"]._serialized_start = 81014 _globals["_TRACKINGSTATEHU"]._serialized_end = 81084 _globals["_VEHICLEDATACONNECTIONSTATE"]._serialized_start = 81086 _globals["_VEHICLEDATACONNECTIONSTATE"]._serialized_end = 81207 _globals["_VEHICLEHEALTHSTATUS"]._serialized_start = 81209 _globals["_VEHICLEHEALTHSTATUS"]._serialized_end = 81328 _globals["_DRIVINGMODE"]._serialized_start = 81331 _globals["_DRIVINGMODE"]._serialized_end = 81496 _globals["_OILWARNINGLEVEL"]._serialized_start = 81499 _globals["_OILWARNINGLEVEL"]._serialized_end = 81644 _globals["_PARKEVENTLEVEL"]._serialized_start = 81646 _globals["_PARKEVENTLEVEL"]._serialized_end = 81744 _globals["_PARKEVENTTYPE"]._serialized_start = 81747 _globals["_PARKEVENTTYPE"]._serialized_end = 82075 _globals["_PARKEVENTSENSORSTATUS"]._serialized_start = 82078 _globals["_PARKEVENTSENSORSTATUS"]._serialized_end = 82240 _globals["_WARNINGWASHWATER"]._serialized_start = 82242 _globals["_WARNINGWASHWATER"]._serialized_end = 82323 _globals["_HYBRIDWARNINGS"]._serialized_start = 82326 _globals["_HYBRIDWARNINGS"]._serialized_end = 82697 _globals["_LASTTHEFTWARNINGREASON"]._serialized_start = 82700 _globals["_LASTTHEFTWARNINGREASON"]._serialized_end = 83929 _globals["_HVBATTERYTHERMALPROPAGATIONEVENT"]._serialized_start = 83932 _globals["_HVBATTERYTHERMALPROPAGATIONEVENT"]._serialized_end = 84105 _globals["_STARTERBATTERYSTATE"]._serialized_start = 84108 _globals["_STARTERBATTERYSTATE"]._serialized_end = 84301 _globals["_VEHICLEPOSITIONERRORCODE"]._serialized_start = 84304 _globals["_VEHICLEPOSITIONERRORCODE"]._serialized_end = 84593 _globals["_CALIBRATIONREQUEST"]._serialized_start = 84595 _globals["_CALIBRATIONREQUEST"]._serialized_end = 84710 _globals["_ASSYSTOILQUANTITY"]._serialized_start = 84713 _globals["_ASSYSTOILQUANTITY"]._serialized_end = 85361 _globals["_ASSYSTOILWARNING"]._serialized_start = 85364 _globals["_ASSYSTOILWARNING"]._serialized_end = 85621 _globals["_PROTECTIONACTIVATIONSTATUS"]._serialized_start = 85624 _globals["_PROTECTIONACTIVATIONSTATUS"]._serialized_end = 85766 _globals["_PROTECTIONSENSORSTATUS"]._serialized_start = 85768 _globals["_PROTECTIONSENSORSTATUS"]._serialized_end = 85870 _globals["_TCUCONNECTIONSTATELOWCHANNEL"]._serialized_start = 85873 _globals["_TCUCONNECTIONSTATELOWCHANNEL"]._serialized_end = 86169 _globals["_TCUTHERMOSHUTDOWN"]._serialized_start = 86171 _globals["_TCUTHERMOSHUTDOWN"]._serialized_end = 86294 _globals["_KEYACTIVATIONSTATE"]._serialized_start = 86297 _globals["_KEYACTIVATIONSTATE"]._serialized_end = 86478 _globals["_PICTURETRANSFERSELECTIONSTATUS"]._serialized_start = 86481 _globals["_PICTURETRANSFERSELECTIONSTATUS"]._serialized_end = 86613 _globals["_VEPUPDATE"]._serialized_start = 166 _globals["_VEPUPDATE"]._serialized_end = 426 _globals["_VEPUPDATE_ATTRIBUTESENTRY"]._serialized_start = 346 _globals["_VEPUPDATE_ATTRIBUTESENTRY"]._serialized_end = 426 _globals["_VEHICLEATTRIBUTESTATUS"]._serialized_start = 429 _globals["_VEHICLEATTRIBUTESTATUS"]._serialized_end = 8421 _globals["_VEHICLEATTRIBUTESTATUS_COMBUSTIONCONSUMPTIONUNIT"]._serialized_start = 6440 _globals["_VEHICLEATTRIBUTESTATUS_COMBUSTIONCONSUMPTIONUNIT"]._serialized_end = 6575 _globals["_VEHICLEATTRIBUTESTATUS_ELECTRICITYCONSUMPTIONUNIT"]._serialized_start = 6578 _globals["_VEHICLEATTRIBUTESTATUS_ELECTRICITYCONSUMPTIONUNIT"]._serialized_end = 6731 _globals["_VEHICLEATTRIBUTESTATUS_GASCONSUMPTIONUNIT"]._serialized_start = 6733 _globals["_VEHICLEATTRIBUTESTATUS_GASCONSUMPTIONUNIT"]._serialized_end = 6838 _globals["_VEHICLEATTRIBUTESTATUS_SPEEDDISTANCEUNIT"]._serialized_start = 6840 _globals["_VEHICLEATTRIBUTESTATUS_SPEEDDISTANCEUNIT"]._serialized_end = 6927 _globals["_VEHICLEATTRIBUTESTATUS_SPEEDUNIT"]._serialized_start = 6929 _globals["_VEHICLEATTRIBUTESTATUS_SPEEDUNIT"]._serialized_end = 7001 _globals["_VEHICLEATTRIBUTESTATUS_DISTANCEUNIT"]._serialized_start = 7003 _globals["_VEHICLEATTRIBUTESTATUS_DISTANCEUNIT"]._serialized_end = 7075 _globals["_VEHICLEATTRIBUTESTATUS_TEMPERATUREUNIT"]._serialized_start = 7077 _globals["_VEHICLEATTRIBUTESTATUS_TEMPERATUREUNIT"]._serialized_end = 7157 _globals["_VEHICLEATTRIBUTESTATUS_PRESSUREUNIT"]._serialized_start = 7159 _globals["_VEHICLEATTRIBUTESTATUS_PRESSUREUNIT"]._serialized_end = 7231 _globals["_VEHICLEATTRIBUTESTATUS_RATIOUNIT"]._serialized_start = 7233 _globals["_VEHICLEATTRIBUTESTATUS_RATIOUNIT"]._serialized_end = 7285 _globals["_VEHICLEATTRIBUTESTATUS_CLOCKHOURUNIT"]._serialized_start = 7287 _globals["_VEHICLEATTRIBUTESTATUS_CLOCKHOURUNIT"]._serialized_end = 7355 _globals["_VEHICLEATTRIBUTESTATUS_TCUCONNECTIONSTATELOWCHANNELSTATUS"]._serialized_start = 7358 _globals["_VEHICLEATTRIBUTESTATUS_TCUCONNECTIONSTATELOWCHANNELSTATUS"]._serialized_end = 7516 _globals["_VEHICLEATTRIBUTESTATUS_CHARGINGCOUPLERERRORDETAILS"]._serialized_start = 7519 _globals["_VEHICLEATTRIBUTESTATUS_CHARGINGCOUPLERERRORDETAILS"]._serialized_end = 7886 _globals["_VEHICLEATTRIBUTESTATUS_CHARGINGERRORIMPOSSIBLECHANGETO400V"]._serialized_start = 7889 _globals["_VEHICLEATTRIBUTESTATUS_CHARGINGERRORIMPOSSIBLECHANGETO400V"]._serialized_end = 8056 _globals["_VEHICLEATTRIBUTESTATUS_CHARGINGERRORIMPOSSIBLECHANGETO800V"]._serialized_start = 8059 _globals["_VEHICLEATTRIBUTESTATUS_CHARGINGERRORIMPOSSIBLECHANGETO800V"]._serialized_end = 8226 _globals["_VEHICLEATTRIBUTESTATUS_CHARGINGERRORVEHICLENOSUPPORT400V"]._serialized_start = 8229 _globals["_VEHICLEATTRIBUTESTATUS_CHARGINGERRORVEHICLENOSUPPORT400V"]._serialized_end = 8387 _globals["_AMGSTAGEMODEERROR"]._serialized_start = 8424 _globals["_AMGSTAGEMODEERROR"]._serialized_end = 8592 _globals["_KEYLINEACTIVATIONSTATEVALUE"]._serialized_start = 8594 _globals["_KEYLINEACTIVATIONSTATEVALUE"]._serialized_end = 8695 _globals["_NEXTDEPARTURETIMEVALUE"]._serialized_start = 8697 _globals["_NEXTDEPARTURETIMEVALUE"]._serialized_end = 8751 _globals["_REMOTEUPDATESTARTSTATUS"]._serialized_start = 8754 _globals["_REMOTEUPDATESTARTSTATUS"]._serialized_end = 8895 _globals["_CHARGINGSCHEDULEACTIVE"]._serialized_start = 8898 _globals["_CHARGINGSCHEDULEACTIVE"]._serialized_end = 11698 _globals["_CHARGINGSCHEDULEACTIVE_CHARGINGSCHEDULEACTIVESCHEDULE"]._serialized_start = 9382 _globals["_CHARGINGSCHEDULEACTIVE_CHARGINGSCHEDULEACTIVESCHEDULE"]._serialized_end = 9461 _globals["_CHARGINGSCHEDULEACTIVE_CHARGINGSCHEDULEACTIVEUSECASEID"]._serialized_start = 9464 _globals["_CHARGINGSCHEDULEACTIVE_CHARGINGSCHEDULEACTIVEUSECASEID"]._serialized_end = 11516 _globals["_CHARGINGSCHEDULEACTIVE_CHARGINGSCHEDULEACTIVEOFFLINEMODE"]._serialized_start = 11519 _globals["_CHARGINGSCHEDULEACTIVE_CHARGINGSCHEDULEACTIVEOFFLINEMODE"]._serialized_end = 11698 _globals["_HVBATTERYPRECONDSTATE"]._serialized_start = 11701 _globals["_HVBATTERYPRECONDSTATE"]._serialized_end = 11844 _globals["_HVBATTERYPRECONDREQUESTSTATE"]._serialized_start = 11847 _globals["_HVBATTERYPRECONDREQUESTSTATE"]._serialized_end = 12077 _globals["_PRECONDOPERABILITYSTATE"]._serialized_start = 12080 _globals["_PRECONDOPERABILITYSTATE"]._serialized_end = 12545 _globals["_PRECONDOPERABILITYSTATE_PRECONDERRORSTATE"]._serialized_start = 12214 _globals["_PRECONDOPERABILITYSTATE_PRECONDERRORSTATE"]._serialized_end = 12545 _globals["_CHARGINGSCHEDULEREQUESTED"]._serialized_start = 12548 _globals["_CHARGINGSCHEDULEREQUESTED"]._serialized_end = 14626 _globals["_CHARGINGSCHEDULEREQUESTED_SCHEDULEIDSTATUS"]._serialized_start = 12737 _globals["_CHARGINGSCHEDULEREQUESTED_SCHEDULEIDSTATUS"]._serialized_end = 12819 _globals["_CHARGINGSCHEDULEREQUESTED_CHARGINGSCHEDULEUSECASEID"]._serialized_start = 12822 _globals["_CHARGINGSCHEDULEREQUESTED_CHARGINGSCHEDULEUSECASEID"]._serialized_end = 14626 _globals["_CHARGINGTIMER"]._serialized_start = 14628 _globals["_CHARGINGTIMER"]._serialized_end = 14687 _globals["_CHARGINGTIMERENTRY"]._serialized_start = 14690 _globals["_CHARGINGTIMERENTRY"]._serialized_end = 15087 _globals["_CHARGINGTIMERENTRY_CHARGINGTIMERACTION"]._serialized_start = 14923 _globals["_CHARGINGTIMERENTRY_CHARGINGTIMERACTION"]._serialized_end = 15087 _globals["_CHARGINGPREDICTIONSOC"]._serialized_start = 15089 _globals["_CHARGINGPREDICTIONSOC"]._serialized_end = 15211 _globals["_CHARGINGPREDICTIONDEPARTURETIME"]._serialized_start = 15213 _globals["_CHARGINGPREDICTIONDEPARTURETIME"]._serialized_end = 15312 _globals["_CHARGEINLETSENTRY"]._serialized_start = 15315 _globals["_CHARGEINLETSENTRY"]._serialized_end = 15976 _globals["_CHARGEINLETSENTRY_CHARGEINLETSCOUPLERSTATE"]._serialized_start = 15491 _globals["_CHARGEINLETSENTRY_CHARGEINLETSCOUPLERSTATE"]._serialized_end = 15741 _globals["_CHARGEINLETSENTRY_CHARGEINLETSLOCKSTATE"]._serialized_start = 15744 _globals["_CHARGEINLETSENTRY_CHARGEINLETSLOCKSTATE"]._serialized_end = 15976 _globals["_CHARGEINLETS"]._serialized_start = 15978 _globals["_CHARGEINLETS"]._serialized_end = 16035 _globals["_CHARGEFLAPSENTRY"]._serialized_start = 16037 _globals["_CHARGEFLAPSENTRY"]._serialized_end = 16124 _globals["_CHARGEFLAPS"]._serialized_start = 16126 _globals["_CHARGEFLAPS"]._serialized_end = 16181 _globals["_CHARGINGPOWERRESTRICTIONS"]._serialized_start = 16183 _globals["_CHARGINGPOWERRESTRICTIONS"]._serialized_end = 16279 _globals["_CHARGINGBREAKCLOCKTIMERVALUE"]._serialized_start = 16281 _globals["_CHARGINGBREAKCLOCKTIMERVALUE"]._serialized_end = 16388 _globals["_PRECONDSTATE"]._serialized_start = 16391 _globals["_PRECONDSTATE"]._serialized_end = 16520 _globals["_CHARGINGPOWERCONTROL"]._serialized_start = 16523 _globals["_CHARGINGPOWERCONTROL"]._serialized_end = 16830 _globals["_CHARGINGPOWERCONTROL_CHARGINGSTATUSFORPOWERCONTROL"]._serialized_start = 16750 _globals["_CHARGINGPOWERCONTROL_CHARGINGSTATUSFORPOWERCONTROL"]._serialized_end = 16830 _globals["_CHARGINGBREAKCLOCKTIMERENTRY"]._serialized_start = 16833 _globals["_CHARGINGBREAKCLOCKTIMERENTRY"]._serialized_end = 17031 _globals["_CHARGEPROGRAMSVALUE"]._serialized_start = 17033 _globals["_CHARGEPROGRAMSVALUE"]._serialized_end = 17121 _globals["_CHARGEPROGRAMPARAMETERS"]._serialized_start = 17124 _globals["_CHARGEPROGRAMPARAMETERS"]._serialized_end = 17480 _globals["_WEEKLYPROFILEVALUE"]._serialized_start = 17483 _globals["_WEEKLYPROFILEVALUE"]._serialized_end = 17944 _globals["_VVRTIMEPROFILE"]._serialized_start = 17947 _globals["_VVRTIMEPROFILE"]._serialized_end = 18141 _globals["_ECOHISTOGRAMVALUE"]._serialized_start = 18143 _globals["_ECOHISTOGRAMVALUE"]._serialized_end = 18214 _globals["_ECOHISTOGRAMBIN"]._serialized_start = 18216 _globals["_ECOHISTOGRAMBIN"]._serialized_end = 18266 _globals["_SPEEDALERTCONFIGURATIONVALUE"]._serialized_start = 18268 _globals["_SPEEDALERTCONFIGURATIONVALUE"]._serialized_end = 18366 _globals["_SPEEDALERTCONFIGURATION"]._serialized_start = 18368 _globals["_SPEEDALERTCONFIGURATION"]._serialized_end = 18480 _globals["_WEEKLYSETTINGSHEADUNITVALUE"]._serialized_start = 18482 _globals["_WEEKLYSETTINGSHEADUNITVALUE"]._serialized_end = 18558 _globals["_WEEKLYSETTING"]._serialized_start = 18560 _globals["_WEEKLYSETTING"]._serialized_end = 18620 _globals["_TEMPERATUREPOINTSVALUE"]._serialized_start = 18622 _globals["_TEMPERATUREPOINTSVALUE"]._serialized_end = 18699 _globals["_TEMPERATUREPOINT"]._serialized_start = 18701 _globals["_TEMPERATUREPOINT"]._serialized_end = 18789 _globals["_WEEKDAYTARIFFVALUE"]._serialized_start = 18791 _globals["_WEEKDAYTARIFFVALUE"]._serialized_end = 18843 _globals["_WEEKENDTARIFFVALUE"]._serialized_start = 18845 _globals["_WEEKENDTARIFFVALUE"]._serialized_end = 18897 _globals["_TARIFF"]._serialized_start = 18899 _globals["_TARIFF"]._serialized_end = 18935 _globals["_STATEOFCHARGEPROFILEVALUE"]._serialized_start = 18937 _globals["_STATEOFCHARGEPROFILEVALUE"]._serialized_end = 19012 _globals["_STATEOFCHARGE"]._serialized_start = 19014 _globals["_STATEOFCHARGE"]._serialized_end = 19078 _globals["_VEPUPDATESBYVIN"]._serialized_start = 19081 _globals["_VEPUPDATESBYVIN"]._serialized_end = 19243 _globals["_VEPUPDATESBYVIN_UPDATESENTRY"]._serialized_start = 19179 _globals["_VEPUPDATESBYVIN_UPDATESENTRY"]._serialized_end = 19243 _globals["_DEBUGMESSAGE"]._serialized_start = 19245 _globals["_DEBUGMESSAGE"]._serialized_end = 19276 _globals["_VEHICLESTATUS"]._serialized_start = 19279 _globals["_VEHICLESTATUS"]._serialized_end = 19447 _globals["_VEHICLESTATUS_ATTRIBUTESENTRY"]._serialized_start = 346 _globals["_VEHICLESTATUS_ATTRIBUTESENTRY"]._serialized_end = 426 _globals["_PUSHMESSAGE"]._serialized_start = 19450 _globals["_PUSHMESSAGE"]._serialized_end = 20456 _globals["_TRACKINGEVENT"]._serialized_start = 20459 _globals["_TRACKINGEVENT"]._serialized_end = 20655 _globals["_TRACKINGEVENT_PAYLOADENTRY"]._serialized_start = 20588 _globals["_TRACKINGEVENT_PAYLOADENTRY"]._serialized_end = 20655 _globals["_PAYLOADVALUE"]._serialized_start = 20657 _globals["_PAYLOADVALUE"]._serialized_end = 20769 _globals["_ACKNOWLEDGEVEPREQUEST"]._serialized_start = 20771 _globals["_ACKNOWLEDGEVEPREQUEST"]._serialized_end = 20823 _globals["_ACKNOWLEDGEVEPUPDATESBYVIN"]._serialized_start = 20825 _globals["_ACKNOWLEDGEVEPUPDATESBYVIN"]._serialized_end = 20878 _globals["_CONFIGUREPINGINTERVAL"]._serialized_start = 20880 _globals["_CONFIGUREPINGINTERVAL"]._serialized_end = 20929 _globals["_ACKNOWLEDGEVEHICLEUPDATED"]._serialized_start = 20931 _globals["_ACKNOWLEDGEVEHICLEUPDATED"]._serialized_end = 20983 _globals["_ACKNOWLEDGEPREFERREDDEALERCHANGE"]._serialized_start = 20985 _globals["_ACKNOWLEDGEPREFERREDDEALERCHANGE"]._serialized_end = 21044 _globals["_VEHICLEUPDATED"]._serialized_start = 21046 _globals["_VEHICLEUPDATED"]._serialized_end = 21147 _globals["_PREFERREDDEALERCHANGE"]._serialized_start = 21149 _globals["_PREFERREDDEALERCHANGE"]._serialized_end = 21257 _globals["_ACKNOWLEDGEDATACHANGEEVENT"]._serialized_start = 21259 _globals["_ACKNOWLEDGEDATACHANGEEVENT"]._serialized_end = 21312 _globals["_SCOPES"]._serialized_start = 21315 _globals["_SCOPES"]._serialized_end = 21559 _globals["_SCOPES_ADDITIONALRESOURCESENTRY"]._serialized_start = 21501 _globals["_SCOPES_ADDITIONALRESOURCESENTRY"]._serialized_end = 21559 _globals["_DATACHANGEEVENT"]._serialized_start = 21561 _globals["_DATACHANGEEVENT"]._serialized_end = 21655 _globals["_VEHICLESTATUSUPDATES"]._serialized_start = 21658 _globals["_VEHICLESTATUSUPDATES"]._serialized_end = 21881 _globals["_VEHICLESTATUSUPDATES_VEHICLESTATUSUPDATESENTRY"]._serialized_start = 21794 _globals["_VEHICLESTATUSUPDATES_VEHICLESTATUSUPDATESENTRY"]._serialized_end = 21881 _globals["_ACKNOWLEDGEVEHICLESTATUSUPDATES"]._serialized_start = 21883 _globals["_ACKNOWLEDGEVEHICLESTATUSUPDATES"]._serialized_end = 21941 _globals["_VSUMETADATA"]._serialized_start = 21943 _globals["_VSUMETADATA"]._serialized_end = 22043 _globals["_BOOLATTRIBUTE"]._serialized_start = 22045 _globals["_BOOLATTRIBUTE"]._serialized_end = 22113 _globals["_INT64ATTRIBUTE"]._serialized_start = 22115 _globals["_INT64ATTRIBUTE"]._serialized_end = 22184 _globals["_DOUBLEATTRIBUTE"]._serialized_start = 22186 _globals["_DOUBLEATTRIBUTE"]._serialized_end = 22256 _globals["_TIMESTAMPATTRIBUTE"]._serialized_start = 22258 _globals["_TIMESTAMPATTRIBUTE"]._serialized_end = 22331 _globals["_INT64DISTANCEATTRIBUTE"]._serialized_start = 22334 _globals["_INT64DISTANCEATTRIBUTE"]._serialized_end = 22492 _globals["_DOUBLEDISTANCEATTRIBUTE"]._serialized_start = 22495 _globals["_DOUBLEDISTANCEATTRIBUTE"]._serialized_end = 22654 _globals["_DOUBLEPRESSUREATTRIBUTE"]._serialized_start = 22657 _globals["_DOUBLEPRESSUREATTRIBUTE"]._serialized_end = 22816 _globals["_DOUBLESPEEDATTRIBUTE"]._serialized_start = 22819 _globals["_DOUBLESPEEDATTRIBUTE"]._serialized_end = 22972 _globals["_DOUBLECOMBUSTIONCONSUMPTIONATTRIBUTE"]._serialized_start = 22975 _globals["_DOUBLECOMBUSTIONCONSUMPTIONATTRIBUTE"]._serialized_end = 23160 _globals["_DOUBLEELECTRICITYCONSUMPTIONATTRIBUTE"]._serialized_start = 23163 _globals["_DOUBLEELECTRICITYCONSUMPTIONATTRIBUTE"]._serialized_end = 23350 _globals["_DOUBLEGASCONSUMPTIONATTRIBUTE"]._serialized_start = 23353 _globals["_DOUBLEGASCONSUMPTIONATTRIBUTE"]._serialized_end = 23524 _globals["_INT64RATIOATTRIBUTE"]._serialized_start = 23527 _globals["_INT64RATIOATTRIBUTE"]._serialized_end = 23679 _globals["_DOUBLERATIOATTRIBUTE"]._serialized_start = 23682 _globals["_DOUBLERATIOATTRIBUTE"]._serialized_end = 23835 _globals["_DOUBLETEMPERATUREATTRIBUTE"]._serialized_start = 23838 _globals["_DOUBLETEMPERATUREATTRIBUTE"]._serialized_end = 24003 _globals["_INT64CLOCKHOURATTRIBUTE"]._serialized_start = 24006 _globals["_INT64CLOCKHOURATTRIBUTE"]._serialized_end = 24166 _globals["_TIMESTAMPCLOCKHOURATTRIBUTE"]._serialized_start = 24169 _globals["_TIMESTAMPCLOCKHOURATTRIBUTE"]._serialized_end = 24333 _globals["_AMGSTAGEMODESTATEENUMATTRIBUTE"]._serialized_start = 24335 _globals["_AMGSTAGEMODESTATEENUMATTRIBUTE"]._serialized_end = 24446 _globals["_ASSYSTOILQUANTITYENUMATTRIBUTE"]._serialized_start = 24448 _globals["_ASSYSTOILQUANTITYENUMATTRIBUTE"]._serialized_end = 24559 _globals["_ASSYSTOILWARNINGENUMATTRIBUTE"]._serialized_start = 24561 _globals["_ASSYSTOILWARNINGENUMATTRIBUTE"]._serialized_end = 24670 _globals["_AUXHEATSTATUSENUMATTRIBUTE"]._serialized_start = 24672 _globals["_AUXHEATSTATUSENUMATTRIBUTE"]._serialized_end = 24775 _globals["_AUXHEATTIMESELECTIONENUMATTRIBUTE"]._serialized_start = 24777 _globals["_AUXHEATTIMESELECTIONENUMATTRIBUTE"]._serialized_end = 24894 _globals["_BATTERYHEALTHENUMATTRIBUTE"]._serialized_start = 24896 _globals["_BATTERYHEALTHENUMATTRIBUTE"]._serialized_end = 24999 _globals["_CALIBRATIONREQUESTENUMATTRIBUTE"]._serialized_start = 25001 _globals["_CALIBRATIONREQUESTENUMATTRIBUTE"]._serialized_end = 25114 _globals["_CHARGECOUPLERLOCKSTATUSENUMATTRIBUTE"]._serialized_start = 25116 _globals["_CHARGECOUPLERLOCKSTATUSENUMATTRIBUTE"]._serialized_end = 25239 _globals["_CHARGECOUPLERSTATUSENUMATTRIBUTE"]._serialized_start = 25241 _globals["_CHARGECOUPLERSTATUSENUMATTRIBUTE"]._serialized_end = 25356 _globals["_CHARGEFLAPSTATUSENUMATTRIBUTE"]._serialized_start = 25358 _globals["_CHARGEFLAPSTATUSENUMATTRIBUTE"]._serialized_end = 25467 _globals["_CHARGINGCOMPATIBILITYERRORENUMATTRIBUTE"]._serialized_start = 25470 _globals["_CHARGINGCOMPATIBILITYERRORENUMATTRIBUTE"]._serialized_end = 25599 _globals["_CHARGINGCOUPLERERRORDETAILSENUMATTRIBUTE"]._serialized_start = 25602 _globals["_CHARGINGCOUPLERERRORDETAILSENUMATTRIBUTE"]._serialized_end = 25756 _globals["_CHARGINGERRORDETAILSENUMATTRIBUTE"]._serialized_start = 25758 _globals["_CHARGINGERRORDETAILSENUMATTRIBUTE"]._serialized_end = 25875 _globals["_CHARGINGERRORIMPOSSIBLECHANGETO400VENUMATTRIBUTE"]._serialized_start = 25878 _globals["_CHARGINGERRORIMPOSSIBLECHANGETO400VENUMATTRIBUTE"]._serialized_end = 26048 _globals["_CHARGINGERRORIMPOSSIBLECHANGETO800VENUMATTRIBUTE"]._serialized_start = 26051 _globals["_CHARGINGERRORIMPOSSIBLECHANGETO800VENUMATTRIBUTE"]._serialized_end = 26221 _globals["_CHARGINGERRORVEHICLENOSUPPORT400VENUMATTRIBUTE"]._serialized_start = 26224 _globals["_CHARGINGERRORVEHICLENOSUPPORT400VENUMATTRIBUTE"]._serialized_end = 26390 _globals["_CHARGINGFLAPERRORDETAILSENUMATTRIBUTE"]._serialized_start = 26392 _globals["_CHARGINGFLAPERRORDETAILSENUMATTRIBUTE"]._serialized_end = 26517 _globals["_CHARGINGMODEENUMATTRIBUTE"]._serialized_start = 26519 _globals["_CHARGINGMODEENUMATTRIBUTE"]._serialized_end = 26620 _globals["_CHARGINGSTATUSENUMATTRIBUTE"]._serialized_start = 26622 _globals["_CHARGINGSTATUSENUMATTRIBUTE"]._serialized_end = 26727 _globals["_CHARGINGSTOPERRORDETAILSENUMATTRIBUTE"]._serialized_start = 26729 _globals["_CHARGINGSTOPERRORDETAILSENUMATTRIBUTE"]._serialized_end = 26854 _globals["_CHILDPRESENCEDETECTIONWARNINGLASTEVENTENUMATTRIBUTE"]._serialized_start = 26857 _globals["_CHILDPRESENCEDETECTIONWARNINGLASTEVENTENUMATTRIBUTE"]._serialized_end = 27010 _globals["_CHILDPRESENCEDETECTIONWARNINGLEVELENUMATTRIBUTE"]._serialized_start = 27013 _globals["_CHILDPRESENCEDETECTIONWARNINGLEVELENUMATTRIBUTE"]._serialized_end = 27158 _globals["_DCCHARGINGPROFILEENUMATTRIBUTE"]._serialized_start = 27160 _globals["_DCCHARGINGPROFILEENUMATTRIBUTE"]._serialized_end = 27271 _globals["_DEPARTURETIMEMODEENUMATTRIBUTE"]._serialized_start = 27273 _globals["_DEPARTURETIMEMODEENUMATTRIBUTE"]._serialized_end = 27384 _globals["_DOORLOCKSTATUSENUMATTRIBUTE"]._serialized_start = 27386 _globals["_DOORLOCKSTATUSENUMATTRIBUTE"]._serialized_end = 27491 _globals["_DOORLOCKSTATUSVEHICLEENUMATTRIBUTE"]._serialized_start = 27493 _globals["_DOORLOCKSTATUSVEHICLEENUMATTRIBUTE"]._serialized_end = 27612 _globals["_DOORSTATUSENUMATTRIBUTE"]._serialized_start = 27614 _globals["_DOORSTATUSENUMATTRIBUTE"]._serialized_end = 27711 _globals["_DOORSTATUSOVERALLENUMATTRIBUTE"]._serialized_start = 27713 _globals["_DOORSTATUSOVERALLENUMATTRIBUTE"]._serialized_end = 27824 _globals["_DOORSTATUSGASENUMATTRIBUTE"]._serialized_start = 27826 _globals["_DOORSTATUSGASENUMATTRIBUTE"]._serialized_end = 27929 _globals["_DRIVINGMODEENUMATTRIBUTE"]._serialized_start = 27931 _globals["_DRIVINGMODEENUMATTRIBUTE"]._serialized_end = 28030 _globals["_EMERGENCYPOWERSUPPLYENUMATTRIBUTE"]._serialized_start = 28032 _globals["_EMERGENCYPOWERSUPPLYENUMATTRIBUTE"]._serialized_end = 28149 _globals["_ENGINEHOODSTATUSENUMATTRIBUTE"]._serialized_start = 28151 _globals["_ENGINEHOODSTATUSENUMATTRIBUTE"]._serialized_end = 28260 _globals["_ENGINESTATEENUMATTRIBUTE"]._serialized_start = 28262 _globals["_ENGINESTATEENUMATTRIBUTE"]._serialized_end = 28361 _globals["_EVSEPAIRINGSTATEENUMATTRIBUTE"]._serialized_start = 28363 _globals["_EVSEPAIRINGSTATEENUMATTRIBUTE"]._serialized_end = 28472 _globals["_EXTERIORMONITORINGSTATUSENUMATTRIBUTE"]._serialized_start = 28474 _globals["_EXTERIORMONITORINGSTATUSENUMATTRIBUTE"]._serialized_end = 28599 _globals["_FILTERPARTICLELOADINGENUMATTRIBUTE"]._serialized_start = 28601 _globals["_FILTERPARTICLELOADINGENUMATTRIBUTE"]._serialized_end = 28720 _globals["_FLIPWINDOWSTATUSENUMATTRIBUTE"]._serialized_start = 28722 _globals["_FLIPWINDOWSTATUSENUMATTRIBUTE"]._serialized_end = 28831 _globals["_HVBATTERYPRECONDAVAILABILITYENUMATTRIBUTE"]._serialized_start = 28834 _globals["_HVBATTERYPRECONDAVAILABILITYENUMATTRIBUTE"]._serialized_end = 28967 _globals["_HVBATTERYTHERMALPROPAGATIONEVENTENUMATTRIBUTE"]._serialized_start = 28970 _globals["_HVBATTERYTHERMALPROPAGATIONEVENTENUMATTRIBUTE"]._serialized_end = 29111 _globals["_HYBRIDWARNINGSENUMATTRIBUTE"]._serialized_start = 29113 _globals["_HYBRIDWARNINGSENUMATTRIBUTE"]._serialized_end = 29218 _globals["_IGNITIONSTATEENUMATTRIBUTE"]._serialized_start = 29220 _globals["_IGNITIONSTATEENUMATTRIBUTE"]._serialized_end = 29323 _globals["_INTERIORMONITORINGSTATUSENUMATTRIBUTE"]._serialized_start = 29325 _globals["_INTERIORMONITORINGSTATUSENUMATTRIBUTE"]._serialized_end = 29450 _globals["_INTERIORPROTECTIONSELECTIONSTATUSENUMATTRIBUTE"]._serialized_start = 29453 _globals["_INTERIORPROTECTIONSELECTIONSTATUSENUMATTRIBUTE"]._serialized_end = 29596 _globals["_KEYACTIVATIONSTATEENUMATTRIBUTE"]._serialized_start = 29598 _globals["_KEYACTIVATIONSTATEENUMATTRIBUTE"]._serialized_end = 29711 _globals["_LANGUAGEHUENUMATTRIBUTE"]._serialized_start = 29713 _globals["_LANGUAGEHUENUMATTRIBUTE"]._serialized_end = 29810 _globals["_LASTTHEFTWARNINGREASONENUMATTRIBUTE"]._serialized_start = 29812 _globals["_LASTTHEFTWARNINGREASONENUMATTRIBUTE"]._serialized_end = 29933 _globals["_OILWARNINGLEVELENUMATTRIBUTE"]._serialized_start = 29935 _globals["_OILWARNINGLEVELENUMATTRIBUTE"]._serialized_end = 30042 _globals["_PARKBRAKESTATUSENUMATTRIBUTE"]._serialized_start = 30044 _globals["_PARKBRAKESTATUSENUMATTRIBUTE"]._serialized_end = 30151 _globals["_PARKCOLLISIONACTIVATIONSTATUSENUMATTRIBUTE"]._serialized_start = 30154 _globals["_PARKCOLLISIONACTIVATIONSTATUSENUMATTRIBUTE"]._serialized_end = 30289 _globals["_PARKCOLLISIONINACTIVEREASONENUMATTRIBUTE"]._serialized_start = 30292 _globals["_PARKCOLLISIONINACTIVEREASONENUMATTRIBUTE"]._serialized_end = 30423 _globals["_PARKCOLLISIONPICTURETRANSFERSTATUSENUMATTRIBUTE"]._serialized_start = 30426 _globals["_PARKCOLLISIONPICTURETRANSFERSTATUSENUMATTRIBUTE"]._serialized_end = 30571 _globals["_PARKCOLLISIONSELECTIONSTATUSENUMATTRIBUTE"]._serialized_start = 30574 _globals["_PARKCOLLISIONSELECTIONSTATUSENUMATTRIBUTE"]._serialized_end = 30707 _globals["_PARKEVENTLEVELENUMATTRIBUTE"]._serialized_start = 30709 _globals["_PARKEVENTLEVELENUMATTRIBUTE"]._serialized_end = 30814 _globals["_PARKEVENTPICTURESELECTIONSTATUSENUMATTRIBUTE"]._serialized_start = 30817 _globals["_PARKEVENTPICTURESELECTIONSTATUSENUMATTRIBUTE"]._serialized_end = 30956 _globals["_PARKEVENTPICTURETRANSMISSIONSTATUSENUMATTRIBUTE"]._serialized_start = 30959 _globals["_PARKEVENTPICTURETRANSMISSIONSTATUSENUMATTRIBUTE"]._serialized_end = 31104 _globals["_PARKEVENTSENSORSTATUSENUMATTRIBUTE"]._serialized_start = 31106 _globals["_PARKEVENTSENSORSTATUSENUMATTRIBUTE"]._serialized_end = 31225 _globals["_PARKEVENTTYPEENUMATTRIBUTE"]._serialized_start = 31227 _globals["_PARKEVENTTYPEENUMATTRIBUTE"]._serialized_end = 31330 _globals["_PERFORMANCELIMITATIONMODESTATUSENUMATTRIBUTE"]._serialized_start = 31333 _globals["_PERFORMANCELIMITATIONMODESTATUSENUMATTRIBUTE"]._serialized_end = 31472 _globals["_PICTURERECORDINGSTATUSENUMATTRIBUTE"]._serialized_start = 31474 _globals["_PICTURERECORDINGSTATUSENUMATTRIBUTE"]._serialized_end = 31595 _globals["_PICTURETRANSFERSELECTIONSTATUSENUMATTRIBUTE"]._serialized_start = 31598 _globals["_PICTURETRANSFERSELECTIONSTATUSENUMATTRIBUTE"]._serialized_end = 31735 _globals["_PRECONDATDEPARTUREENUMATTRIBUTE"]._serialized_start = 31737 _globals["_PRECONDATDEPARTUREENUMATTRIBUTE"]._serialized_end = 31850 _globals["_PRECONDERRORENUMATTRIBUTE"]._serialized_start = 31852 _globals["_PRECONDERRORENUMATTRIBUTE"]._serialized_end = 31953 _globals["_PRECONDNOWENUMATTRIBUTE"]._serialized_start = 31955 _globals["_PRECONDNOWENUMATTRIBUTE"]._serialized_end = 32052 _globals["_PRECONDOPERATINGMODEENUMATTRIBUTE"]._serialized_start = 32054 _globals["_PRECONDOPERATINGMODEENUMATTRIBUTE"]._serialized_end = 32171 _globals["_PRECONDSEATENUMATTRIBUTE"]._serialized_start = 32173 _globals["_PRECONDSEATENUMATTRIBUTE"]._serialized_end = 32272 _globals["_PROTECTIONACTIVATIONSTATUSENUMATTRIBUTE"]._serialized_start = 32275 _globals["_PROTECTIONACTIVATIONSTATUSENUMATTRIBUTE"]._serialized_end = 32404 _globals["_PROTECTIONSENSORSTATUSENUMATTRIBUTE"]._serialized_start = 32406 _globals["_PROTECTIONSENSORSTATUSENUMATTRIBUTE"]._serialized_end = 32527 _globals["_RANGESKIPINDICATIONENUMATTRIBUTE"]._serialized_start = 32529 _globals["_RANGESKIPINDICATIONENUMATTRIBUTE"]._serialized_end = 32644 _globals["_ROOFTOPSTATUSENUMATTRIBUTE"]._serialized_start = 32646 _globals["_ROOFTOPSTATUSENUMATTRIBUTE"]._serialized_end = 32749 _globals["_SELECTEDCHARGEPROGRAMENUMATTRIBUTE"]._serialized_start = 32751 _globals["_SELECTEDCHARGEPROGRAMENUMATTRIBUTE"]._serialized_end = 32870 _globals["_SMARTCHARGINGENUMATTRIBUTE"]._serialized_start = 32872 _globals["_SMARTCHARGINGENUMATTRIBUTE"]._serialized_end = 32975 _globals["_SMARTCHARGINGATDEPARTUREENUMATTRIBUTE"]._serialized_start = 32977 _globals["_SMARTCHARGINGATDEPARTUREENUMATTRIBUTE"]._serialized_end = 33102 _globals["_SOHCALIBRATIONNOTIFICATIONSENUMATTRIBUTE"]._serialized_start = 33105 _globals["_SOHCALIBRATIONNOTIFICATIONSENUMATTRIBUTE"]._serialized_end = 33236 _globals["_SOHCALIBRATIONPLANNEDENUMATTRIBUTE"]._serialized_start = 33238 _globals["_SOHCALIBRATIONPLANNEDENUMATTRIBUTE"]._serialized_end = 33357 _globals["_SOHCALIBRATIONREQUIREDENUMATTRIBUTE"]._serialized_start = 33359 _globals["_SOHCALIBRATIONREQUIREDENUMATTRIBUTE"]._serialized_end = 33480 _globals["_SOHCALIBRATIONSTATEENUMATTRIBUTE"]._serialized_start = 33482 _globals["_SOHCALIBRATIONSTATEENUMATTRIBUTE"]._serialized_end = 33597 _globals["_SOHFAVORABLECONDITIONSENUMATTRIBUTE"]._serialized_start = 33599 _globals["_SOHFAVORABLECONDITIONSENUMATTRIBUTE"]._serialized_end = 33720 _globals["_SPEEDUNITFROMICENUMATTRIBUTE"]._serialized_start = 33722 _globals["_SPEEDUNITFROMICENUMATTRIBUTE"]._serialized_end = 33829 _globals["_STARTERBATTERYSTATEENUMATTRIBUTE"]._serialized_start = 33831 _globals["_STARTERBATTERYSTATEENUMATTRIBUTE"]._serialized_end = 33946 _globals["_SUNROOFEVENTENUMATTRIBUTE"]._serialized_start = 33948 _globals["_SUNROOFEVENTENUMATTRIBUTE"]._serialized_end = 34049 _globals["_SUNROOFSTATUSENUMATTRIBUTE"]._serialized_start = 34051 _globals["_SUNROOFSTATUSENUMATTRIBUTE"]._serialized_end = 34154 _globals["_SUNROOFSTATUSBLINDENUMATTRIBUTE"]._serialized_start = 34156 _globals["_SUNROOFSTATUSBLINDENUMATTRIBUTE"]._serialized_end = 34269 _globals["_TCUCONNECTIONSTATELOWCHANNELENUMATTRIBUTE"]._serialized_start = 34272 _globals["_TCUCONNECTIONSTATELOWCHANNELENUMATTRIBUTE"]._serialized_end = 34405 _globals["_TCUTHERMOSHUTDOWNENUMATTRIBUTE"]._serialized_start = 34407 _globals["_TCUTHERMOSHUTDOWNENUMATTRIBUTE"]._serialized_end = 34518 _globals["_TEMPERATUREUNITHUENUMATTRIBUTE"]._serialized_start = 34520 _globals["_TEMPERATUREUNITHUENUMATTRIBUTE"]._serialized_end = 34631 _globals["_TIMEFORMATHUENUMATTRIBUTE"]._serialized_start = 34633 _globals["_TIMEFORMATHUENUMATTRIBUTE"]._serialized_end = 34734 _globals["_TIREMARKERENUMATTRIBUTE"]._serialized_start = 34736 _globals["_TIREMARKERENUMATTRIBUTE"]._serialized_end = 34833 _globals["_TIRESENSORAVAILABLEENUMATTRIBUTE"]._serialized_start = 34835 _globals["_TIRESENSORAVAILABLEENUMATTRIBUTE"]._serialized_end = 34950 _globals["_TIREWARNINGLEVELPRWENUMATTRIBUTE"]._serialized_start = 34952 _globals["_TIREWARNINGLEVELPRWENUMATTRIBUTE"]._serialized_end = 35067 _globals["_TIREWARNINGLAMPENUMATTRIBUTE"]._serialized_start = 35069 _globals["_TIREWARNINGLAMPENUMATTRIBUTE"]._serialized_end = 35176 _globals["_TIREWARNINGSPRWENUMATTRIBUTE"]._serialized_start = 35178 _globals["_TIREWARNINGSPRWENUMATTRIBUTE"]._serialized_end = 35285 _globals["_TIREWARNINGSRDKENUMATTRIBUTE"]._serialized_start = 35287 _globals["_TIREWARNINGSRDKENUMATTRIBUTE"]._serialized_end = 35394 _globals["_TOWPROTECTIONSELECTIONSTATUSENUMATTRIBUTE"]._serialized_start = 35397 _globals["_TOWPROTECTIONSELECTIONSTATUSENUMATTRIBUTE"]._serialized_end = 35530 _globals["_TRACKINGSTATEHUENUMATTRIBUTE"]._serialized_start = 35532 _globals["_TRACKINGSTATEHUENUMATTRIBUTE"]._serialized_end = 35639 _globals["_TURNOFFENGINEPREWARNINGENUMATTRIBUTE"]._serialized_start = 35641 _globals["_TURNOFFENGINEPREWARNINGENUMATTRIBUTE"]._serialized_end = 35764 _globals["_VEHICLEDATACONNECTIONSTATEENUMATTRIBUTE"]._serialized_start = 35767 _globals["_VEHICLEDATACONNECTIONSTATEENUMATTRIBUTE"]._serialized_end = 35896 _globals["_VEHICLEHEALTHSTATUSENUMATTRIBUTE"]._serialized_start = 35898 _globals["_VEHICLEHEALTHSTATUSENUMATTRIBUTE"]._serialized_end = 36013 _globals["_VEHICLEPOSITIONERRORCODEENUMATTRIBUTE"]._serialized_start = 36015 _globals["_VEHICLEPOSITIONERRORCODEENUMATTRIBUTE"]._serialized_end = 36140 _globals["_VEHICLETHEFTALARMINACTIVEREASONENUMATTRIBUTE"]._serialized_start = 36143 _globals["_VEHICLETHEFTALARMINACTIVEREASONENUMATTRIBUTE"]._serialized_end = 36282 _globals["_WARNINGWASHWATERENUMATTRIBUTE"]._serialized_start = 36284 _globals["_WARNINGWASHWATERENUMATTRIBUTE"]._serialized_end = 36393 _globals["_WEEKDAYENUMATTRIBUTE"]._serialized_start = 36395 _globals["_WEEKDAYENUMATTRIBUTE"]._serialized_end = 36486 _globals["_WINDOWSTATUSENUMATTRIBUTE"]._serialized_start = 36488 _globals["_WINDOWSTATUSENUMATTRIBUTE"]._serialized_end = 36589 _globals["_WINDOWSTATUSBLINDENUMATTRIBUTE"]._serialized_start = 36591 _globals["_WINDOWSTATUSBLINDENUMATTRIBUTE"]._serialized_end = 36702 _globals["_WINDOWSTATUSOVERALLENUMATTRIBUTE"]._serialized_start = 36704 _globals["_WINDOWSTATUSOVERALLENUMATTRIBUTE"]._serialized_end = 36819 _globals["_AMGSTAGEMODEERROROBJECTATTRIBUTE"]._serialized_start = 36821 _globals["_AMGSTAGEMODEERROROBJECTATTRIBUTE"]._serialized_end = 36934 _globals["_CHARGINGBREAKCLOCKTIMEROBJECTATTRIBUTE"]._serialized_start = 36937 _globals["_CHARGINGBREAKCLOCKTIMEROBJECTATTRIBUTE"]._serialized_end = 37067 _globals["_CHARGINGPREDICTIONDEPARTURETIMEOBJECTATTRIBUTE"]._serialized_start = 37070 _globals["_CHARGINGPREDICTIONDEPARTURETIMEOBJECTATTRIBUTE"]._serialized_end = 37211 _globals["_CHARGINGPREDICTIONSOCOBJECTATTRIBUTE"]._serialized_start = 37213 _globals["_CHARGINGPREDICTIONSOCOBJECTATTRIBUTE"]._serialized_end = 37334 _globals["_CHARGINGSCHEDULEACTIVEOBJECTATTRIBUTE"]._serialized_start = 37336 _globals["_CHARGINGSCHEDULEACTIVEOBJECTATTRIBUTE"]._serialized_end = 37459 _globals["_CHARGINGSCHEDULEREQUESTEDOBJECTATTRIBUTE"]._serialized_start = 37462 _globals["_CHARGINGSCHEDULEREQUESTEDOBJECTATTRIBUTE"]._serialized_end = 37591 _globals["_HVBATTERYPRECONDREQUESTSTATEOBJECTATTRIBUTE"]._serialized_start = 37594 _globals["_HVBATTERYPRECONDREQUESTSTATEOBJECTATTRIBUTE"]._serialized_end = 37729 _globals["_HVBATTERYPRECONDSTATEOBJECTATTRIBUTE"]._serialized_start = 37731 _globals["_HVBATTERYPRECONDSTATEOBJECTATTRIBUTE"]._serialized_end = 37852 _globals["_KEYLINEACTIVATIONSTATEOBJECTATTRIBUTE"]._serialized_start = 37855 _globals["_KEYLINEACTIVATIONSTATEOBJECTATTRIBUTE"]._serialized_end = 37983 _globals["_NEXTDEPARTURETIMEOBJECTATTRIBUTE"]._serialized_start = 37986 _globals["_NEXTDEPARTURETIMEOBJECTATTRIBUTE"]._serialized_end = 38186 _globals["_PRECONDOPERABILITYSTATEOBJECTATTRIBUTE"]._serialized_start = 38188 _globals["_PRECONDOPERABILITYSTATEOBJECTATTRIBUTE"]._serialized_end = 38313 _globals["_PRECONDSTATEOBJECTATTRIBUTE"]._serialized_start = 38315 _globals["_PRECONDSTATEOBJECTATTRIBUTE"]._serialized_end = 38418 _globals["_REMOTEUPDATESTARTSTATUSOBJECTATTRIBUTE"]._serialized_start = 38420 _globals["_REMOTEUPDATESTARTSTATUSOBJECTATTRIBUTE"]._serialized_end = 38545 _globals["_WEEKLYPROFILEOBJECTATTRIBUTE"]._serialized_start = 38547 _globals["_WEEKLYPROFILEOBJECTATTRIBUTE"]._serialized_end = 38657 _globals["_AUXHEATWARNINGSARRAYATTRIBUTE"]._serialized_start = 38659 _globals["_AUXHEATWARNINGSARRAYATTRIBUTE"]._serialized_end = 38766 _globals["_CHARGEFLAPSARRAYATTRIBUTE"]._serialized_start = 38768 _globals["_CHARGEFLAPSARRAYATTRIBUTE"]._serialized_end = 38873 _globals["_CHARGEINLETSARRAYATTRIBUTE"]._serialized_start = 38875 _globals["_CHARGEINLETSARRAYATTRIBUTE"]._serialized_end = 38982 _globals["_CHARGEPROGRAMSARRAYATTRIBUTE"]._serialized_start = 38984 _globals["_CHARGEPROGRAMSARRAYATTRIBUTE"]._serialized_end = 39099 _globals["_CHARGINGPOWERRESTRICTIONARRAYATTRIBUTE"]._serialized_start = 39101 _globals["_CHARGINGPOWERRESTRICTIONARRAYATTRIBUTE"]._serialized_end = 39227 _globals["_CHARGINGTIMERARRAYATTRIBUTE"]._serialized_start = 39229 _globals["_CHARGINGTIMERARRAYATTRIBUTE"]._serialized_end = 39338 _globals["_SOCPROFILEARRAYATTRIBUTE"]._serialized_start = 39340 _globals["_SOCPROFILEARRAYATTRIBUTE"]._serialized_end = 39441 _globals["_SPEEDALERTCONFARRAYATTRIBUTE"]._serialized_start = 39443 _globals["_SPEEDALERTCONFARRAYATTRIBUTE"]._serialized_end = 39558 _globals["_TEMPERATUREPOINTSARRAYATTRIBUTE"]._serialized_start = 39560 _globals["_TEMPERATUREPOINTSARRAYATTRIBUTE"]._serialized_end = 39671 _globals["_WEEKLYSETHUARRAYATTRIBUTE"]._serialized_start = 39673 _globals["_WEEKLYSETHUARRAYATTRIBUTE"]._serialized_end = 39775 _globals["_VEHICLESTATUSUPDATE"]._serialized_start = 39779 _globals["_VEHICLESTATUSUPDATE"]._serialized_end = 58200 # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/proto/vehicleapi_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: vehicleapi.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 import custom_components.mbapi2020.proto.acp_pb2 as acp__pb2 import custom_components.mbapi2020.proto.gogo_pb2 as gogo__pb2 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\x10vehicleapi.proto\x12\x05proto\x1a\tacp.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\ngogo.proto"F\n+AcknowledgeAppTwinCommandStatusUpdatesByVIN\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05"\xec\x01\n AppTwinCommandStatusUpdatesByVIN\x12\x17\n\x0fsequence_number\x18\x01 \x01(\x05\x12Q\n\x0eupdates_by_vin\x18\x02 \x03(\x0b\x32\x39.proto.AppTwinCommandStatusUpdatesByVIN.UpdatesByVinEntry\x1a\\\n\x11UpdatesByVinEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x36\n\x05value\x18\x02 \x01(\x0b\x32\'.proto.AppTwinCommandStatusUpdatesByPID:\x02\x38\x01"\xd4\x01\n AppTwinCommandStatusUpdatesByPID\x12\x0b\n\x03vin\x18\x01 \x01(\t\x12Q\n\x0eupdates_by_pid\x18\x02 \x03(\x0b\x32\x39.proto.AppTwinCommandStatusUpdatesByPID.UpdatesByPidEntry\x1aP\n\x11UpdatesByPidEntry\x12\x0b\n\x03key\x18\x01 \x01(\x03\x12*\n\x05value\x18\x02 \x01(\x0b\x32\x1b.proto.AppTwinCommandStatus:\x02\x38\x01"\x91\x02\n\x14\x41ppTwinCommandStatus\x12\x12\n\nprocess_id\x18\x01 \x01(\x03\x12\x12\n\nrequest_id\x18\x02 \x01(\t\x12\x17\n\x0ftimestamp_in_ms\x18\x03 \x01(\x03\x12&\n\x06\x65rrors\x18\x04 \x03(\x0b\x32\x16.proto.VehicleAPIError\x12!\n\x15\x62locking_time_seconds\x18\x05 \x01(\x03\x42\x02\x18\x01\x12\x18\n\x0cpin_attempts\x18\x06 \x01(\x05\x42\x02\x18\x01\x12$\n\x04type\x18\x07 \x01(\x0e\x32\x16.proto.ACP.CommandType\x12-\n\x05state\x18\x08 \x01(\x0e\x32\x1e.proto.VehicleAPI.CommandState"\xa2\x01\n\x1bVehicleAPICommandPostResult\x12\x1d\n\nprocess_id\x18\x01 \x01(\x03R\tprocessid\x12.\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x16.proto.VehicleAPIErrorR\x06\x65rrors\x12\x34\n\x05state\x18\x03 \x01(\x0e\x32\x1e.proto.VehicleAPI.CommandStateR\x05state"\xba\x01\n\x1aVehicleAPICommandGetResult\x12?\n\x07process\x18\x01 \x03(\x0b\x32%.proto.VehicleAPICommandProcessStatusR\x07process\x12\x1f\n\x0bqueue_count\x18\x02 \x01(\x05R\nqueuecount\x12:\n\nqueue_type\x18\x03 \x01(\x0e\x32\x1b.proto.VehicleAPI.QueueTypeR\tqueuetype"\xa0\x01\n\x17VehicleAPIDataGetResult\x12\x36\n\x04\x64\x61ta\x18\x01 \x03(\x0b\x32(.proto.VehicleAPIDataGetResult.DataEntry\x1aM\n\tDataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12/\n\x05value\x18\x02 \x01(\x0b\x32 .proto.VehicleAPIAttributeStatus:\x02\x38\x01"\xa1\x01\n\x19VehicleAPIAttributeStatus\x12,\n\x05value\x18\x03 \x01(\x0b\x32\x16.google.protobuf.ValueR\x05value\x12\x1b\n\x0ftimestamp_in_ms\x18\x02 \x01(\x03R\x02ts\x12\x39\n\x06Status\x18\x01 \x01(\x0e\x32!.proto.VehicleAPI.AttributeStatusR\x06status"\xe7\x02\n\x1eVehicleAPICommandProcessStatus\x12.\n\x06\x65rrors\x18\x01 \x03(\x0b\x32\x16.proto.VehicleAPIErrorR\x06\x65rrors\x12\x1f\n\x0binstance_id\x18\x02 \x01(\tR\ninstanceid\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12\x1d\n\nprocess_id\x18\x04 \x01(\x03R\tprocessid\x12G\n\x13response_parameters\x18\x06 \x01(\x0b\x32\x16.google.protobuf.ValueR\x12responseparameters\x12\x34\n\x05state\x18\x07 \x01(\x0e\x32\x1e.proto.VehicleAPI.CommandStateR\x05state\x12!\n\x0etimestamp_in_s\x18\x08 \x01(\x03R\ttimestamp\x12\x1f\n\x0btracking_id\x18\t \x01(\tR\ntrackingid"\x96\x02\n\x0fVehicleAPIError\x12\x18\n\x04\x63ode\x18\x01 \x01(\tR\nerror-code\x12\x1e\n\x07message\x18\x02 \x01(\tR\rerror-message\x12\x46\n\nattributes\x18\x03 \x03(\x0b\x32&.proto.VehicleAPIError.AttributesEntryR\nattributes\x12\x36\n\nsub_errors\x18\x04 \x03(\x0b\x32\x16.proto.VehicleAPIErrorR\nsub-errors\x1aI\n\x0f\x41ttributesEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12%\n\x05value\x18\x02 \x01(\x0b\x32\x16.google.protobuf.Value:\x02\x38\x01"\x1f\n\x1d\x41ppTwinPendingCommandsRequest"Q\n\x1e\x41ppTwinPendingCommandsResponse\x12/\n\x10pending_commands\x18\x01 \x03(\x0b\x32\x15.proto.PendingCommand"k\n\x0ePendingCommand\x12\x0b\n\x03vin\x18\x01 \x01(\t\x12\x12\n\nprocess_id\x18\x02 \x01(\x03\x12\x12\n\nrequest_id\x18\x03 \x01(\t\x12$\n\x04type\x18\x04 \x01(\x0e\x32\x16.proto.ACP.CommandTypeB \n\x1a\x63om.daimler.mbcarkit.proto\xd0\xe1\x1e\x01\x62\x06proto3' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "vehicleapi_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals["DESCRIPTOR"]._serialized_options = b"\n\032com.daimler.mbcarkit.proto\320\341\036\001" _globals["_APPTWINCOMMANDSTATUSUPDATESBYVIN_UPDATESBYVINENTRY"]._loaded_options = None _globals["_APPTWINCOMMANDSTATUSUPDATESBYVIN_UPDATESBYVINENTRY"]._serialized_options = b"8\001" _globals["_APPTWINCOMMANDSTATUSUPDATESBYPID_UPDATESBYPIDENTRY"]._loaded_options = None _globals["_APPTWINCOMMANDSTATUSUPDATESBYPID_UPDATESBYPIDENTRY"]._serialized_options = b"8\001" _globals["_APPTWINCOMMANDSTATUS"].fields_by_name["blocking_time_seconds"]._loaded_options = None _globals["_APPTWINCOMMANDSTATUS"].fields_by_name["blocking_time_seconds"]._serialized_options = b"\030\001" _globals["_APPTWINCOMMANDSTATUS"].fields_by_name["pin_attempts"]._loaded_options = None _globals["_APPTWINCOMMANDSTATUS"].fields_by_name["pin_attempts"]._serialized_options = b"\030\001" _globals["_VEHICLEAPIDATAGETRESULT_DATAENTRY"]._loaded_options = None _globals["_VEHICLEAPIDATAGETRESULT_DATAENTRY"]._serialized_options = b"8\001" _globals["_VEHICLEAPIERROR_ATTRIBUTESENTRY"]._loaded_options = None _globals["_VEHICLEAPIERROR_ATTRIBUTESENTRY"]._serialized_options = b"8\001" _globals["_ACKNOWLEDGEAPPTWINCOMMANDSTATUSUPDATESBYVIN"]._serialized_start = 80 _globals["_ACKNOWLEDGEAPPTWINCOMMANDSTATUSUPDATESBYVIN"]._serialized_end = 150 _globals["_APPTWINCOMMANDSTATUSUPDATESBYVIN"]._serialized_start = 153 _globals["_APPTWINCOMMANDSTATUSUPDATESBYVIN"]._serialized_end = 389 _globals["_APPTWINCOMMANDSTATUSUPDATESBYVIN_UPDATESBYVINENTRY"]._serialized_start = 297 _globals["_APPTWINCOMMANDSTATUSUPDATESBYVIN_UPDATESBYVINENTRY"]._serialized_end = 389 _globals["_APPTWINCOMMANDSTATUSUPDATESBYPID"]._serialized_start = 392 _globals["_APPTWINCOMMANDSTATUSUPDATESBYPID"]._serialized_end = 604 _globals["_APPTWINCOMMANDSTATUSUPDATESBYPID_UPDATESBYPIDENTRY"]._serialized_start = 524 _globals["_APPTWINCOMMANDSTATUSUPDATESBYPID_UPDATESBYPIDENTRY"]._serialized_end = 604 _globals["_APPTWINCOMMANDSTATUS"]._serialized_start = 607 _globals["_APPTWINCOMMANDSTATUS"]._serialized_end = 880 _globals["_VEHICLEAPICOMMANDPOSTRESULT"]._serialized_start = 883 _globals["_VEHICLEAPICOMMANDPOSTRESULT"]._serialized_end = 1045 _globals["_VEHICLEAPICOMMANDGETRESULT"]._serialized_start = 1048 _globals["_VEHICLEAPICOMMANDGETRESULT"]._serialized_end = 1234 _globals["_VEHICLEAPIDATAGETRESULT"]._serialized_start = 1237 _globals["_VEHICLEAPIDATAGETRESULT"]._serialized_end = 1397 _globals["_VEHICLEAPIDATAGETRESULT_DATAENTRY"]._serialized_start = 1320 _globals["_VEHICLEAPIDATAGETRESULT_DATAENTRY"]._serialized_end = 1397 _globals["_VEHICLEAPIATTRIBUTESTATUS"]._serialized_start = 1400 _globals["_VEHICLEAPIATTRIBUTESTATUS"]._serialized_end = 1561 _globals["_VEHICLEAPICOMMANDPROCESSSTATUS"]._serialized_start = 1564 _globals["_VEHICLEAPICOMMANDPROCESSSTATUS"]._serialized_end = 1923 _globals["_VEHICLEAPIERROR"]._serialized_start = 1926 _globals["_VEHICLEAPIERROR"]._serialized_end = 2204 _globals["_VEHICLEAPIERROR_ATTRIBUTESENTRY"]._serialized_start = 2131 _globals["_VEHICLEAPIERROR_ATTRIBUTESENTRY"]._serialized_end = 2204 _globals["_APPTWINPENDINGCOMMANDSREQUEST"]._serialized_start = 2206 _globals["_APPTWINPENDINGCOMMANDSREQUEST"]._serialized_end = 2237 _globals["_APPTWINPENDINGCOMMANDSRESPONSE"]._serialized_start = 2239 _globals["_APPTWINPENDINGCOMMANDSRESPONSE"]._serialized_end = 2320 _globals["_PENDINGCOMMAND"]._serialized_start = 2322 _globals["_PENDINGCOMMAND"]._serialized_end = 2429 # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/proto/vin_events_pb2.py ================================================ # Generated by the protocol buffer compiler. DO NOT EDIT! # source: vin-events.proto # Protobuf Python Version: 5.29.5 """Generated protocol buffer code.""" from google.protobuf import ( descriptor as _descriptor, descriptor_pool as _descriptor_pool, symbol_database as _symbol_database, ) from google.protobuf.internal import builder as _builder # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( b'\n\x10vin-events.proto\x12\x05proto"3\n\tVINUpdate\x12\x11\n\taddedVINs\x18\x01 \x03(\t\x12\x13\n\x0b\x64\x65letedVINs\x18\x02 \x03(\tB\x1c\n\x1a\x63om.daimler.mbcarkit.protob\x06proto3' ) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "vin_events_pb2", _globals) if not _descriptor._USE_C_DESCRIPTORS: _globals["DESCRIPTOR"]._loaded_options = None _globals["DESCRIPTOR"]._serialized_options = b"\n\032com.daimler.mbcarkit.proto" _globals["_VINUPDATE"]._serialized_start = 27 _globals["_VINUPDATE"]._serialized_end = 78 # @@protoc_insertion_point(module_scope) ================================================ FILE: custom_components/mbapi2020/repairs.py ================================================ """Repairs platform for MBAPI2020.""" from __future__ import annotations from typing import Any import voluptuous as vol from homeassistant import data_entry_flow from homeassistant.components.repairs import RepairsFlow from homeassistant.core import HomeAssistant from .const import DOMAIN class RestartRequiredFixFlow(RepairsFlow): """Handler for an issue fixing flow.""" def __init__(self, issue_id: str) -> None: self.issue_id = issue_id async def async_step_init(self, user_input: dict[str, str] | None = None) -> data_entry_flow.FlowResult: """Handle the first step of a fix flow.""" return await self.async_step_confirm_restart() async def async_step_confirm_restart(self, user_input: dict[str, str] | None = None) -> data_entry_flow.FlowResult: """Handle the confirm step of a fix flow.""" if user_input is not None: await self.hass.services.async_call("homeassistant", "restart") return self.async_create_entry(title="", data={}) return self.async_show_form( step_id="confirm_restart", data_schema=vol.Schema({}), description_placeholders={"name": DOMAIN}, ) async def async_create_fix_flow( hass: HomeAssistant, issue_id: str, data: dict[str, str | int | float | None] | None = None, *args: Any, **kwargs: Any, ) -> RepairsFlow | None: """Create flow.""" if issue_id.startswith("restart_required"): return RestartRequiredFixFlow(issue_id) return None ================================================ FILE: custom_components/mbapi2020/sensor.py ================================================ """Sensor support for Mercedes cars with Mercedes ME. For more details about this component, please refer to the documentation at https://github.com/ReneNulschDE/mbapi2020/ """ from __future__ import annotations from datetime import datetime from homeassistant.components.sensor import RestoreSensor from homeassistant.config_entries import ConfigEntry from homeassistant.const import STATE_UNKNOWN from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import MercedesMeEntity from .const import ( CONF_FT_DISABLE_CAPABILITY_CHECK, DOMAIN, LOGGER, SENSORS, SENSORS_POLL, DefaultValueModeType, SensorConfigFields as scf, ) from .coordinator import MBAPI2020DataUpdateCoordinator def _create_sensor_if_eligible(key, config, car, coordinator, should_poll=False, initial_setup=False): """Check if sensor should be created and return device if eligible.""" # Skip special sensors during dynamic loading, but allow during initial setup if key in ["car", "data_mode"] and not initial_setup: return None if ( config[scf.CAPABILITIES_LIST.value] is None or coordinator.config_entry.options.get(CONF_FT_DISABLE_CAPABILITY_CHECK, False) or car.features.get(config[scf.CAPABILITIES_LIST.value], False) ): device_class = MercedesMESensorPoll if should_poll else MercedesMESensor device = device_class( internal_name=key, config=config, vin=car.finorvin, coordinator=coordinator, should_poll=should_poll, ) # Check eligibility status = device.device_retrieval_status() is_eligible = False if should_poll: is_eligible = status in ["VALID", "NOT_RECEIVED"] or ( config[scf.DEFAULT_VALUE_MODE.value] is not None and config[scf.DEFAULT_VALUE_MODE.value] != DefaultValueModeType.NONE and str(status) not in ["4", "error"] ) else: is_eligible = status in ["VALID", "NOT_RECEIVED", "3", 3] or ( config[scf.DEFAULT_VALUE_MODE.value] is not None and config[scf.DEFAULT_VALUE_MODE.value] != DefaultValueModeType.NONE and str(status) not in ["4", "error"] ) if is_eligible: return device return None async def create_missing_sensors_for_car(car, coordinator, async_add_entities): """Create missing sensors for a specific car.""" missing_sensors = [] # Helper function to check and add eligible devices def _check_and_add_device(device, car, sensor_type="sensor"): if device: if f"sensor.{device.unique_id}" not in car.sensors: missing_sensors.append(device) LOGGER.debug("Sensor added: %s, %s", device._name, f"sensor.{device.unique_id}") # Process regular sensors for key, value in sorted(SENSORS.items()): device = _create_sensor_if_eligible(key, value, car, coordinator, False) _check_and_add_device(device, car) # Process polling sensors for key, value in sorted(SENSORS_POLL.items()): device = _create_sensor_if_eligible(key, value, car, coordinator, True) _check_and_add_device(device, car) if missing_sensors: await async_add_entities(missing_sensors, True) return len(missing_sensors) return 0 async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Setups sensor platform.""" coordinator: MBAPI2020DataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] if not coordinator.client.cars: LOGGER.info("No Cars found.") return sensor_list = [] for car in coordinator.client.cars.values(): for key, value in sorted(SENSORS.items()): device = _create_sensor_if_eligible(key, value, car, coordinator, False, initial_setup=True) if device: sensor_list.append(device) for key, value in sorted(SENSORS_POLL.items()): device = _create_sensor_if_eligible(key, value, car, coordinator, True, initial_setup=True) if device: sensor_list.append(device) async_add_entities(sensor_list, True) class MercedesMESensor(MercedesMeEntity, RestoreSensor): """Representation of a Sensor.""" @property def native_value(self) -> str | int | float | datetime | None: """Return the state.""" return self.state @property def state(self): """Return the state of the sensor.""" if self.device_retrieval_status() in ("NOT_RECEIVED", "4", 4): if self._sensor_config[scf.DEFAULT_VALUE_MODE.value]: if self._sensor_config[scf.DEFAULT_VALUE_MODE.value] == "Zero": return 0 return STATE_UNKNOWN if self.device_retrieval_status() == 3: if self._sensor_config[scf.DEFAULT_VALUE_MODE.value]: if self._sensor_config[scf.DEFAULT_VALUE_MODE.value] == "Zero": return 0 return STATE_UNKNOWN return STATE_UNKNOWN if self._internal_name == "lastParkEvent": if self._state: return datetime.fromtimestamp(int(self._state)) elif self._internal_name == "chargingpowerecolimit": if self._state and int(self._state) <= 0: return None return self._state elif self._internal_name == "chargingpowerkw": if self._state and isinstance(self._state, (int, float)): return round(float(self._state), 1) if self._state and self._state == "error": return STATE_UNKNOWN return self._state async def async_added_to_hass(self): """Add callback after being added to hass.""" self._car.add_sensor(f"sensor.{self._attr_unique_id}") await super().async_added_to_hass() async def async_will_remove_from_hass(self): """Entity being removed from hass.""" self._car.remove_sensor(f"sensor.{self._attr_unique_id}") await super().async_will_remove_from_hass() class MercedesMESensorPoll(MercedesMeEntity, RestoreSensor): """Representation of a Sensor.""" @property def native_value(self) -> str | int | float | datetime | None: """Return the state.""" return self.state @property def state(self): """Return the state of the sensor.""" if self.device_retrieval_status() == "NOT_RECEIVED": return STATE_UNKNOWN if self.device_retrieval_status() == 3: return STATE_UNKNOWN return self._state async def async_added_to_hass(self): """Add callback after being added to hass.""" self._car.add_sensor(f"sensor.{self._attr_unique_id}") await super().async_added_to_hass() async def async_will_remove_from_hass(self): """Entity being removed from hass.""" self._car.remove_sensor(f"sensor.{self._attr_unique_id}") await super().async_will_remove_from_hass() ================================================ FILE: custom_components/mbapi2020/services.py ================================================ """Services for the Blink integration.""" from __future__ import annotations from homeassistant.core import HomeAssistant from homeassistant.exceptions import ServiceValidationError from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import ( CONF_PIN, CONF_TIME, CONF_VIN, DOMAIN, LOGGER, SERVICE_AUXHEAT_CONFIGURE, SERVICE_AUXHEAT_CONFIGURE_SCHEMA, SERVICE_AUXHEAT_START, SERVICE_AUXHEAT_STOP, SERVICE_BATTERY_MAX_SOC_CONFIGURE, SERVICE_BATTERY_MAX_SOC_CONFIGURE_SCHEMA, SERVICE_CHARGE_PROGRAM_CONFIGURE, SERVICE_CHARGING_BREAK_CLOCKTIMER_CONFIGURE, SERVICE_CHARGING_BREAK_CLOCKTIMER_CONFIGURE_SCHEMA, SERVICE_DOORS_LOCK_URL, SERVICE_DOORS_UNLOCK_URL, SERVICE_DOWNLOAD_IMAGES, SERVICE_ENGINE_START, SERVICE_ENGINE_STOP, SERVICE_PRECONDITIONING_CONFIGURE, SERVICE_PRECONDITIONING_CONFIGURE_SCHEMA, SERVICE_PRECONDITIONING_CONFIGURE_SEATS, SERVICE_PRECONDITIONING_CONFIGURE_SEATS_SCHEMA, SERVICE_PREHEAT_START, SERVICE_PREHEAT_START_DEPARTURE_TIME, SERVICE_PREHEAT_START_SCHEMA, SERVICE_PREHEAT_STOP, SERVICE_PREHEAT_STOP_DEPARTURE_TIME, SERVICE_SEND_ROUTE, SERVICE_SEND_ROUTE_SCHEMA, SERVICE_SIGPOS_START, SERVICE_SUNROOF_CLOSE, SERVICE_SUNROOF_OPEN, SERVICE_SUNROOF_TILT, SERVICE_TEMPERATURE_CONFIGURE, SERVICE_TEMPERATURE_CONFIGURE_SCHEMA, SERVICE_VIN_CHARGE_PROGRAM_SCHEMA, SERVICE_VIN_PIN_SCHEMA, SERVICE_VIN_SCHEMA, SERVICE_VIN_TIME_SCHEMA, SERVICE_WINDOWS_CLOSE, SERVICE_WINDOWS_MOVE, SERVICE_WINDOWS_MOVE_SCHEMA, SERVICE_WINDOWS_OPEN, ) def setup_services(hass: HomeAssistant) -> None: """Set up the services for the MBAPI2020 integration.""" domain = hass.data[DOMAIN] def _get_config_entryid(vin: str): for key in iter(domain): if isinstance(domain[key], DataUpdateCoordinator): coordinator = domain[key] if coordinator.client and coordinator.client.cars: if vin in coordinator.client.cars: if coordinator.client.cars[vin].data_collection_mode == "pull": raise ServiceValidationError( "The connection to the MB-server is in pull mode currently. Actions can't be executed in this mode." ) continue return key raise ServiceValidationError( "Given VIN/FIN is not managed by any coordinator or excluded in the integration options." ) async def auxheat_configure(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.auxheat_configure( call.data.get(CONF_VIN), call.data.get("time_selection"), call.data.get("time_1"), call.data.get("time_2"), call.data.get("time_3"), ) async def auxheat_start(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.auxheat_start(call.data.get(CONF_VIN)) async def auxheat_stop(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.auxheat_stop(call.data.get(CONF_VIN)) async def doors_unlock(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.doors_unlock( call.data.get(CONF_VIN), call.data.get(CONF_PIN) ) async def charge_program_configure(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.charge_program_configure( call.data.get(CONF_VIN), call.data.get("charge_program"), call.data.get("max_soc"), ) async def charging_break_clocktimer_configure(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.charging_break_clocktimer_configure( call.data.get(CONF_VIN), call.data.get("status_timer_1"), call.data.get("starttime_timer_1"), call.data.get("stoptime_timer_1"), call.data.get("status_timer_2"), call.data.get("starttime_timer_2"), call.data.get("stoptime_timer_2"), call.data.get("status_timer_3"), call.data.get("starttime_timer_3"), call.data.get("stoptime_timer_3"), call.data.get("status_timer_4"), call.data.get("starttime_timer_4"), call.data.get("stoptime_timer_4"), ) async def doors_lock(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.doors_lock(call.data.get(CONF_VIN)) async def engine_start(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.engine_start( call.data.get(CONF_VIN), call.data.get(CONF_PIN), ) async def engine_stop(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.engine_stop(call.data.get(CONF_VIN)) async def hv_battery_start_conditioning(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.hv_battery_start_conditioning( call.data.get(CONF_VIN) ) async def hv_battery_stop_conditioning(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.hv_battery_stop_conditioning( call.data.get(CONF_VIN) ) async def sigpos_start(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.sigpos_start(call.data.get(CONF_VIN)) async def sunroof_open(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.sunroof_open( call.data.get(CONF_VIN), call.data.get(CONF_PIN), ) async def sunroof_tilt(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.sunroof_tilt( call.data.get(CONF_VIN), call.data.get(CONF_PIN), ) async def sunroof_close(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.sunroof_close(call.data.get(CONF_VIN)) async def preconditioning_configure_seats(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.preconditioning_configure_seats( call.data.get(CONF_VIN), call.data.get("front_left"), call.data.get("front_right"), call.data.get("rear_left"), call.data.get("rear_right"), ) async def preheat_start(call) -> None: if call.data.get("type", 0) == 0: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.preheat_start(call.data.get(CONF_VIN)) else: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.preheat_start_immediate( call.data.get(CONF_VIN) ) async def preheat_start_departure_time(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.preheat_start_departure_time( call.data.get(CONF_VIN), call.data.get(CONF_TIME) ) async def preheat_stop(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.preheat_stop(call.data.get(CONF_VIN)) async def preheat_stop_departure_time(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.preheat_stop_departure_time( call.data.get(CONF_VIN) ) async def preconditioning_configure(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.preconditioning_configure( call.data.get(CONF_VIN), call.data.get("departure_time_mode"), call.data.get("departure_time"), ) async def windows_open(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.windows_open( call.data.get(CONF_VIN), call.data.get(CONF_PIN) ) async def temperature_configure(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.temperature_configure( call.data.get(CONF_VIN), call.data.get("front_left"), call.data.get("front_right"), call.data.get("rear_left"), call.data.get("rear_right"), ) async def windows_close(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.windows_close(call.data.get(CONF_VIN)) async def windows_move(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.windows_move( call.data.get(CONF_VIN), call.data.get("front_left"), call.data.get("front_right"), call.data.get("rear_left"), call.data.get("rear_right"), call.data.get(CONF_PIN), ) async def send_route_to_car(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.send_route_to_car( call.data.get(CONF_VIN), call.data.get("title"), call.data.get("latitude"), call.data.get("longitude"), call.data.get("city"), call.data.get("postcode"), call.data.get("street"), ) async def battery_max_soc_configure(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.battery_max_soc_configure( call.data.get(CONF_VIN), call.data.get("max_soc"), call.data.get("charge_program") ) async def download_images(call) -> None: await domain[_get_config_entryid(call.data.get(CONF_VIN))].client.download_images(call.data.get(CONF_VIN)) # Register all the above services service_mapping = [ ( SERVICE_AUXHEAT_CONFIGURE, auxheat_configure, SERVICE_AUXHEAT_CONFIGURE_SCHEMA, ), (SERVICE_AUXHEAT_START, auxheat_start, SERVICE_VIN_SCHEMA), (SERVICE_AUXHEAT_STOP, auxheat_stop, SERVICE_VIN_SCHEMA), ( SERVICE_BATTERY_MAX_SOC_CONFIGURE, battery_max_soc_configure, SERVICE_BATTERY_MAX_SOC_CONFIGURE_SCHEMA, ), (SERVICE_CHARGE_PROGRAM_CONFIGURE, charge_program_configure, SERVICE_VIN_CHARGE_PROGRAM_SCHEMA), ( SERVICE_CHARGING_BREAK_CLOCKTIMER_CONFIGURE, charging_break_clocktimer_configure, SERVICE_CHARGING_BREAK_CLOCKTIMER_CONFIGURE_SCHEMA, ), (SERVICE_DOORS_LOCK_URL, doors_lock, SERVICE_VIN_SCHEMA), (SERVICE_DOORS_UNLOCK_URL, doors_unlock, SERVICE_VIN_PIN_SCHEMA), (SERVICE_DOWNLOAD_IMAGES, download_images, SERVICE_VIN_SCHEMA), (SERVICE_ENGINE_START, engine_start, SERVICE_VIN_PIN_SCHEMA), (SERVICE_ENGINE_STOP, engine_stop, SERVICE_VIN_SCHEMA), # (SERVICE_HV_BATTERY_START_CONDITIONING, hv_battery_start_conditioning, SERVICE_VIN_SCHEMA), # (SERVICE_HV_BATTERY_STOP_CONDITIONING, hv_battery_stop_conditioning, SERVICE_VIN_SCHEMA), ( SERVICE_PRECONDITIONING_CONFIGURE, preconditioning_configure, SERVICE_PRECONDITIONING_CONFIGURE_SCHEMA, ), ( SERVICE_PRECONDITIONING_CONFIGURE_SEATS, preconditioning_configure_seats, SERVICE_PRECONDITIONING_CONFIGURE_SEATS_SCHEMA, ), (SERVICE_PREHEAT_START, preheat_start, SERVICE_PREHEAT_START_SCHEMA), ( SERVICE_PREHEAT_START_DEPARTURE_TIME, preheat_start_departure_time, SERVICE_VIN_TIME_SCHEMA, ), (SERVICE_PREHEAT_STOP, preheat_stop, SERVICE_VIN_SCHEMA), ( SERVICE_PREHEAT_STOP_DEPARTURE_TIME, preheat_stop_departure_time, SERVICE_VIN_SCHEMA, ), (SERVICE_SEND_ROUTE, send_route_to_car, SERVICE_SEND_ROUTE_SCHEMA), (SERVICE_SIGPOS_START, sigpos_start, SERVICE_VIN_SCHEMA), (SERVICE_SUNROOF_OPEN, sunroof_open, SERVICE_VIN_PIN_SCHEMA), (SERVICE_SUNROOF_TILT, sunroof_tilt, SERVICE_VIN_PIN_SCHEMA), (SERVICE_SUNROOF_CLOSE, sunroof_close, SERVICE_VIN_SCHEMA), (SERVICE_TEMPERATURE_CONFIGURE, temperature_configure, SERVICE_TEMPERATURE_CONFIGURE_SCHEMA), (SERVICE_WINDOWS_OPEN, windows_open, SERVICE_VIN_PIN_SCHEMA), (SERVICE_WINDOWS_CLOSE, windows_close, SERVICE_VIN_SCHEMA), (SERVICE_WINDOWS_MOVE, windows_move, SERVICE_WINDOWS_MOVE_SCHEMA), ] for service_name, service_handler, schema in service_mapping: hass.services.async_register(DOMAIN, service_name, service_handler, schema=schema) def remove_services(hass: HomeAssistant) -> None: """Remove the services for the MBAPI2020 integration.""" LOGGER.debug("Start unload component. Services") hass.services.async_remove(DOMAIN, SERVICE_AUXHEAT_CONFIGURE) hass.services.async_remove(DOMAIN, SERVICE_AUXHEAT_START) hass.services.async_remove(DOMAIN, SERVICE_AUXHEAT_STOP) hass.services.async_remove(DOMAIN, SERVICE_BATTERY_MAX_SOC_CONFIGURE) hass.services.async_remove(DOMAIN, SERVICE_CHARGE_PROGRAM_CONFIGURE) hass.services.async_remove(DOMAIN, SERVICE_CHARGING_BREAK_CLOCKTIMER_CONFIGURE) hass.services.async_remove(DOMAIN, SERVICE_DOORS_LOCK_URL) hass.services.async_remove(DOMAIN, SERVICE_DOORS_UNLOCK_URL) hass.services.async_remove(DOMAIN, SERVICE_DOWNLOAD_IMAGES) hass.services.async_remove(DOMAIN, SERVICE_ENGINE_START) hass.services.async_remove(DOMAIN, SERVICE_ENGINE_STOP) # hass.services.async_remove(DOMAIN, SERVICE_HV_BATTERY_START_CONDITIONING) # hass.services.async_remove(DOMAIN, SERVICE_HV_BATTERY_STOP_CONDITIONING) hass.services.async_remove(DOMAIN, SERVICE_PRECONDITIONING_CONFIGURE) hass.services.async_remove(DOMAIN, SERVICE_PRECONDITIONING_CONFIGURE_SEATS) hass.services.async_remove(DOMAIN, SERVICE_PREHEAT_START) hass.services.async_remove(DOMAIN, SERVICE_PREHEAT_START_DEPARTURE_TIME) hass.services.async_remove(DOMAIN, SERVICE_PREHEAT_STOP) hass.services.async_remove(DOMAIN, SERVICE_PREHEAT_STOP_DEPARTURE_TIME) hass.services.async_remove(DOMAIN, SERVICE_SEND_ROUTE) hass.services.async_remove(DOMAIN, SERVICE_SIGPOS_START) hass.services.async_remove(DOMAIN, SERVICE_SUNROOF_OPEN) hass.services.async_remove(DOMAIN, SERVICE_SUNROOF_TILT) hass.services.async_remove(DOMAIN, SERVICE_SUNROOF_CLOSE) hass.services.async_remove(DOMAIN, SERVICE_TEMPERATURE_CONFIGURE) hass.services.async_remove(DOMAIN, SERVICE_WINDOWS_OPEN) hass.services.async_remove(DOMAIN, SERVICE_WINDOWS_CLOSE) hass.services.async_remove(DOMAIN, SERVICE_WINDOWS_MOVE) ================================================ FILE: custom_components/mbapi2020/services.yaml ================================================ auxheat_configure: description: "Command for configuring the auxiliary heating. It is possible to define three daytimes and select one active time." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: time_selection: description: "The activated auxiliary heating preset time (0=no_selection, 1=time_1, 2=time_2, 3=time_3" example: "0" default: 0 selector: select: options: - "0" - "1" - "2" - "3" time_1: description: "Daytime in minutes after midnight. E.g. valid value for 8 am would be 480. Value range is 0 to 1439." example: "480" default: 0 selector: number: min: 0 max: 1439 step: 1 mode: slider time_2: description: "Daytime in minutes after midnight. E.g. valid value for 8 am would be 480. Value range is 0 to 1439." example: "480" default: 0 selector: number: min: 0 max: 1439 step: 1 mode: slider time_3: description: "Daytime in minutes after midnight. E.g. valid value for 8 am would be 480. Value range is 0 to 1439." example: "480" default: 0 selector: number: min: 0 max: 1439 step: 1 mode: slider auxheat_start: description: "Start the auxiliary heating of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: auxheat_stop: description: "Stop the auxiliary heating of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: battery_max_soc_configure: description: "Configure the maximum value for the state of charge of the HV battery of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: max_soc: description: "The maximum value for the state of charge of the HV battery (Value needs to be between 50 and 100 and divisible by ten)" example: "100" default: 100 selector: select: options: - label: "30% (CLA >= 2025)" value: "30" - label: "40% (CLA >= 2025)" value: "40" - label: "50%" value: "50" - label: "60%" value: "60" - label: "70%" value: "70" - label: "80%" value: "80" - label: "90%" value: "90" - label: "100%" value: "100" charge_program: description: "(optional) Charge Program - (0=Default, 2=Home, 3=Work)" example: "0" default: 0 selector: select: options: - "0" - "2" - "3" translation_key: "charge_program" charge_program_configure: description: "Command to select the charge program." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: charge_program: description: "The activated charge program (0=Default, 2=Home, 3=Work)" required: True example: "0" default: 0 selector: select: options: - "0" - "2" - "3" max_soc: description: "The maximum value for the state of charge of the HV battery (Value needs to be between 50 and 100 and divisible by ten)" example: "100" default: None required: False selector: select: options: - "50" - "60" - "70" - "80" - "90" - "100" doors_unlock: description: "Unlock a car defined by a vin. PIN setup required. See options dialog of the integration." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: pin: description: "security pin" example: "1234" required: False selector: text: doors_lock: description: "Lock a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: engine_start: description: "Start the engine of a car defined by a vin. PIN setup required. See options dialog of the integration." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: pin: description: "Security pin" example: "1234" required: False selector: text: engine_stop: description: "Stop the engine of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: hv_battery_start_conditioning: description: "Start the HV battery conditioning of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: hv_battery_stop_conditioninge_stop: description: "Stop the HV battery conditioning of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: preheat_start: description: "Start the pre-heating of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: type: description: "Method that is used to initiate the start process. 0=Now (Default), 1=Immediate - Use Immediate in case your does not support now." default: "0" example: "0" selector: select: options: - "0" - "1" preheat_start_departure_time: description: "Start the pre-heating of a car defined by a vin and a given departure time." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: time: description: "Departure time in minutes after midnight. E.g. valid value for 8 am would be 480. Value range is 0 to 1439" example: "480" default: 0 selector: number: min: 0 max: 1439 step: 1 mode: slider preheat_stop: description: "Stop the pre-heating of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: preheat_stop_departure_time: description: "Stop the pre-heating (departure mode) of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: preconditioning_configure: description: "Configure preconditioning departure time mode. Use mode 0 to disable scheduled departure preconditioning. Note: WEEKLY_DEPARTURE mode is not available on all car models." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: departure_time_mode: description: "Departure time mode: 0=DISABLED, 1=SINGLE_DEPARTURE, 2=WEEKLY_DEPARTURE" example: "0" default: 0 selector: select: options: - label: "Disabled" value: "0" - label: "Single Departure" value: "1" - label: "Weekly Departure" value: "2" departure_time: description: "Departure time in minutes after midnight (0-1439). Only used when mode > 0." example: "480" default: 0 required: False selector: number: min: 0 max: 1439 step: 1 mode: slider sigpos_start: description: "Start light signaling of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: sunroof_open: description: "Open the sunroof of a car defined by a vin. PIN setup required. See options dialog of the integration." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: pin: description: "Security pin" example: "1234" required: False selector: text: sunroof_tilt: description: "Tilt the sunroof of a car defined by a vin. PIN setup required. See options dialog of the integration." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: pin: description: "Security pin" example: "1234" required: False selector: text: sunroof_close: description: "Close the sunroof of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: windows_open: description: "Open the windows of a car defined by a vin. PIN setup required. See options dialog of the integration." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: pin: description: "security pin" example: "1234" required: False selector: text: windows_close: description: "Close the windows of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: windows_move: description: "Move the windows to the defined positions of a car defined by a vin. PIN setup required. See options dialog of the integration." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: pin: description: "Security pin" example: "1234" required: False selector: text: front_left: description: "The new position of the front left window (Value needs to be between 0 and 100 and divisible by ten)." example: "80" required: False selector: select: options: - "0" - "10" - "20" - "30" - "40" - "50" - "60" - "70" - "80" - "90" - "100" front_right: description: "The new position of the front right window (Value needs to be between 0 and 100 and divisible by ten)." example: "80" required: False selector: select: options: - "0" - "10" - "20" - "30" - "40" - "50" - "60" - "70" - "80" - "90" - "100" rear_left: description: "The new position of the rear left window (Value needs to be between 0 and 100 and divisible by ten)." example: "80" required: False selector: select: options: - "0" - "10" - "20" - "30" - "40" - "50" - "60" - "70" - "80" - "90" - "100" rear_right: description: "The new position of the front left window (Value needs to be between 0 and 100 and divisible by ten)." example: "80" required: False selector: select: options: - "0" - "10" - "20" - "30" - "40" - "50" - "60" - "70" - "80" - "90" - "100" send_route: description: "Sends a route to the car. (Single location only)" fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: title: description: "title of the route" example: "Brandenburger Tor" required: True selector: text: latitude: description: "Latitude of the location" example: "52.5162746" required: True selector: text: longitude: description: "Longitude of the location" example: "13.3755154" required: True selector: text: city: description: "City name of the location" example: "Berlin" required: True selector: text: postcode: description: "Postcode of the location" example: "10117" required: True selector: text: street: description: "Streetname of the location" example: "Pariser Platz" required: True selector: text: download_images: description: "Download the images and save it to the component folder." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: charging_break_clocktimer_configure: description: "Configure charging breaks (AC only)" fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: status_timer_1: description: "Status Timer 1" default: "notset" selector: select: translation_key: "charging_break_clocktimer_configure_action" options: - "notset" - "active" - "inactive" starttime_timer_1: description: "Start time (Timer 1)" selector: time: stoptime_timer_1: description: "Stop time (Timer 1)" selector: time: status_timer_2: description: "Status Timer 2" default: "notset" selector: select: translation_key: "charging_break_clocktimer_configure_action" options: - "notset" - "active" - "inactive" starttime_timer_2: description: "Start time (Timer 2)" selector: time: stoptime_timer_2: description: "Stop time (Timer 2)" selector: time: status_timer_3: description: "Status Timer 3" default: "notset" selector: select: translation_key: "charging_break_clocktimer_configure_action" options: - "notset" - "active" - "inactive" starttime_timer_3: description: "Start time (Timer 3)" selector: time: stoptime_timer_3: description: "Stop time (Timer 3)" selector: time: status_timer_4: description: "Status Timer 4" default: "notset" selector: select: translation_key: "charging_break_clocktimer_configure_action" options: - "notset" - "active" - "inactive" starttime_timer_4: description: "Start time (Timer 4)" selector: time: stoptime_timer_4: description: "Stop time (Timer 4)" selector: time: preconditioning_configure_seats: description: "Configure which seats should be preconditioned of a car defined by a vin." fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: front_left: description: "Activate if the front left seat should be preconditioned." required: True selector: boolean: front_right: description: "Activate if the front right seat should be preconditioned." required: True selector: boolean: rear_left: description: "Activate if the rear left seat should be preconditioned." required: True selector: boolean: rear_right: description: "Activate if the rear right seat should be preconditioned." required: True selector: boolean: temperature_configure: description: "Configure the temperature for the allowed zones in a car. " fields: vin: description: "vin of the car" example: "Wxxxxxxxxxxxxxx" required: True selector: text: front_left: description: "Target temperature for the zone front_left in CELSIUS" required: False selector: select: translation_key: "temperature_configure" options: - "0" - "16" - "16.5" - "17" - "17.5" - "18" - "18.5" - "19" - "19.5" - "20" - "20.5" - "21" - "21.5" - "22" - "22.5" - "23" - "23.5" - "24" - "24.5" - "25" - "25.5" - "26" - "26.5" - "27" - "27.5" - "28" - "30" front_right: description: "Target temperature for the zone front_right in CELSIUS" required: False selector: select: translation_key: "temperature_configure" options: - "0" - "16" - "16.5" - "17" - "17.5" - "18" - "18.5" - "19" - "19.5" - "20" - "20.5" - "21" - "21.5" - "22" - "22.5" - "23" - "23.5" - "24" - "24.5" - "25" - "25.5" - "26" - "26.5" - "27" - "27.5" - "28" - "30" rear_left: description: "Target temperature for the zone rear_left in CELSIUS. (if available)" required: False selector: select: translation_key: "temperature_configure" options: - "0" - "16" - "16.5" - "17" - "17.5" - "18" - "18.5" - "19" - "19.5" - "20" - "20.5" - "21" - "21.5" - "22" - "22.5" - "23" - "23.5" - "24" - "24.5" - "25" - "25.5" - "26" - "26.5" - "27" - "27.5" - "28" - "30" rear_right: description: "Target temperature for the zone rear_right in CELSIUS. (if available)" required: False selector: select: translation_key: "temperature_configure" options: - "0" - "16" - "16.5" - "17" - "17.5" - "18" - "18.5" - "19" - "19.5" - "20" - "20.5" - "21" - "21.5" - "22" - "22.5" - "23" - "23.5" - "24" - "24.5" - "25" - "25.5" - "26" - "26.5" - "27" - "27.5" - "28" - "30" ================================================ FILE: custom_components/mbapi2020/switch.py ================================================ """Switch support for Mercedes cars with Mercedes ME. For more details about this component, please refer to the documentation at https://github.com/ReneNulschDE/mbapi2020/ """ from __future__ import annotations from collections.abc import Callable, Coroutine from dataclasses import dataclass from typing import Any from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.event import async_call_later from homeassistant.helpers.restore_state import RestoreEntity from . import MercedesMeEntity, MercedesMeEntityDescription from .car import Car from .const import CONF_FT_DISABLE_CAPABILITY_CHECK, DOMAIN, LOGGER, STATE_CONFIRMATION_DURATION from .coordinator import MBAPI2020DataUpdateCoordinator from .helper import LogHelper as loghelper @dataclass(frozen=True, kw_only=True) class MercedesMeSwitchEntityDescription(MercedesMeEntityDescription, SwitchEntityDescription): """Configuration class for MercedesMe switch entities.""" is_on_fn: Callable[[MercedesMeSwitch], Callable[[], Coroutine[Any, Any, bool]]] turn_on_fn: Callable[[MercedesMeSwitch], Callable[[], Coroutine[Any, Any, None]]] turn_off_fn: Callable[[MercedesMeSwitch], Callable[[], Coroutine[Any, Any, None]]] SWITCH_DESCRIPTIONS: list[MercedesMeSwitchEntityDescription] = [ MercedesMeSwitchEntityDescription( key="precond", translation_key="precond", icon="mdi:hvac", is_on_fn=lambda self: self._get_car_value("precond", "precondStatus", "value", default_value=False), turn_on_fn=lambda self, **kwargs: self._coordinator.client.preheat_start_universal(self._vin), turn_off_fn=lambda self, **kwargs: self._coordinator.client.preheat_stop(self._vin), check_capability_fn=lambda car: car.check_capabilities( ["ZEV_PRECONDITIONING_START", "ZEV_PRECONDITIONING_STOP"] ), ), MercedesMeSwitchEntityDescription( key="auxheat", translation_key="auxheat", icon="mdi:hvac", is_on_fn=lambda self: self._get_car_value("auxheat", "auxheatActive", "value", default_value=False), turn_on_fn=lambda self, **kwargs: self._coordinator.client.auxheat_start(self._vin), turn_off_fn=lambda self, **kwargs: self._coordinator.client.auxheat_stop(self._vin), check_capability_fn=lambda car: car.check_capabilities(["AUXHEAT_START", "AUXHEAT_STOP", "auxHeat"]), ), ] class MercedesMeSwitch(MercedesMeEntity, SwitchEntity, RestoreEntity): """Representation of a Mercedes Me Switch.""" def __init__(self, description: MercedesMeSwitchEntityDescription, vin, coordinator) -> None: """Initialize the switch with methods for handling on/off commands.""" # Initialize command tracking variables self._expected_state = None # True for on, False for off, or None self._state_confirmation_duration = STATE_CONFIRMATION_DURATION self._confirmation_handle = None super().__init__(description.key, description, vin, coordinator) async def async_turn_on(self, **kwargs: dict) -> None: """Turn the device component on.""" await self._async_handle_state_change(state=True, **kwargs) async def async_turn_off(self, **kwargs: dict) -> None: """Turn the device component off.""" await self._async_handle_state_change(state=False, **kwargs) async def _async_handle_state_change(self, state: bool, **kwargs) -> None: """Handle changing the device state and manage confirmation duration.""" # Set the expected state based on the desired state self._expected_state = state try: # Execute the appropriate method and handle any exceptions if state: await self.entity_description.turn_on_fn(self, **kwargs) else: await self.entity_description.turn_off_fn(self, **kwargs) # Cancel any existing confirmation handle if self._confirmation_handle: self._confirmation_handle() # Schedule state reset after confirmation duration self._confirmation_handle = async_call_later( self.hass, self._state_confirmation_duration, self._reset_expected_state ) except Exception as e: # Log the error and reset state if needed LOGGER.error( "Error changing state to %s for entity '%s': %s", "on" if state else "off", self.entity_description.translation_key, str(e), ) self._expected_state = None if self._confirmation_handle: self._confirmation_handle() self._confirmation_handle = None self.async_write_ha_state() async def _reset_expected_state(self, _): """Reset the expected state after confirmation duration and update the state.""" self._attr_is_on = not self._expected_state self._expected_state = None self._confirmation_handle = None self.async_write_ha_state() def _mercedes_me_update(self) -> None: """Update Mercedes Me entity.""" try: actual_state = self.entity_description.is_on_fn(self) except Exception as e: LOGGER.error("Error getting actual state for %s: %s", self.name, str(e)) self._attr_available = False return if self._expected_state is not None: if actual_state == self._expected_state: # Expected state reached, cancel confirmation duration if self._confirmation_handle: self._confirmation_handle() self._confirmation_handle = None self._expected_state = None else: # Return expected state during the confirmation duration self._attr_is_on = self._expected_state else: self._attr_is_on = actual_state self.async_write_ha_state() @property def assumed_state(self) -> bool: """Return True if the state is assumed.""" return self._expected_state is not None async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Set up the switch platform for Mercedes Me.""" coordinator: MBAPI2020DataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id] skip_capability_check: bool = config_entry.options.get(CONF_FT_DISABLE_CAPABILITY_CHECK, False) def check_capability(car: Car, description: MercedesMeSwitchEntityDescription) -> bool: """Check if the car supports the necessary capability for the given feature description.""" if not skip_capability_check and not description.check_capability_fn(car): vin_masked = loghelper.Mask_VIN(car.finorvin) LOGGER.debug( "Skipping feature '%s' for VIN '%s' due to lack of required capability", description.key, vin_masked ) return False return True def create_entity(description: MercedesMeSwitchEntityDescription, car: Car) -> MercedesMeSwitch | None: """Create a MercedesMeSwitch entity for the car based on the given description.""" vin_masked = loghelper.Mask_VIN(car.finorvin) try: entity = MercedesMeSwitch(description, car.finorvin, coordinator) LOGGER.debug("Created switch entity for VIN: '%s', feature: '%s'", vin_masked, description.key) except Exception: LOGGER.error( "Error creating switch entity for VIN: '%s', feature: '%s'. Exception:", vin_masked, description.key, exc_info=True, ) return None else: return entity entities: list[MercedesMeSwitch] = [ entity for car in coordinator.client.cars.values() # Iterate over all cars for description in SWITCH_DESCRIPTIONS # Iterate over all feature descriptions if check_capability(car, description) # Check if the car supports the feature and (entity := create_entity(description, car)) # Create the entity if possible ] async_add_entities(entities) ================================================ FILE: custom_components/mbapi2020/system_health.py ================================================ """Provide info to system health.""" from __future__ import annotations from homeassistant.components import system_health from homeassistant.core import HomeAssistant, callback from homeassistant.loader import async_get_integration from .const import DOMAIN, REST_API_BASE from .coordinator import MBAPI2020DataUpdateCoordinator @callback def async_register(hass: HomeAssistant, register: system_health.SystemHealthRegistration) -> None: """Register system health callbacks.""" register.async_register_info(system_health_info) async def system_health_info(hass: HomeAssistant): """Get info for the info page.""" integration = await async_get_integration(hass, DOMAIN) if DOMAIN in hass.data: domain = hass.data[DOMAIN] first_coordinator: MBAPI2020DataUpdateCoordinator = None used_cars: int = 0 for key in iter(domain): if isinstance(domain[key], MBAPI2020DataUpdateCoordinator): coordinator = domain[key] if not first_coordinator: first_coordinator = coordinator if coordinator.client and coordinator.client.cars: used_cars += len(coordinator.client.cars) if first_coordinator and first_coordinator.client and first_coordinator.client.websocket: websocket_connection_state = str(first_coordinator.client.websocket.connection_state) else: websocket_connection_state = "unknown" return { "api_endpoint_reachable": system_health.async_check_can_reach_url(hass, REST_API_BASE), "websocket_connection_state": websocket_connection_state, "cars_connected": used_cars, "version": integration.manifest.get("version"), } return { "status": "Disabled/Deleted", "version": integration.manifest.get("version"), } ================================================ FILE: custom_components/mbapi2020/translations/cs.json ================================================ { "config": { "abort": { "already_configured": "Komponenta je již nakonfigurována.", "reauth_successful": "Opětovné ověření úspěšné! Probíhá načítání komponenty." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Neznámá chyba. Pro více informací zkontrolujte logy Home Assistant.", "2fa_required": "Účty s dvoufaktorovým ověřením (2FA) nejsou podporovány.", "legal_terms": "Nejprve musíte přijmout právní podmínky na webových stránkách Mercedes" }, "step": { "user": { "data": { "region": "Region" }, "description": "Vyberte svůj region.", "title": "Nastavení připojení Mercedes ME 2020" }, "credentials": { "data": { "username": "MB uživatelské jméno (e-mailová adresa)", "password": "Heslo" }, "description": "Zadejte údaje svého účtu.", "title": "Mercedes ME 2020 - Přihlášení" }, "pin": { "data": { "password": "TAN (přijatý e-mailem nebo SMS)" }, "description": "Zadejte TAN, který jste obdrželi e-mailem nebo SMS, pro dokončení ověření. Pokud jste TAN neobdrželi, zkontrolujte prosím svou e-mailovou schránku (včetně spamu) nebo SMS zprávy.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Pro dokončení aktualizace ověření je vyžadován restart Home Assistant. Kliknutím na Odeslat restartujte nyní.", "title": "Vyžadován restart" } } }, "title": "Vyžadován restart" } }, "options": { "abort": { "already_configured": "Komponenta je již nakonfigurována.", "reauth_successful": "Opětovné ověření úspěšné! Probíhá znovunačítání komponenty." }, "step": { "init": { "data": { "cap_check_disabled": "Zakázat kontrolu funkcí", "enable_china_gcj_02": "Povolit překlad GCJ-02 (pouze Čína)", "delete_auth_file": "Odstranit autentizační token. Vyžaduje restart Home Assistant po uložení.", "excluded_cars": "Vyloučené VINy (oddělené čárkou)", "pin": "Bezpečnostní PIN (vytvořený v mobilní aplikaci)", "save_files": "POUZE PRO DEBUG: Povolit ukládání zpráv serveru do složky zpráv", "overwrite_cap_precondnow": "Exp: Přepsat schopnost precondnow (nastavit na true)" }, "description": "Nakonfigurujte své možnosti. Některé změny vyžadují restart Home Assistant.", "title": "Možnosti Mercedes ME 2020" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API dostupné", "websocket_connection_state": "MB WS stav", "cars_connected": "Připojené vozy", "version": "Verze" } }, "services": { "refresh_access_token": { "name": "Obnovit přístupový token", "description": "Obnovit přístupový token API" }, "auxheat_configure": { "name": "Konfigurace přídavného topení", "description": "Příkaz pro nastavení přídavného topení. Je možné definovat tři časy během dne a vybrat jeden aktivní čas.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "time_selection": { "name": "Výběr času", "description": "Aktivovaný přednastavený čas přídavného topení (0=žádný_výběr, 1=čas_1, 2=čas_2, 3=čas_3)" }, "time_1": { "name": "time_1", "description": "Denní doba v minutách po půlnoci. Např. platná hodnota pro 8 hodin ráno je 480. Rozsah hodnot 0-1439." }, "time_2": { "name": "time_2", "description": "Denní doba v minutách po půlnoci. Např. platná hodnota pro 8 hodin ráno je 480. Rozsah hodnot 0-1439." }, "time_3": { "name": "time_3", "description": "Denní doba v minutách po půlnoci. Např. platná hodnota pro 8 hodin ráno je 480. Rozsah hodnot 0-1439." } } }, "auxheat_start": { "name": "Spustit přídavné topení", "description": "Spustit přídavné topení vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "auxheat_stop": { "name": "Zastavit přídavné topení", "description": "Zastavit přídavné topení vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "battery_max_soc_configure": { "name": "Konfigurace maximálního stavu nabití baterie", "description": "Konfigurace maximální hodnoty pro stav nabití HV baterie vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "max_soc": { "name": "Maximální stav nabití", "description": "Maximální hodnota pro stav nabití HV baterie (hodnota musí být mezi 50 (některé novější vozy jako 2025 CLA podporují 30) a 100 a dělitelná deseti)" }, "charge_program": { "name": "Nabíjecí program", "description": "(Volitelné, Výchozí=0) Nabíjecí program ke změně (0=Výchozí, 2=Domov, 3=Práce) (nepoužívá se pro 2025 CLA)" } } }, "charge_program_configure": { "name": "Konfigurace nabíjecího programu", "description": "Příkaz pro výběr nabíjecího programu.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "charge_program": { "name": "Nabíjecí program", "description": "Aktivovaný nabíjecí program (0=Výchozí, 2=Domov, 3=Práce)" }, "max_soc": { "name": "Maximální stav nabití", "description": "Maximální hodnota pro stav nabití HV baterie (hodnota musí být mezi 50 a 100 a dělitelná deseti)" } } }, "doors_unlock": { "name": "Odemknout dveře", "description": "Odemknutí vozu definovaného pomocí VIN. Vyžaduje nastavení PINu. Viz dialog s možnostmi integrace.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "pin": { "name": "PIN", "description": "Bezpečnostní PIN, vyžadován, pokud není uložen v nastavení." } } }, "doors_lock": { "name": "Zamknout dveře", "description": "Zamknutí vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "download_images": { "name": "Stáhnout obrázky", "description": "Stáhnout obrázky do složky zdrojů komponenty pro vůz definovaný pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "engine_start": { "name": "Spustit motor", "description": "Spustit motor vozu definovaného pomocí VIN. Vyžaduje nastavení PINu. Viz dialog s možnostmi integrace.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "pin": { "name": "PIN", "description": "Bezpečnostní PIN, vyžadován, pokud není uložen v nastavení." } } }, "engine_stop": { "name": "Zastavit motor", "description": "Zastavit motor vozu definovaného pomocí VIN. Vyžaduje nastavení PINu. Viz dialog s možnostmi integrace.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "hv_battery_start_conditioning": { "name": "Spustit kondicionování HV baterie", "description": "Spustit kondicionování HV baterie vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "hv_battery_stop_conditioning": { "name": "Zastavit kondicionování HV baterie", "description": "Zastavit kondicionování HV baterie vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "preconditioning_configure_seats": { "name": "Konfigurace předkondicionování sedadel", "description": "Odeslat příkaz k předkondicionování sedadel do vozu definovaného podle VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "front_left": { "name": "Přední levé", "description": "Aktivovat, pokud by mělo být předkondicionováno přední levé sedadlo." }, "front_right": { "name": "Přední pravé", "description": "Aktivovat, pokud by mělo být předkondicionováno přední pravé sedadlo." }, "rear_left": { "name": "Zadní levé", "description": "Aktivovat, pokud by mělo být předkondicionováno zadní levé sedadlo." }, "rear_right": { "name": "Zadní pravé", "description": "Aktivovat, pokud by mělo být předkondicionováno zadní pravé sedadlo." } } }, "preheat_start": { "name": "Spustit předkondicionování", "description": "Spustit předkondicionování vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "type": { "name": "Typ", "description": "Metoda použitá pro zahájení procesu. 0=Nyní (Výchozí), 1=Okamžitě - Použijte Okamžitě v případě, že váš vůz nepodporuje Nyní." } } }, "preheat_start_departure_time": { "name": "Spustit předkondicionování s časem odjezdu", "description": "Spustit předkondicionování vozu definovaného pomocí VIN a zadaného času odjezdu.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "time": { "name": "Čas", "description": "Čas odjezdu v minutách po půlnoci. Např. platná hodnota pro 8 hodin ráno je 480. Rozsah hodnot 0-1439." } } }, "preheat_stop": { "name": "Zastavit předkondicionování", "description": "Zastavit předkondicionování vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "preheat_stop_departure_time": { "name": "Zastavit předkondicionování s časem odjezdu", "description": "Zastavit předkondicionování s nastaveným časem odjezdu vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "preconditioning_configure": { "name": "Konfigurace předkondicionování odjezdu", "description": "Konfigurace režimu času odjezdu předkondicionování. Použijte režim 0 (Deaktivováno) pro zrušení naplánovaného předkondicionování.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "departure_time_mode": { "name": "Režim času odjezdu", "description": "0=Deaktivováno, 1=Jednorázový odjezd, 2=Týdenní odjezd" }, "departure_time": { "name": "Čas odjezdu", "description": "Čas odjezdu v minutách po půlnoci (0-1439). Použije se pouze při režimu > 0." } } }, "sigpos_start": { "name": "Spustit světelnou signalizaci", "description": "Spustit světelnou signalizaci vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "sunroof_open": { "name": "Otevřít střešní okno", "description": "Otevřít střešní okno vozu definovaného pomocí VIN. Vyžaduje nastavení PINu. Viz dialog s možnostmi integrace.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "pin": { "name": "PIN", "description": "Bezpečnostní PIN, vyžadován, pokud není uložen v nastavení." } } }, "sunroof_tilt": { "name": "Naklonit střešní okno", "description": "Naklonit střešní okno vozu definovaného pomocí VIN. Vyžaduje nastavení PINu. Viz dialog s možnostmi integrace.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "pin": { "name": "PIN", "description": "Bezpečnostní PIN, vyžadován, pokud není uložen v nastavení." } } }, "sunroof_close": { "name": "Zavřít střešní okno", "description": "Zavřít střešní okno vozu definovaného pomocí VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "temperature_configure": { "name": "Nastavení cílové teploty (předkondicionování/přídavné topení)", "description": "Nakonfigurujte cílové teploty pro předkondicionování/přídavné topení pro zóny ve voze definovaném podle VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "front_left": { "name": "Přední levé", "description": "Cílová teplota pro zónu přední levé ve stupních CELSIA." }, "front_right": { "name": "Přední pravé", "description": "Cílová teplota pro zónu přední pravé ve stupních CELSIA." }, "rear_left": { "name": "Zadní levé", "description": "Cílová teplota pro zónu zadní levé ve stupních CELSIA. (pokud je k dispozici)" }, "rear_right": { "name": "Zadní pravé", "description": "Cílová teplota pro zónu zadní pravé ve stupních CELSIA. (pokud je k dispozici)" } } }, "windows_open": { "name": "Otevřít okna", "description": "Otevřít okna vozu definovaného pomocí VIN. Vyžaduje nastavení PINu. Viz dialog s možnostmi integrace.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "pin": { "name": "PIN", "description": "Bezpečnostní PIN, vyžadován, pokud není uložen v nastavení." } } }, "windows_close": { "name": "Zavřít okna", "description": "Zavřít okna vozu definovaného pomocí VIN. Vyžaduje nastavení PINu. Viz dialog s možnostmi integrace.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" } } }, "windows_move": { "name": "Pohyb oken", "description": "Přesunout okna vozu definovaného pomocí VIN na novou pozici. Vyžaduje nastavení PINu. Viz dialog s možnostmi integrace.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "pin": { "name": "PIN", "description": "Bezpečnostní PIN, vyžadován, pokud není uložen v nastavení." }, "front_left": { "name": "Přední levé", "description": "Nová pozice předního levého okna (0=zavřené, 10=ventilace, 100=otevřené)" }, "front_right": { "name": "Přední pravé", "description": "Nová pozice předního pravého okna (0=zavřené, 10=ventilace, 100=otevřené)" }, "rear_left": { "name": "Zadní levé", "description": "Nová pozice zadního levého okna (0=zavřené, 10=ventilace, 100=otevřené)" }, "rear_right": { "name": "Zadní pravé", "description": "Nová pozice zadního pravého okna (0=zavřené, 10=ventilace, 100=otevřené)" } } }, "send_route": { "name": "Odeslat trasu", "description": "Poslat trasu do vozu. (Pouze jedna poloha)", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "title": { "name": "Název", "description": "Název trasy" }, "latitude": { "name": "Zeměpisná šířka", "description": "Zeměpisná šířka místa" }, "longitude": { "name": "Zeměpisná délka", "description": "Zeměpisná délka místa" }, "city": { "name": "Město", "description": "Název města" }, "postcode": { "name": "PSČ", "description": "PSČ místa" }, "street": { "name": "Ulice", "description": "Název ulice" } } }, "charging_break_clocktimer_configure": { "name": "Nastavení časovače přestávky nabíjení", "description": "Nastavte přestávky při nabíjení (pouze AC). Tímto přepíšete celé nastavení pro všechny časové sloty ve vašem voze.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN vozu" }, "status_timer_1": { "name": "Stav (Časovač 1)", "description": "" }, "starttime_timer_1": { "name": "Čas začátku (Časovač 1)", "description": "Čas začátku okna přestávky nabíjení (Časovač 1)" }, "stoptime_timer_1": { "name": "Čas ukončení (Časovač 1)", "description": "Čas ukončení okna přestávky nabíjení (Časovač 1)" }, "status_timer_2": { "name": "Stav (Časovač 2)", "description": "" }, "starttime_timer_2": { "name": "Čas začátku (Časovač 2)", "description": "Čas začátku okna přestávky nabíjení (Časovač 2)" }, "stoptime_timer_2": { "name": "Čas ukončení (Časovač 2)", "description": "Čas ukončení okna přestávky nabíjení (Časovač 2)" }, "status_timer_3": { "name": "Stav (Časovač 3)", "description": "" }, "starttime_timer_3": { "name": "Čas začátku (Časovač 3)", "description": "Čas začátku okna přestávky nabíjení (Časovač 3)" }, "stoptime_timer_3": { "name": "Čas ukončení (Časovač 3)", "description": "Čas ukončení okna přestávky nabíjení (Časovač 3)" }, "status_timer_4": { "name": "Stav (Časovač 4)", "description": "" }, "starttime_timer_4": { "name": "Čas začátku (Časovač 4)", "description": "Čas začátku okna přestávky nabíjení (Časovač 4)" }, "stoptime_timer_4": { "name": "Čas ukončení (Časovač 4)", "description": "Čas ukončení okna přestávky nabíjení (Časovač 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Nabíjení aktivní" } }, "sensor": { "chargingpowerecolimit": { "name": "Limit nabíjecího výkonu" }, "auxheatstatus": { "state": { "0": "Neaktivní", "1": "Normální vytápění", "2": "Normální větrání", "3": "Manuální vytápění", "4": "Dodatečné vytápění", "5": "Dodatečné větrání", "6": "Automatické vytápění" } }, "chargeflapacstatus": { "state": { "0": "Otevřené", "1": "Zavřené", "2": "Klapka stisknuta", "3": "Neznámé" } }, "chargeflapdcstatus": { "state": { "0": "Otevřené", "1": "Zavřené", "2": "Klapka stisknuta", "3": "Neznámé" } }, "chargingstatus": { "state": { "0": "Nabíjení", "1": "Nabíjení ukončeno", "2": "Přestávka nabíjení", "3": "Odpojeno", "4": "Chyba", "5": "Pomalé", "6": "Rychlé", "7": "Vybíjení", "8": "Nenabíjí se", "9": "Pomalé nabíjení po dosažení cíle", "10": "Nabíjení po dosažení cíle", "11": "Rychlé nabíjení po dosažení cíle", "12": "Připojeno", "13": "AC nabíjení", "14": "DC nabíjení", "15": "Kalibrace baterie aktivní", "16": "Neznámé" } }, "departuretimemode": { "state": { "0": "Deaktivováno", "1": "Denně", "2": "Týdně" } }, "ignitionstate": { "state": { "0": "Zamknuté", "1": "Vypnuté", "2": "Příslušenství", "4": "Zapnuté", "5": "Start" } }, "interiorprotectionsensorstatus": { "state": { "0": "Neaktivní", "1": "Neaktivní", "2": "Aktivní" }, "state_attributes": {} }, "lock": { "state": { "0": "Odemčeno", "1": "Zamčeno interně", "2": "Zamčeno", "3": "Částečně odemčeno", "4": "Neznámé" }, "state_attributes": { "decklidstatus": { "name": "Zavazadlový prostor", "state": { "false": "zavřené", "true": "otevřené" } }, "doorstatusfrontleft": { "name": "Přední levé dveře", "state": { "false": "zavřené", "true": "otevřené" } }, "doorstatusfrontright": { "name": "Přední pravé dveře", "state": { "false": "zavřené", "true": "otevřené" } }, "doorstatusrearleft": { "name": "Zadní levé dveře", "state": { "false": "zavřené", "true": "otevřené" } }, "doorstatusrearright": { "name": "Zadní pravé dveře", "state": { "false": "zavřené", "true": "otevřené" } }, "doorlockstatusfrontleft": { "name": "Zámek předních levých dveří", "state": { "false": "zamčeno", "true": "odemčeno" } }, "doorlockstatusfrontright": { "name": "Zámek předních pravých dveří", "state": { "false": "zamčeno", "true": "odemčeno" } }, "doorlockstatusrearleft": { "name": "Zámek zadních levých dveří", "state": { "false": "zamčeno", "true": "odemčeno" } }, "doorlockstatusrearright": { "name": "Zámek zadních pravých dveří", "state": { "false": "zamčeno", "true": "odemčeno" } }, "doorlockstatusgas": { "name": "Zámek palivové nádrže", "state": { "false": "zamčeno", "true": "odemčeno" } }, "enginehoodstatus": { "name": "Kapota", "state": { "false": "zavřené", "true": "otevřené" } }, "doorstatusoverall": { "name": "Celkový stav dveří", "state": { "0": "otevřené", "1": "zavřené", "2": "neexistující", "3": "neznámé" } }, "sunroofstatus": { "name": "Stav střešního okna", "state": { "0": "zavřené", "1": "otevřené", "2": "ventilace otevřená", "3": "v pohybu", "4": "protihluková pozice", "5": "posuvné střední", "6": "zvedání střední", "7": "otevírání", "8": "zavírání", "9": "zvedání protihlukové", "10": "střední poloha", "11": "zvedání otevírání", "12": "zvedání zavírání" } } } }, "sunroofstatus": { "state": { "0": "Zavřeno", "1": "Otevřeno", "2": "Otevřená ventilace", "3": "V pohybu", "4": "Protihluková pozice", "5": "Střední posuv", "6": "Střední zvedání", "7": "Otevírání", "8": "Zavírání", "9": "Zvednutí protihlukové", "10": "Střední poloha", "11": "Otevírání ventilace", "12": "Zavírání ventilace" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Zelená", "1": "Žlutá", "2": "Červená" } }, "tirewarningsrdk": { "state": { "0": "Žádné varování", "1": "Mírné varování", "2": "Nízký tlak", "3": "Defekt" } }, "selectedchargeprogram": { "state": { "0": "Standardní", "2": "Domov", "3": "Práce", "4": "Nepodporováno" } } }, "switch": { "auxheat": { "name": "Přídavné topení" }, "precond": { "name": "Předkondicionování" } }, "button": { "btn_preheat_start_now": { "name": "Spustit předkondicionování" }, "btn_preheat_stop_now": { "name": "Zastavit předkondicionování" }, "btn_sigpos_start_now": { "name": "Blikat světly" } } }, "selector": { "charge_program": { "options": { "0": "Výchozí", "2": "Domov", "3": "Práce" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Nenastaveno", "active": "Aktivní", "inactive": "Neaktivní" } }, "temperature_configure": { "options": { "0": "Nízká", "30": "Vysoká" } } } } ================================================ FILE: custom_components/mbapi2020/translations/da.json ================================================ { "config": { "abort": { "already_configured": "Komponenten er allerede konfigureret.", "reauth_successful": "Genautentificering lykkedes! Komponent genindlæses." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Ukendt fejl. Kontroller venligst Home Assistant-loggen for mere information.", "2fa_required": "Tofaktorautentificering (2FA)-konti understøttes ikke.", "legal_terms": "Du skal først acceptere de juridiske vilkår på Mercedes' hjemmeside" }, "step": { "user": { "data": { "region": "Region" }, "description": "Vælg din region.", "title": "Opsæt Mercedes ME 2020-forbindelsen" }, "credentials": { "data": { "username": "MB brugernavn (e-mailadresse)", "password": "Adgangskode" }, "description": "Indtast dine kontooplysninger.", "title": "Mercedes ME 2020 - Login" }, "pin": { "data": { "password": "TAN (modtaget via e-mail eller SMS)" }, "description": "Indtast den TAN-kode, du har modtaget via e-mail eller SMS, for at fuldføre autentificeringen. Hvis du ikke har modtaget en TAN-kode, skal du kontrollere din e-mail-indbakke (og spam-mappen) eller dine SMS-beskeder.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Genstart af Home Assistant er påkrævet for at fuldføre autentificeringsopdateringen. Klik på send for at genstarte nu.", "title": "Genstart påkrævet" } } }, "title": "Genstart påkrævet" } }, "options": { "abort": { "already_configured": "Komponenten er allerede konfigureret.", "reauth_successful": "Genautentificering lykkedes! Komponent genindlæses." }, "step": { "init": { "data": { "cap_check_disabled": "Deaktiver kapabilitetskontrol", "enable_china_gcj_02": "Aktiver GCJ-02-oversættelse (kun Kina)", "delete_auth_file": "Slet autentificeringstoken nu. Kræver en genstart af Home Assistant efter gem.", "excluded_cars": "Ekskluderede VIN-numre (kommasepareret)", "pin": "Sikkerheds-PIN (skal oprettes i mobilappen)", "save_files": "KUN FEJLSØGNING: Aktiver gemning af serverbeskeder i meddelelsesmappen", "overwrite_cap_precondnow": "Eks: Overskriv kapabilitet precondnow (sæt til sand)" }, "description": "Konfigurer dine indstillinger. Nogle ændringer kræver en genstart af Home Assistant.", "title": "Mercedes ME 2020 Indstillinger" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API tilgængelig", "websocket_connection_state": "MB WS-tilstand", "cars_connected": "Tilsluttede biler", "version": "Version" } }, "services": { "refresh_access_token": { "name": "Opdater adgangstoken", "description": "Opdater API-adgangstoken" }, "auxheat_configure": { "name": "Konfigurer ekstravarme", "description": "Kommando til konfiguration af ekstravarmen. Det er muligt at definere tre tidspunkter og vælge et aktivt tidspunkt.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "time_selection": { "name": "Tidsvalg", "description": "Det aktiverede forudindstillede tidspunkt for ekstravarmen (0=intet_valg, 1=tid_1, 2=tid_2, 3=tid_3)" }, "time_1": { "name": "time_1", "description": "Tidspunkt i minutter efter midnat. F.eks. er 480 en gyldig værdi for kl. 08.00. Værdiområdet er 0 til 1439." }, "time_2": { "name": "time_2", "description": "Tidspunkt i minutter efter midnat. F.eks. er 480 en gyldig værdi for kl. 08.00. Værdiområdet er 0 til 1439." }, "time_3": { "name": "time_3", "description": "Tidspunkt i minutter efter midnat. F.eks. er 480 en gyldig værdi for kl. 08.00. Værdiområdet er 0 til 1439." } } }, "auxheat_start": { "name": "Start ekstravarme", "description": "Start ekstravarmen for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "auxheat_stop": { "name": "Stop ekstravarme", "description": "Stop ekstravarmen for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "battery_max_soc_configure": { "name": "Konfigurer batteriets maksimale ladeniveau (SoC)", "description": "Konfigurer den maksimale værdi for ladeniveauet (SoC) i højspændingsbatteriet for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "max_soc": { "name": "Maks SoC", "description": "Den maksimale værdi for højspændingsbatteriets ladeniveau (SoC). Værdien skal være mellem 50 (nogle nye biler som 2025 CLA understøtter 30) og 100 og delelig med ti." }, "charge_program": { "name": "Ladeprogram", "description": "(Valgfri, Standard=0) Ladeprogram der skal ændres (0=Standard, 2=Hjem, 3=Arbejde) (bruges ikke til 2025 CLA)" } } }, "charge_program_configure": { "name": "Konfigurer ladeprogram", "description": "Kommando til at vælge ladeprogrammet.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "charge_program": { "name": "Ladeprogram", "description": "Det aktiverede ladeprogram (0=Standard, 2=Hjem, 3=Arbejde)" }, "max_soc": { "name": "Maks SoC", "description": "Den maksimale værdi for højspændingsbatteriets ladeniveau (SoC). Værdien skal være mellem 50 og 100 og delelig med ti." } } }, "doors_unlock": { "name": "Lås døre op", "description": "Lås en bil op defineret af et VIN-nummer. PIN-kode opsætning påkrævet. Se indstillingsdialogen for integrationen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhedskode (PIN), påkrævet hvis den ikke er gemt i indstillingerne." } } }, "doors_lock": { "name": "Lås døre", "description": "Lås en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "download_images": { "name": "Download billeder", "description": "Downloader app-billeder til komponentens ressourcemappe for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "engine_start": { "name": "Start motor", "description": "Start motoren på en bil defineret af et VIN-nummer. PIN-kode opsætning påkrævet. Se indstillingsdialogen for integrationen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhedskode (PIN), påkrævet hvis den ikke er gemt i indstillingerne." } } }, "engine_stop": { "name": "Stop motor", "description": "Stop motoren på en bil defineret af et VIN-nummer. PIN-kode opsætning påkrævet. Se indstillingsdialogen for integrationen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "hv_battery_start_conditioning": { "name": "Start konditionering af højspændingsbatteri", "description": "Start konditioneringen af højspændingsbatteriet for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "hv_battery_stop_conditioning": { "name": "Stop konditionering af højspændingsbatteri", "description": "Stop konditioneringen af højspændingsbatteriet for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preconditioning_configure_seats": { "name": "Konfigurer sæder til forklimatisering", "description": "Send en konfigurationskommando for sædeforklimatisering til en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "front_left": { "name": "Venstre for", "description": "Aktiver hvis det venstre forsæde skal forklimatiseres." }, "front_right": { "name": "Højre for", "description": "Aktiver hvis det højre forsæde skal forklimatiseres." }, "rear_left": { "name": "Venstre bag", "description": "Aktiver hvis det venstre bagsæde skal forklimatiseres." }, "rear_right": { "name": "Højre bag", "description": "Aktiver hvis det højre bagsæde skal forklimatiseres." } } }, "preheat_start": { "name": "Start forklimatisering", "description": "Start forklimatiseringen for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "type": { "name": "Type", "description": "Metode der bruges til at starte processen. 0=Nu (Standard), 1=Øjeblikkelig - Brug Øjeblikkelig hvis din bil ikke understøtter Nu." } } }, "preheat_start_departure_time": { "name": "Start forklimatisering med afgangstid", "description": "Start forklimatiseringen for en bil defineret af et VIN-nummer og en given afgangstid.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "time": { "name": "Tid", "description": "Afgangstid i minutter efter midnat. F.eks. er 480 en gyldig værdi for kl. 08.00. Værdiområdet er 0 til 1439." } } }, "preheat_stop": { "name": "Stop forklimatisering", "description": "Stop forklimatiseringen for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preheat_stop_departure_time": { "name": "Stop forklimatisering for afgangstid", "description": "Stop den konfigurerede afgangstid-forklimatisering for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preconditioning_configure": { "name": "Konfigurer forklimatisering ved afgang", "description": "Konfigurer forklimatiseringstilstand ved afgang. Brug tilstand 0 (Deaktiveret) for at annullere planlagt afgangsforklimatisering.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "departure_time_mode": { "name": "Afgangstidstilstand", "description": "0=Deaktiveret, 1=Enkelt afgang, 2=Ugentlig afgang" }, "departure_time": { "name": "Afgangstid", "description": "Afgangstid i minutter efter midnat (0-1439). Bruges kun når tilstand > 0." } } }, "sigpos_start": { "name": "Start signalposition", "description": "Start lyssignalering for en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "sunroof_open": { "name": "Åbn soltag", "description": "Åbn soltaget på en bil defineret af et VIN-nummer. PIN-kode opsætning påkrævet. Se indstillingsdialogen for integrationen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhedskode (PIN), påkrævet hvis den ikke er gemt i indstillingerne." } } }, "sunroof_tilt": { "name": "Vip soltag", "description": "Vip soltaget på en bil defineret af et VIN-nummer. PIN-kode opsætning påkrævet. Se indstillingsdialogen for integrationen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhedskode (PIN), påkrævet hvis den ikke er gemt i indstillingerne." } } }, "sunroof_close": { "name": "Luk soltag", "description": "Luk soltaget på en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "temperature_configure": { "name": "Konfigurer måltemperatur (forklimatisering/ekstravarme)", "description": "Konfigurer måltemperaturer for forklimatisering/ekstravarme for zoner i en bil defineret af et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "front_left": { "name": "Venstre for", "description": "Måltemperatur for zonen venstre for i CELSIUS." }, "front_right": { "name": "Højre for", "description": "Måltemperatur for zonen højre for i CELSIUS." }, "rear_left": { "name": "Venstre bag", "description": "Måltemperatur for zonen venstre bag i CELSIUS. (hvis tilgængelig)" }, "rear_right": { "name": "Højre bag", "description": "Måltemperatur for zonen højre bag i CELSIUS. (hvis tilgængelig)" } } }, "windows_open": { "name": "Åbn vinduer", "description": "Åbn vinduerne på en bil defineret af et VIN-nummer. PIN-kode opsætning påkrævet. Se indstillingsdialogen for integrationen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhedskode (PIN), påkrævet hvis den ikke er gemt i indstillingerne." } } }, "windows_close": { "name": "Luk vinduer", "description": "Luk vinduerne på en bil defineret af et VIN-nummer. PIN-kode opsætning påkrævet. Se indstillingsdialogen for integrationen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "windows_move": { "name": "Flyt vinduer", "description": "Flyt vinduerne på en bil defineret af et VIN-nummer til en ny position. PIN-kode opsætning påkrævet. Se indstillingsdialogen for integrationen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhedskode (PIN), påkrævet hvis den ikke er gemt i indstillingerne." }, "front_left": { "name": "Venstre for", "description": "Den nye position for det venstre forvindue (0=lukket, 10=udluftning, 100=åbent)" }, "front_right": { "name": "Højre for", "description": "Den nye position for det højre forvindue (0=lukket, 10=udluftning, 100=åbent)" }, "rear_left": { "name": "Venstre bag", "description": "Den nye position for det venstre bagvindue (0=lukket, 10=udluftning, 100=åbent)" }, "rear_right": { "name": "Højre bag", "description": "Den nye position for det højre bagvindue (0=lukket, 10=udluftning, 100=åbent)" } } }, "send_route": { "name": "Send rute", "description": "Sender en rute til bilen. (Kun enkelt placering)", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "title": { "name": "Titel", "description": "Rutens titel" }, "latitude": { "name": "Breddegrad", "description": "Placeringens breddegrad" }, "longitude": { "name": "Længdegrad", "description": "Placeringens længdegrad" }, "city": { "name": "By", "description": "Placeringens bynavn" }, "postcode": { "name": "Postnummer", "description": "Placeringens postnummer" }, "street": { "name": "Gade", "description": "Placeringens gadenavn" } } }, "charging_break_clocktimer_configure": { "name": "Konfigurer tidsstyring for ladepause", "description": "Konfigurer ladepauser (kun AC). Dette vil overskrive hele konfigurationen for alle pladser i din bil.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "status_timer_1": { "name": "Status (Timer 1)", "description": "" }, "starttime_timer_1": { "name": "Starttid (Timer 1)", "description": "Starttid for ladepausevinduet (Timer 1)" }, "stoptime_timer_1": { "name": "Sluttid (Timer 1)", "description": "Sluttid for ladepausevinduet (Timer 1)" }, "status_timer_2": { "name": "Status (Timer 2)", "description": "" }, "starttime_timer_2": { "name": "Starttid (Timer 2)", "description": "Starttid for ladepausevinduet (Timer 2)" }, "stoptime_timer_2": { "name": "Sluttid (Timer 2)", "description": "Sluttid for ladepausevinduet (Timer 2)" }, "status_timer_3": { "name": "Status (Timer 3)", "description": "" }, "starttime_timer_3": { "name": "Starttid (Timer 3)", "description": "Starttid for ladepausevinduet (Timer 3)" }, "stoptime_timer_3": { "name": "Sluttid (Timer 3)", "description": "Sluttid for ladepausevinduet (Timer 3)" }, "status_timer_4": { "name": "Status (Timer 4)", "description": "" }, "starttime_timer_4": { "name": "Starttid (Timer 4)", "description": "Starttid for ladepausevinduet (Timer 4)" }, "stoptime_timer_4": { "name": "Sluttid (Timer 4)", "description": "Sluttid for ladepausevinduet (Timer 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Opladning aktiv" } }, "sensor": { "chargingpowerecolimit": { "name": "Ladeeffektgrænse" }, "auxheatstatus": { "state": { "0": "Inaktiv", "1": "Normal opvarmning", "2": "Normal ventilation", "3": "Manuel opvarmning", "4": "Efteropvarmning", "5": "Efterventilation", "6": "Automatisk opvarmning" } }, "chargeflapacstatus": { "state": { "0": "Åben", "1": "Lukket", "2": "Klap trykket", "3": "Ukendt" } }, "chargeflapdcstatus": { "state": { "0": "Åben", "1": "Lukket", "2": "Klap trykket", "3": "Ukendt" } }, "chargingstatus": { "state": { "0": "oplader", "1": "opladning slutter", "2": "Ladepause", "3": "frakoblet", "4": "fejl", "5": "langsom", "6": "hurtig", "7": "aflader", "8": "oplader ikke", "9": "langsom opladning efter nået rejsemål", "10": "opladning efter nået rejsemål", "11": "hurtig opladning efter nået rejsemål", "12": "Tilsluttet", "13": "AC-opladning", "14": "DC-opladning", "15": "Batterikalibrering aktiv", "16": "ukendt" } }, "departuretimemode": { "state": { "0": "Deaktiveret", "1": "Daglig", "2": "Ugentlig" } }, "ignitionstate": { "state": { "0": "Låst", "1": "Slukket", "2": "Tilbehør", "4": "Tændt", "5": "Start" } }, "interiorprotectionsensorstatus": { "state": { "0": "Ikke aktiv", "1": "Ikke aktiv", "2": "Aktiv" }, "state_attributes": {} }, "lock": { "state": { "0": "Ulåst", "1": "Låst internt", "2": "Låst", "3": "Delvist ulåst", "4": "Ukendt" }, "state_attributes": { "decklidstatus": { "name": "Bagklap", "state": { "false": "lukket", "true": "åben" } }, "doorstatusfrontleft": { "name": "Dør venstre for", "state": { "false": "lukket", "true": "åben" } }, "doorstatusfrontright": { "name": "Dør højre for", "state": { "false": "lukket", "true": "åben" } }, "doorstatusrearleft": { "name": "Dør venstre bag", "state": { "false": "lukket", "true": "åben" } }, "doorstatusrearright": { "name": "Dør højre bag", "state": { "false": "lukket", "true": "åben" } }, "doorlockstatusfrontleft": { "name": "Dørlås venstre for", "state": { "false": "låst", "true": "ulåst" } }, "doorlockstatusfrontright": { "name": "Dørlås højre for", "state": { "false": "låst", "true": "ulåst" } }, "doorlockstatusrearleft": { "name": "Dørlås venstre bag", "state": { "false": "låst", "true": "ulåst" } }, "doorlockstatusrearright": { "name": "Dørlås højre bag", "state": { "false": "låst", "true": "ulåst" } }, "doorlockstatusgas": { "name": "Tanklåg", "state": { "false": "låst", "true": "ulåst" } }, "enginehoodstatus": { "name": "Motorhjelm", "state": { "false": "lukket", "true": "åben" } }, "doorstatusoverall": { "name": "Samlet dørstatus", "state": { "0": "åben", "1": "lukket", "2": "findes ikke", "3": "ukendt" } }, "sunroofstatus": { "name": "Soltagsstatus", "state": { "0": "lukket", "1": "åben", "2": "løft åben", "3": "kører", "4": "vindstøjsposition", "5": "glidende mellemposition", "6": "løftende mellemposition", "7": "åbner", "8": "lukker", "9": "vindstøjsløft", "10": "mellemposition", "11": "åbner løft", "12": "lukker løft" } } } }, "sunroofstatus": { "state": { "0": "Lukket", "1": "Åben", "2": "Åben løft", "3": "Kører", "4": "Vindstøjsposition", "5": "Glidende mellemposition", "6": "Løftende mellemposition", "7": "Åbner", "8": "Lukker", "9": "Vindstøjsløft", "10": "Mellemposition", "11": "Åbner løft", "12": "Lukker løft" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Grøn", "1": "Gul", "2": "Rød" } }, "tirewarningsrdk": { "state": { "0": "Ingen advarsel", "1": "Blød advarsel", "2": "Lavt tryk", "3": "Punktering" } }, "selectedchargeprogram": { "state": { "0": "Standard", "2": "Hjem", "3": "Arbejde", "4": "Ikke understøttet" } } }, "switch": { "auxheat": { "name": "Ekstravarme" }, "precond": { "name": "Forklimatisering" } }, "button": { "btn_preheat_start_now": { "name": "Start forklimatisering" }, "btn_preheat_stop_now": { "name": "Stop forklimatisering" }, "btn_sigpos_start_now": { "name": "Blink lygter" } } }, "selector": { "charge_program": { "options": { "0": "Standard", "2": "Hjem", "3": "Arbejde" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Ikke indstillet", "active": "Aktiv", "inactive": "Inaktiv" } }, "temperature_configure": { "options": { "0": "Lav", "30": "Høj" } } } } ================================================ FILE: custom_components/mbapi2020/translations/de.json ================================================ { "config": { "abort": { "already_configured": "Komponente ist bereits konfiguriert.", "reauth_successful": "Neuanmeldung erfolgreich! Komponente wird neu geladen." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Unbekannter Fehler. Bitte prüfe das Home Assistant Log für weitere Informationen.", "2fa_required": "Zwei-Faktor-Authentifizierung (2FA) Konten werden nicht unterstützt.", "legal_terms": "Du musst die rechtlichen Bedingungen auf der Mercedes-Website zuerst akzeptieren" }, "step": { "user": { "data": { "region": "Region" }, "description": "Wähle deine Region aus.", "title": "Mercedes ME 2020 Verbindung einrichten" }, "credentials": { "data": { "username": "MB Benutzername (E-Mail)", "password": "Passwort" }, "description": "Gib deine Kontodaten ein.", "title": "Mercedes ME 2020 - Anmeldung" }, "pin": { "data": { "password": "TAN (per E-Mail oder SMS erhalten)" }, "description": "Gib die TAN ein, die du per E-Mail oder SMS erhalten hast, um die Authentifizierung abzuschließen. Falls du keine TAN erhalten hast, prüfe bitte deinen E-Mail-Posteingang (und Spam-Ordner) oder deine SMS-Nachrichten.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Ein Neustart von Home Assistant ist erforderlich, um das Auth-Update abzuschließen. Klicke auf Senden, um jetzt neu zu starten.", "title": "Neustart erforderlich" } } }, "title": "Neustart erforderlich" } }, "options": { "abort": { "already_configured": "Komponente ist bereits konfiguriert.", "reauth_successful": "Reauth erfolgreich! Komponente wird neu geladen." }, "step": { "init": { "data": { "cap_check_disabled": "Verfügbarkeitsprüfung deaktivieren", "enable_china_gcj_02": "GCJ-02 Übersetzung aktivieren (nur China)", "delete_auth_file": "Authentifizierungs-Token jetzt löschen. Erfordert nach dem Speichern einen Neustart von Home Assistant.", "excluded_cars": "Ausgeschlossene VINs (kommagetrennt)", "pin": "Sicherheits-PIN (in der Mobile-App zu erstellen)", "save_files": "NUR DEBUG: Servernachrichten in den Messages-Ordner speichern", "overwrite_cap_precondnow": "Exp: Capability precondnow überschreiben (auf true setzen)" }, "description": "Konfiguriere deine Optionen. Einige Änderungen erfordern einen Neustart von Home Assistant.", "title": "Mercedes ME 2020 Optionen" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API erreichbar", "websocket_connection_state": "MB WS Status", "cars_connected": "Verbundene Fahrzeuge", "version": "Version" } }, "services": { "refresh_access_token": { "name": "Access-Token erneuern", "description": "Erneuert das API Zugriffstoken" }, "auxheat_configure": { "name": "Standheizung konfigurieren", "description": "Befehl zum Konfigurieren der Standheizung. Es ist möglich, drei Tageszeiten zu definieren und eine aktive Zeit auszuwählen.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "time_selection": { "name": "Zeit Auswahl", "description": "Aktiviertes Standheizungs-Preset (0=no_selection, 1=time_1, 2=time_2, 3=time_3)" }, "time_1": { "name": "time_1", "description": "Tageszeit in Minuten nach Mitternacht. Z. B. 8 Uhr = 480. Wertebereich 0-1439." }, "time_2": { "name": "time_2", "description": "Tageszeit in Minuten nach Mitternacht. Z. B. 8 Uhr = 480. Wertebereich 0-1439." }, "time_3": { "name": "time_3", "description": "Tageszeit in Minuten nach Mitternacht. Z. B. 8 Uhr = 480. Wertebereich 0-1439." } } }, "auxheat_start": { "name": "Standheizung starten", "description": "Startet die Standheizung eines Fahrzeugs (VIN)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "auxheat_stop": { "name": "Standheizung stoppen", "description": "Stoppt die Standheizung eines Fahrzeugs (VIN)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "battery_max_soc_configure": { "name": "Maximale Akku-Ladezustand konfigurieren", "description": "Konfiguriert den maximalen Ladezustand der HV-Batterie für ein Fahrzeug (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "max_soc": { "name": "Max Soc", "description": "Maximaler Ladezustand (muss zwischen 50 (einige neue Fahrzeuge wie der 2025 CLA unterstützen 30) und 100 liegen und durch 10 teilbar sein)" }, "charge_program": { "name": "Ladeprogramm", "description": "(Optional, Standard=0) Zu änderndes Ladeprogramm (0=Standard, 2=Zuhause, 3=Arbeit) (nicht für 2025 CLA verwendet)" } } }, "charge_program_configure": { "name": "Ladeprogramm auswählen", "description": "Befehl zum Auswählen des Ladeprogramms.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "charge_program": { "name": "Ladeprogramm", "description": "Aktiviertes Ladeprogramm (0=Standard, 2=Zuhause, 3=Arbeit)" }, "max_soc": { "name": "Max Soc", "description": "Maximaler Ladezustand (muss zwischen 50 und 100 liegen und durch 10 teilbar sein)" } } }, "doors_unlock": { "name": "Türen entriegeln", "description": "Entriegelt ein Fahrzeug (VIN). PIN-Einrichtung erforderlich.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "pin": { "name": "Pin", "description": "Sicherheits-PIN, erforderlich wenn nicht in den Einstellungen gespeichert" } } }, "doors_lock": { "name": "Türen verriegeln", "description": "Verriegelt ein Fahrzeug (VIN)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "download_images": { "name": "Bilder herunterladen", "description": "Lädt App-Bilder in den Ressourcenordner des Components herunter.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "engine_start": { "name": "Motor starten", "description": "Startet den Motor eines Fahrzeugs (VIN). PIN-Einrichtung erforderlich.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "pin": { "name": "Pin", "description": "Sicherheits-PIN, erforderlich wenn nicht in den Einstellungen gespeichert" } } }, "engine_stop": { "name": "Motor stoppen", "description": "Stoppt den Motor eines Fahrzeugs (VIN). PIN-Einrichtung erforderlich.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "hv_battery_start_conditioning": { "name": "HV-Batterie Konditionierung starten", "description": "Startet die HV-Batterie-Konditionierung eines Fahrzeugs (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "hv_battery_stop_conditioning": { "name": "HV-Batterie Konditionierung stoppen", "description": "Stoppt die HV-Batterie-Konditionierung eines Fahrzeugs (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "preconditioning_configure_seats": { "name": "Sitze vorklimatisieren konfigurieren", "description": "Sendet Sitzkonfigurationsbefehl für Vorklimatisierung an ein Fahrzeug (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "front_left": { "name": "Vorne links", "description": "Aktivieren wenn Sitz vorne links vorklimatisiert werden soll" }, "front_right": { "name": "Vorne rechts", "description": "Aktivieren wenn Sitz vorne rechts vorklimatisiert werden soll" }, "rear_left": { "name": "Hinten links", "description": "Aktivieren wenn Sitz hinten links vorklimatisiert werden soll" }, "rear_right": { "name": "Hinten rechts", "description": "Aktivieren wenn Sitz hinten rechts vorklimatisiert werden soll" } } }, "preheat_start": { "name": "Vorklimatisierung starten", "description": "Startet die Vorklimatisierung eines Fahrzeugs (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "type": { "name": "Typ", "description": "Methode zum Starten (0=Jetzt (Standard), 1=Sofort - Verwende 'Sofort' falls Fahrzeug 'Jetzt' nicht unterstützt)" } } }, "preheat_start_departure_time": { "name": "Vorklimatisierung mit Abfahrtszeit starten", "description": "Startet die Vorklimatisierung mit gegebener Abfahrtszeit.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "time": { "name": "Zeit", "description": "Abfahrtszeit in Minuten nach Mitternacht (z. B. 8 Uhr = 480). Wertebereich 0-1439." } } }, "preheat_stop": { "name": "Vorklimatisierung stoppen", "description": "Stoppt die Vorklimatisierung eines Fahrzeugs (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "preheat_stop_departure_time": { "name": "Vorklimatisierung mit Abfahrtszeit stoppen", "description": "Stoppt konfigurierte Vorklimatisierung mit Abfahrtszeit.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "preconditioning_configure": { "name": "Vorklimatisierung Abfahrt konfigurieren", "description": "Konfiguriert den Abfahrtszeit-Modus der Vorklimatisierung. Verwende Modus 0 (Deaktiviert) um die geplante Abfahrts-Vorklimatisierung abzubrechen.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "departure_time_mode": { "name": "Abfahrtszeit-Modus", "description": "0=Deaktiviert, 1=Einzelne Abfahrt, 2=Wöchentliche Abfahrt" }, "departure_time": { "name": "Abfahrtszeit", "description": "Abfahrtszeit in Minuten nach Mitternacht (0-1439). Wird nur bei Modus > 0 verwendet." } } }, "sigpos_start": { "name": "Signalposition starten", "description": "Startet Lichtsignal eines Fahrzeugs (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "sunroof_open": { "name": "Schiebedach öffnen", "description": "Öffnet das Schiebedach eines Fahrzeugs (VIN). PIN-Einrichtung erforderlich.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "pin": { "name": "Pin", "description": "Sicherheits-PIN, erforderlich wenn nicht in den Einstellungen gespeichert" } } }, "sunroof_tilt": { "name": "Schiebedach kippen", "description": "Kippt das Schiebedach eines Fahrzeugs (VIN). PIN-Einrichtung erforderlich.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "pin": { "name": "Pin", "description": "Sicherheits-PIN, erforderlich wenn nicht in den Einstellungen gespeichert" } } }, "sunroof_close": { "name": "Schiebedach schließen", "description": "Schließt das Schiebedach eines Fahrzeugs (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "temperature_configure": { "name": "Zieltemperatur konfigurieren (precond/auxheat)", "description": "Konfiguriert Zieltemperaturen für Zonen in einem Fahrzeug (VIN).", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "front_left": { "name": "Vorne links", "description": "Zieltemperatur für Zone vorne links in CELSIUS." }, "front_right": { "name": "Vorne rechts", "description": "Zieltemperatur für Zone vorne rechts in CELSIUS." }, "rear_left": { "name": "Hinten links", "description": "Zieltemperatur für Zone hinten links in CELSIUS. (falls vorhanden)" }, "rear_right": { "name": "Hinten rechts", "description": "Zieltemperatur für Zone hinten rechts in CELSIUS. (falls vorhanden)" } } }, "windows_open": { "name": "Fenster öffnen", "description": "Öffnet die Fenster eines Fahrzeugs (VIN). PIN-Einrichtung erforderlich.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "pin": { "name": "Pin", "description": "Sicherheits-PIN, erforderlich wenn nicht in den Einstellungen gespeichert" } } }, "windows_close": { "name": "Fenster schließen", "description": "Schließt die Fenster eines Fahrzeugs (VIN). PIN-Einrichtung erforderlich.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" } } }, "windows_move": { "name": "Fenster bewegen", "description": "Bewegt die Fenster eines Fahrzeugs (VIN) auf eine neue Position. PIN-Einrichtung erforderlich.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "pin": { "name": "Pin", "description": "Sicherheits-PIN, erforderlich wenn nicht in den Einstellungen gespeichert" }, "front_left": { "name": "Vorne links", "description": "Neue Position des vorderen linken Fensters (0=geschlossen, 10=belüftet, 100=offen)" }, "front_right": { "name": "Vorne rechts", "description": "Neue Position des vorderen rechten Fensters (0=geschlossen, 10=belüftet, 100=offen)" }, "rear_left": { "name": "Hinten links", "description": "Neue Position des hinteren linken Fensters (0=geschlossen, 10=belüftet, 100=offen)" }, "rear_right": { "name": "Hinten rechts", "description": "Neue Position des hinteren rechten Fensters (0=geschlossen, 10=belüftet, 100=offen)" } } }, "send_route": { "name": "Route senden", "description": "Sendet eine Route an das Fahrzeug. (Nur ein Standort)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "title": { "name": "Titel", "description": "Titel der Route" }, "latitude": { "name": "Breitengrad", "description": "Breitengrad des Standorts" }, "longitude": { "name": "Längengrad", "description": "Längengrad des Standorts" }, "city": { "name": "Stadt", "description": "Stadt des Standorts" }, "postcode": { "name": "Postleitzahl", "description": "Postleitzahl des Standorts" }, "street": { "name": "Straße", "description": "Straßenname des Standorts" } } }, "charging_break_clocktimer_configure": { "name": "Ladepausen Timer konfigurieren", "description": "Konfiguriert Ladepausen (nur AC). Überschreibt die komplette Konfiguration für alle Slots im Fahrzeug.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin des Fahrzeugs" }, "status_timer_1": { "name": "Status (Timer 1)", "description": "" }, "starttime_timer_1": { "name": "Startzeit (Timer 1)", "description": "Startzeit des Ladepausefensters (Timer 1)" }, "stoptime_timer_1": { "name": "Endzeit (Timer 1)", "description": "Endzeit des Ladepausefensters (Timer 1)" }, "status_timer_2": { "name": "Status (Timer 2)", "description": "" }, "starttime_timer_2": { "name": "Startzeit (Timer 2)", "description": "Startzeit des Ladepausefensters (Timer 2)" }, "stoptime_timer_2": { "name": "Endzeit (Timer 2)", "description": "Endzeit des Ladepausefensters (Timer 2)" }, "status_timer_3": { "name": "Status (Timer 3)", "description": "" }, "starttime_timer_3": { "name": "Startzeit (Timer 3)", "description": "Startzeit des Ladepausefensters (Timer 3)" }, "stoptime_timer_3": { "name": "Endzeit (Timer 3)", "description": "Endzeit des Ladepausefensters (Timer 3)" }, "status_timer_4": { "name": "Status (Timer 4)", "description": "" }, "starttime_timer_4": { "name": "Startzeit (Timer 4)", "description": "Startzeit des Ladepausefensters (Timer 4)" }, "stoptime_timer_4": { "name": "Endzeit (Timer 4)", "description": "Endzeit des Ladepausefensters (Timer 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Ladevorgang aktiv" } }, "sensor": { "chargingpowerecolimit": { "name": "Ladeleistungsbegrenzung" }, "auxheatstatus": { "state": { "0": "Inaktiv", "1": "Normal heizen", "2": "Normal belüften", "3": "Manuelles Heizen", "4": "Nachheizen", "5": "Nachlüften", "6": "Automatisch heizen" } }, "chargeflapacstatus": { "state": { "0": "Offen", "1": "Geschlossen", "2": "Klappe gedrückt", "3": "Unbekannt" } }, "chargeflapdcstatus": { "state": { "0": "Offen", "1": "Geschlossen", "2": "Klappe gedrückt", "3": "Unbekannt" } }, "chargingstatus": { "state": { "0": "Lädt", "1": "Ladevorgang beendet", "2": "Ladepause", "3": "Gekappt", "4": "Fehler", "5": "Langsam", "6": "Schnell", "7": "Entladung", "8": "Nicht ladend", "9": "Langsam nach Ziel erreicht", "10": "Laden nach Ziel erreicht", "11": "Schnell nach Ziel erreicht", "12": "Verbunden", "13": "AC Laden", "14": "DC Laden", "15": "Batteriekalibrierung aktiv", "16": "Unbekannt" } }, "departuretimemode": { "state": { "0": "Deaktiviert", "1": "Täglich", "2": "Wöchentlich" } }, "ignitionstate": { "state": { "0": "Verriegelt", "1": "Aus", "2": "Zubehör", "4": "Ein", "5": "Start" } }, "interiorprotectionsensorstatus": { "state": { "0": "Nicht aktiv", "1": "Nicht aktiv", "2": "Aktiv" }, "state_attributes": {} }, "lock": { "state": { "0": "Entriegelt", "1": "Intern verriegelt", "2": "Verriegelt", "3": "Teilweise entriegelt", "4": "Unbekannt" }, "state_attributes": { "decklidstatus": { "name": "Kofferraumklappe", "state": { "false": "geschlossen", "true": "offen" } }, "doorstatusfrontleft": { "name": "Tür vorne links", "state": { "false": "geschlossen", "true": "offen" } }, "doorstatusfrontright": { "name": "Tür vorne rechts", "state": { "false": "geschlossen", "true": "offen" } }, "doorstatusrearleft": { "name": "Tür hinten links", "state": { "false": "geschlossen", "true": "offen" } }, "doorstatusrearright": { "name": "Tür hinten rechts", "state": { "false": "geschlossen", "true": "offen" } }, "doorlockstatusfrontleft": { "name": "Türschloss vorne links", "state": { "false": "verriegelt", "true": "entriegelt" } }, "doorlockstatusfrontright": { "name": "Türschloss vorne rechts", "state": { "false": "verriegelt", "true": "entriegelt" } }, "doorlockstatusrearleft": { "name": "Türschloss hinten links", "state": { "false": "verriegelt", "true": "entriegelt" } }, "doorlockstatusrearright": { "name": "Türschloss hinten rechts", "state": { "false": "verriegelt", "true": "entriegelt" } }, "doorlockstatusgas": { "name": "Tankklappenschloss", "state": { "false": "verriegelt", "true": "entriegelt" } }, "enginehoodstatus": { "name": "Motorhaube", "state": { "false": "geschlossen", "true": "offen" } }, "doorstatusoverall": { "name": "Allgemeiner Türstatus", "state": { "0": "offen", "1": "geschlossen", "2": "nicht vorhanden", "3": "unbekannt" } }, "sunroofstatus": { "name": "Schiebedachstatus", "state": { "0": "geschlossen", "1": "offen", "2": "gekippt offen", "3": "in Bewegung", "4": "Anti-Bump Position", "5": "Zwischenposition Schiebe", "6": "Zwischenposition Kipp", "7": "Öffnet", "8": "Schließt", "9": "Anti-Bump Kipp", "10": "Zwischenposition", "11": "Öffnet (Kipp)", "12": "Schließt (Kipp)" } } } }, "sunroofstatus": { "state": { "0": "Geschlossen", "1": "Offen", "2": "Geöffnet gekippt", "3": "In Bewegung", "4": "Anti-Bump", "5": "Zwischenposition Schiebe", "6": "Zwischenposition Kipp", "7": "Öffnet", "8": "Schließt", "9": "Anti-Bump Kipp", "10": "Zwischenposition", "11": "Öffnet (Kipp)", "12": "Schließt (Kipp)" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Grün", "1": "Gelb", "2": "Rot" } }, "tirewarningsrdk": { "state": { "0": "Keine Warnung", "1": "Leichte Warnung", "2": "Niedriger Druck", "3": "Plattfuß" } }, "selectedchargeprogram": { "state": { "0": "Standard", "2": "Zuhause", "3": "Arbeit", "4": "Nicht unterstützt" } } }, "switch": { "auxheat": { "name": "Standheizung" }, "precond": { "name": "Vorklimatisierung" } }, "button": { "btn_preheat_start_now": { "name": "Vorklimatisierung starten" }, "btn_preheat_stop_now": { "name": "Vorklimatisierung stoppen" }, "btn_sigpos_start_now": { "name": "Signallicht blinken" } } }, "selector": { "charge_program": { "options": { "0": "Standard", "2": "Zuhause", "3": "Arbeit" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Nicht gesetzt", "active": "Aktiv", "inactive": "Inaktiv" } }, "temperature_configure": { "options": { "0": "Niedrig", "30": "Hoch" } } } } ================================================ FILE: custom_components/mbapi2020/translations/en.json ================================================ { "config": { "abort": { "already_configured": "Component is configured already.", "reauth_successful": "Reauth successful! Component reload in progress." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Unknown error. Please check the Home Assistant log for more information.", "2fa_required": "Two-factor authentication (2FA) accounts are not supported.", "legal_terms": "You need to accept the legal terms in the Mercedes website first" }, "step": { "user": { "data": { "region": "Region" }, "description": "Select your region.", "title": "Set up the Mercedes ME 2020 connection" }, "credentials": { "data": { "username": "MB username (email address)", "password": "Password" }, "description": "Enter your account details.", "title": "Mercedes ME 2020 - Login" }, "pin": { "data": { "password": "TAN (received via eMail or SMS)" }, "description": "Enter the TAN you have received via eMail or SMS to complete the authentication. If you have not received a TAN, please check your email inbox (and spam folder) or your SMS messages.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Restart of Home Assistant is required to finish auth update click submit to restart now.", "title": "Restart required" } } }, "title": "Restart required" } }, "options": { "abort": { "already_configured": "Component is configured already.", "reauth_successful": "Reauth successful! Component reload in progress." }, "step": { "init": { "data": { "cap_check_disabled": "Disable capabilities check", "enable_china_gcj_02": "Enable GCJ-02 translation (China only)", "delete_auth_file": "Delete authentication token now. Requires a restart of Home Assistant after save.", "excluded_cars": "VINs excluded (comma-sep)", "pin": "Security PIN (to be created in mobile app)", "save_files": "DEBUG ONLY: Enable save server messages to the messages folder", "overwrite_cap_precondnow": "Exp: Overwrite capability precondnow (set to true)" }, "description": "Configure your options. Some changes require a restart of Home Assistant.", "title": "Mercedes ME 2020 Options" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API reachable", "websocket_connection_state": "MB WS state", "cars_connected": "Connected cars", "version": "Version" } }, "services": { "refresh_access_token": { "name": "Refresh access token", "description": "Refresh the API access token" }, "auxheat_configure": { "name": "Auxheat configure", "description": "Command for configuring the auxiliary heating. It is possible to define three daytimes and select one active time.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "time_selection": { "name": "Time selection", "description": "The activated auxiliary heating preset time (0=no_selection, 1=time_1, 2=time_2, 3=time_3)" }, "time_1": { "name": "time_1", "description": "Daytime in minutes after midnight. E.g. valid value for 8 am would be 480. Value range is 0 to 1439." }, "time_2": { "name": "time_2", "description": "Daytime in minutes after midnight. E.g. valid value for 8 am would be 480. Value range is 0 to 1439." }, "time_3": { "name": "time_3", "description": "Daytime in minutes after midnight. E.g. valid value for 8 am would be 480. Value range is 0 to 1439." } } }, "auxheat_start": { "name": "Auxheat start", "description": "Start the auxiliary heating of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "auxheat_stop": { "name": "Auxheat stop", "description": "Stop the auxiliary heating of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "battery_max_soc_configure": { "name": "Battery max soc configure", "description": "Configure the maximum value for the state of charge of the HV battery of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "max_soc": { "name": "Max Soc", "description": "The maximum value for the state of charge of the HV battery (Value needs to be between 50 (some new cars like 2025 CLA supporting 30) and 100 and divisible by ten)" }, "charge_program": { "name": "Charge program", "description": "(Optional, Default=0) Charge program to change (0=Default, 2=Home, 3=Work) (not used for 2025 CLA)" } } }, "charge_program_configure": { "name": "Charge program configure", "description": "Command to select the charge program.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "charge_program": { "name": "Charge program", "description": "The activated charging program (0=Default, 2=Home, 3=Work)" }, "max_soc": { "name": "Max Soc", "description": "The maximum value for the state of charge of the HV battery (Value needs to be between 50 and 100 and divisible by ten)" } } }, "doors_unlock": { "name": "Doors unlock", "description": "Unlock a car defined by a vin. PIN setup required. See options dialog of the integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "pin": { "name": "Pin", "description": "security pin, required if not stored in the settings." } } }, "doors_lock": { "name": "Doors lock", "description": "Lock a car defined by a vin", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "download_images": { "name": "Download images", "description": "Downloads the app images to the components resource folder for a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "engine_start": { "name": "Engine start", "description": "Start the engine of a car defined by a vin. PIN setup required. See options dialog of the integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "pin": { "name": "Pin", "description": "Security pin, required if not stored in the settings." } } }, "engine_stop": { "name": "Engine stop", "description": "Stop the engine of a car defined by a vin. PIN setup required. See options dialog of the integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "hv_battery_start_conditioning": { "name": "HV Battery start conditioning", "description": "Start the HV battery conditioning of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "hv_battery_stop_conditioning": { "name": "HV Battery stop conditioning", "description": "Stop the HV battery conditioning of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "preconditioning_configure_seats": { "name": "Preconditioning configure seats", "description": "Send a preconditioning seat configuration command to a car defined by a VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "front_left": { "name": "Front left", "description": "Activate if the front left seat should be preconditioned." }, "front_right": { "name": "Front right", "description": "Activate if the front right seat should be preconditioned." }, "rear_left": { "name": "Rear left", "description": "Activate if the rear left seat should be preconditioned." }, "rear_right": { "name": "Rear right", "description": "Activate if the rear right seat should be preconditioned." } } }, "preheat_start": { "name": "Preconditioning start", "description": "Start the preconditioning of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "type": { "name": "Type", "description": "Method that is used to initiate the start process. 0=Now (Default), 1=Immediate - Use Immediate in case your car does not support now." } } }, "preheat_start_departure_time": { "name": "Preconditioning start with departure time", "description": "Start the preconditioning of a car defined by a vin and a given departure time.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "time": { "name": "Time", "description": "Departure time in minutes after midnight. E.g. valid value for 8 am would be 480. Value range is 0 to 1439." } } }, "preheat_stop": { "name": "Preconditioning stop", "description": "Stop the preconditioning of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "preheat_stop_departure_time": { "name": "Preconditioning stop mode departuretime", "description": "Stop the configured departure time preconditioning of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "preconditioning_configure": { "name": "Configure preconditioning departure", "description": "Configure preconditioning departure time mode. Use mode 0 (Disabled) to cancel scheduled departure preconditioning.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "departure_time_mode": { "name": "Departure Time Mode", "description": "0=Disabled, 1=Single Departure, 2=Weekly Departure" }, "departure_time": { "name": "Departure Time", "description": "Departure time in minutes after midnight (0-1439). Only used when mode > 0." } } }, "sigpos_start": { "name": "Start signal position", "description": "Start light signaling of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "sunroof_open": { "name": "Sunroof open", "description": "Open the sunroof of a car defined by a vin. PIN setup required. See options dialog of the integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "pin": { "name": "Pin", "description": "Security pin, required if not stored in the settings." } } }, "sunroof_tilt": { "name": "Sunroof tilt", "description": "Tilt the sunroof of a car defined by a vin. PIN setup required. See options dialog of the integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "pin": { "name": "Pin", "description": "Security pin, required if not stored in the settings." } } }, "sunroof_close": { "name": "Sunroof close", "description": "Close the sunroof of a car defined by a vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "temperature_configure": { "name": "Target temperature configure (precond/auxheat)", "description": "Configure the target preconditioning/auxheat temperatures for zones in a car defined by a VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "front_left": { "name": "Front left", "description": "Target temperature for the zone front_left in CELSIUS." }, "front_right": { "name": "Front right", "description": "Target temperature for the zone front_right in CELSIUS." }, "rear_left": { "name": "Rear left", "description": "Target temperature for the zone rear_left in CELSIUS. (if available)" }, "rear_right": { "name": "Rear right", "description": "Target temperature for the zone rear_right in CELSIUS. (if available)" } } }, "windows_open": { "name": "Windows open", "description": "Open the windows of a car defined by a vin. PIN setup required. See options dialog of the integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "pin": { "name": "Pin", "description": "Security pin, required if not stored in the settings." } } }, "windows_close": { "name": "Windows close", "description": "Close the windows of a car defined by a vin. PIN setup required. See options dialog of the integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" } } }, "windows_move": { "name": "Windows move", "description": "Move the windows of a car defined by a vin to a new position. PIN setup required. See options dialog of the integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "pin": { "name": "Pin", "description": "Security pin, required if not stored in the settings." }, "front_left": { "name": "Front left", "description": "The new position of the front left window (0=closed, 10=ventilating, 100=open)" }, "front_right": { "name": "Front right", "description": "The new position of the front left window (0=closed, 10=ventilating, 100=open)" }, "rear_left": { "name": "Rear left", "description": "The new position of the front left window (0=closed, 10=ventilating, 100=open)" }, "rear_right": { "name": "Rear right", "description": "The new position of the front left window (0=closed, 10=ventilating, 100=open)" } } }, "send_route": { "name": "Route send", "description": "Sends a route to the car. (Single location only)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "title": { "name": "Title", "description": "Title of the route" }, "latitude": { "name": "Latitude", "description": "Latitude of the location" }, "longitude": { "name": "Longitude", "description": "Longitude of the location" }, "city": { "name": "City", "description": "City name of the location" }, "postcode": { "name": "Postcode", "description": "Postcode of the location" }, "street": { "name": "Street", "description": "Street name of the location" } } }, "charging_break_clocktimer_configure": { "name": "Charging Break Clocktimer Configure", "description": "Configure charging breaks (AC only). This will overwrite the complete config for all slots in your car.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin of the car" }, "status_timer_1": { "name": "Status (Timer 1)", "description": "" }, "starttime_timer_1": { "name": "Start time (Timer 1)", "description": "Start time of the charge break window (Timer 1)" }, "stoptime_timer_1": { "name": "End Time (Timer 1)", "description": "End time of the charge break window (Timer 1)" }, "status_timer_2": { "name": "Status (Timer 2)", "description": "" }, "starttime_timer_2": { "name": "Start time (Timer 2)", "description": "Start time of the charge break window (Timer 2)" }, "stoptime_timer_2": { "name": "End Time (Timer 2)", "description": "End time of the charge break window (Timer 2)" }, "status_timer_3": { "name": "Status (Timer 3)", "description": "" }, "starttime_timer_3": { "name": "Start time (Timer 3)", "description": "Start time of the charge break window (Timer 3)" }, "stoptime_timer_3": { "name": "End Time (Timer 3)", "description": "End time of the charge break window (Timer 3)" }, "status_timer_4": { "name": "Status (Timer 4)", "description": "" }, "starttime_timer_4": { "name": "Start time (Timer 4)", "description": "Start time of the charge break window (Timer 4)" }, "stoptime_timer_4": { "name": "End Time (Timer 4)", "description": "End time of the charge break window (Timer 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Charging active" } }, "sensor": { "chargingpowerecolimit": { "name": "Charging power limit" }, "auxheatstatus": { "state": { "0": "Inactive", "1": "Normal heating", "2": "Normal ventilation", "3": "Manual heating", "4": "Post heating", "5": "Post ventilation", "6": "Auto heating" } }, "chargeflapacstatus": { "state": { "0": "Open", "1": "Closed", "2": "Flap pressed", "3": "Unknown" } }, "chargeflapdcstatus": { "state": { "0": "Open", "1": "Closed", "2": "Flap pressed", "3": "Unknown" } }, "chargingstatus": { "state": { "0": "charging", "1": "charging ends", "2": "Charge break", "3": "unplugged", "4": "failure", "5": "slow", "6": "fast", "7": "discharging", "8": "not charging", "9": "slow charging after reaching trip target", "10": "charging after reaching trip target", "11": "fast charging after reaching trip target", "12": "Connected", "13": "AC Charging", "14": "DC Charging", "15": "Battery calibration active", "16": "unknown" } }, "departuretimemode": { "state": { "0": "Disabled", "1": "Daily", "2": "Weekly" } }, "ignitionstate": { "state": { "0": "Locked", "1": "Off", "2": "Accessory", "4": "On", "5": "Start" } }, "interiorprotectionsensorstatus": { "state": { "0": "Not active", "1": "Not active", "2": "Active" }, "state_attributes": {} }, "lock": { "state": { "0": "Unlocked", "1": "Locked int", "2": "Locked", "3": "Partly unlocked", "4": "Unknown" }, "state_attributes": { "decklidstatus": { "name": "Deck lid", "state": { "false": "closed", "true": "open" } }, "doorstatusfrontleft": { "name": "Door front left", "state": { "false": "closed", "true": "open" } }, "doorstatusfrontright": { "name": "Door front right", "state": { "false": "closed", "true": "open" } }, "doorstatusrearleft": { "name": "Door rear left", "state": { "false": "closed", "true": "open" } }, "doorstatusrearright": { "name": "Door rear right", "state": { "false": "closed", "true": "open" } }, "doorlockstatusfrontleft": { "name": "Door lock front left", "state": { "false": "locked", "true": "unlocked" } }, "doorlockstatusfrontright": { "name": "Door lock front right", "state": { "false": "locked", "true": "unlocked" } }, "doorlockstatusrearleft": { "name": "Door lock rear left", "state": { "false": "locked", "true": "unlocked" } }, "doorlockstatusrearright": { "name": "Door lock rear right", "state": { "false": "locked", "true": "unlocked" } }, "doorlockstatusgas": { "name": "Gas lock", "state": { "false": "locked", "true": "unlocked" } }, "enginehoodstatus": { "name": "Engine hood", "state": { "false": "closed", "true": "open" } }, "doorstatusoverall": { "name": "Door status overall", "state": { "0": "open", "1": "closed", "2": "not existing", "3": "unknown" } }, "sunroofstatus": { "name": "Sunroof status", "state": { "0": "closed", "1": "open", "2": "lifting open", "3": "running", "4": "anti-booming position", "5": "sliding intermediate", "6": "lifting intermediate", "7": "opening", "8": "closing", "9": "anti-booming lifting", "10": "intermediate position", "11": "opening lifting", "12": "closing lifting" } } } }, "sunroofstatus": { "state": { "0": "Closed", "1": "Open", "2": "Open lifting", "3": "Running", "4": "Anti booming", "5": "Intermediate sliding", "6": "Intermediate lifting", "7": "Opening", "8": "Closing", "9": "Anti booming lifting", "10": "Intermediate position", "11": "Opening lifting", "12": "Closing lifting" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Green", "1": "Yellow", "2": "Red" } }, "tirewarningsrdk": { "state": { "0": "No warning", "1": "Soft warning", "2": "Low pressure", "3": "Deflation" } }, "selectedchargeprogram": { "state": { "0": "Standard", "2": "Home", "3": "Work", "4": "Not supported" } } }, "switch": { "auxheat": { "name": "Auxiliary Heating" }, "precond": { "name": "Pre-entry climate control" } }, "button": { "btn_preheat_start_now": { "name": "Preclimate start" }, "btn_preheat_stop_now": { "name": "Preclimate stop" }, "btn_sigpos_start_now": { "name": "Flash lights" } } }, "selector": { "charge_program": { "options": { "0": "Default", "2": "Home", "3": "Work" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Not set", "active": "Active", "inactive": "Inactive" } }, "temperature_configure": { "options": { "0": "Low", "30": "High" } } } } ================================================ FILE: custom_components/mbapi2020/translations/es.json ================================================ { "config": { "abort": { "already_configured": "El componente ya está configurado.", "reauth_successful": "¡Reautenticación exitosa! Recargando el componente." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Error desconocido. Por favor, revisa el registro de Home Assistant para más información.", "2fa_required": "Las cuentas con autenticación de dos factores (2FA) no son compatibles.", "legal_terms": "Primero debes aceptar los términos legales en el sitio web de Mercedes" }, "step": { "user": { "data": { "region": "Región" }, "description": "Selecciona tu región.", "title": "Configurar la conexión Mercedes ME 2020" }, "credentials": { "data": { "username": "Usuario MB (dirección de correo electrónico)", "password": "Contraseña" }, "description": "Introduce los datos de tu cuenta.", "title": "Mercedes ME 2020 - Iniciar sesión" }, "pin": { "data": { "password": "TAN (recibido por correo electrónico o SMS)" }, "description": "Introduce el TAN que has recibido por correo electrónico o SMS para completar la autenticación. Si no has recibido un TAN, por favor revisa tu bandeja de entrada de correo electrónico (y la carpeta de spam) o tus mensajes SMS.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Se requiere reiniciar Home Assistant para finalizar la actualización de autenticación, haz clic en enviar para reiniciar ahora.", "title": "Reinicio requerido" } } }, "title": "Reinicio requerido" } }, "options": { "abort": { "already_configured": "El componente ya está configurado.", "reauth_successful": "¡Reautenticación exitosa! Recargando el componente." }, "step": { "init": { "data": { "cap_check_disabled": "Deshabilitar verificación de capacidades", "enable_china_gcj_02": "Habilitar traducción GCJ-02 (solo China)", "delete_auth_file": "Eliminar el token de autenticación ahora. Se requiere un reinicio de Home Assistant después de guardar.", "excluded_cars": "VINs excluidos (separados por comas)", "pin": "PIN de seguridad (a crear en la aplicación móvil)", "save_files": "SOLO PARA DEBUG: Habilitar guardar mensajes del servidor en la carpeta de mensajes", "overwrite_cap_precondnow": "Exp: Sobrescribir capacidad precondnow (establecer en verdadero)" }, "description": "Configura tus opciones. Algunos cambios requieren un reinicio de Home Assistant.", "title": "Opciones Mercedes ME 2020" } } }, "system_health": { "info": { "api_endpoint_reachable": "API MB accesible", "websocket_connection_state": "Estado WS MB", "cars_connected": "Coches conectados", "version": "Versión" } }, "services": { "refresh_access_token": { "name": "Actualizar token de acceso", "description": "Actualizar el token de acceso a la API" }, "auxheat_configure": { "name": "Configurar calefacción auxiliar", "description": "Comando para configurar la calefacción auxiliar. Es posible definir tres horarios y seleccionar un tiempo activo.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "time_selection": { "name": "Selección de tiempo", "description": "El tiempo de calefacción auxiliar preestablecido activado (0=no_selection, 1=time_1, 2=time_2, 3=time_3)" }, "time_1": { "name": "time_1", "description": "Tiempo en minutos después de la medianoche. Por ejemplo, un valor válido para las 8 a.m. sería 480. El rango de valores es de 0 a 1439." }, "time_2": { "name": "time_2", "description": "Tiempo en minutos después de la medianoche. Por ejemplo, un valor válido para las 8 a.m. sería 480. El rango de valores es de 0 a 1439." }, "time_3": { "name": "time_3", "description": "Tiempo en minutos después de la medianoche. Por ejemplo, un valor válido para las 8 a.m. sería 480. El rango de valores es de 0 a 1439." } } }, "auxheat_start": { "name": "Iniciar calefacción auxiliar", "description": "Iniciar la calefacción auxiliar de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "auxheat_stop": { "name": "Detener calefacción auxiliar", "description": "Detener la calefacción auxiliar de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "battery_max_soc_configure": { "name": "Configurar máximo soc de batería", "description": "Configurar el valor máximo para el estado de carga de la batería HV de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "max_soc": { "name": "Máx Soc", "description": "El valor máximo para el estado de carga de la batería HV (el valor debe estar entre 50 (algunos coches nuevos como el CLA 2025 admiten 30) y 100 y ser divisible por diez)" }, "charge_program": { "name": "Programa de carga", "description": "(Opcional, Predeterminado=0) Programa de carga a cambiar (0=Predeterminado, 2=Casa, 3=Trabajo) (no usado para CLA 2025)" } } }, "charge_program_configure": { "name": "Configurar programa de carga", "description": "Comando para seleccionar el programa de carga.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "charge_program": { "name": "Programa de carga", "description": "El programa de carga activado (0=Predeterminado, 2=Casa, 3=Trabajo)" }, "max_soc": { "name": "Máx Soc", "description": "El valor máximo para el estado de carga de la batería HV (el valor debe estar entre 50 y 100 y ser divisible por diez)" } } }, "doors_unlock": { "name": "Desbloquear puertas", "description": "Desbloquear un coche definido por un vin. Se requiere configuración de PIN. Consulta el diálogo de opciones de la integración.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "pin": { "name": "Pin", "description": "PIN de seguridad, requerido si no está almacenado en la configuración." } } }, "doors_lock": { "name": "Bloquear puertas", "description": "Bloquear un coche definido por un vin", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "download_images": { "name": "Descargar imágenes", "description": "Descarga las imágenes de la aplicación a la carpeta de recursos del componente para un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "engine_start": { "name": "Iniciar motor", "description": "Iniciar el motor de un coche definido por un vin. Se requiere configuración de PIN. Consulta el diálogo de opciones de la integración.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "pin": { "name": "Pin", "description": "PIN de seguridad, requerido si no está almacenado en la configuración." } } }, "engine_stop": { "name": "Detener motor", "description": "Detener el motor de un coche definido por un vin. Se requiere configuración de PIN. Consulta el diálogo de opciones de la integración.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "hv_battery_start_conditioning": { "name": "Iniciar acondicionamiento de batería HV", "description": "Iniciar el acondicionamiento de la batería HV de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "hv_battery_stop_conditioning": { "name": "Detener acondicionamiento de batería HV", "description": "Detener el acondicionamiento de la batería HV de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "preconditioning_configure_seats": { "name": "Configurar preacondicionamiento de asientos", "description": "Enviar un comando de configuración de preacondicionamiento de asientos a un coche definido por un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "front_left": { "name": "Frente izquierdo", "description": "Activar si el asiento delantero izquierdo debe ser preacondicionado." }, "front_right": { "name": "Frente derecho", "description": "Activar si el asiento delantero derecho debe ser preacondicionado." }, "rear_left": { "name": "Detrás izquierdo", "description": "Activar si el asiento trasero izquierdo debe ser preacondicionado." }, "rear_right": { "name": "Detrás derecho", "description": "Activar si el asiento trasero derecho debe ser preacondicionado." } } }, "preheat_start": { "name": "Iniciar preacondicionamiento", "description": "Iniciar el preacondicionamiento de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "type": { "name": "Tipo", "description": "Método que se utiliza para iniciar el proceso de arranque. 0=Ahora (por defecto), 1=Inmediato - Utilice Inmediato en caso de que su coche no admita ahora." } } }, "preheat_start_departure_time": { "name": "Iniciar preacondicionamiento con hora de salida", "description": "Iniciar el preacondicionamiento de un coche definido por un vin y una hora de salida dada.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "time": { "name": "Hora", "description": "Hora de salida en minutos después de la medianoche. Por ejemplo, un valor válido para las 8 a.m. sería 480. El rango de valores es de 0 a 1439." } } }, "preheat_stop": { "name": "Detener preacondicionamiento", "description": "Detener el preacondicionamiento de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "preheat_stop_departure_time": { "name": "Detener modo de preacondicionamiento con hora de salida", "description": "Detener el preacondicionamiento configurado con hora de salida de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "preconditioning_configure": { "name": "Configurar salida de preacondicionamiento", "description": "Configurar el modo de hora de salida del preacondicionamiento. Usa el modo 0 (Deshabilitado) para cancelar el preacondicionamiento de salida programado.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "departure_time_mode": { "name": "Modo de hora de salida", "description": "0=Deshabilitado, 1=Salida única, 2=Salida semanal" }, "departure_time": { "name": "Hora de salida", "description": "Hora de salida en minutos después de la medianoche (0-1439). Solo se usa cuando el modo > 0." } } }, "sigpos_start": { "name": "Iniciar señal de posición", "description": "Iniciar señalización de luz de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "sunroof_open": { "name": "Abrir techo solar", "description": "Abrir el techo solar de un coche definido por un vin. Se requiere configuración de PIN. Consulta el diálogo de opciones de la integración.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "pin": { "name": "Pin", "description": "PIN de seguridad, requerido si no está almacenado en la configuración." } } }, "sunroof_tilt": { "name": "Inclinación del techo solar", "description": "Inclinar el techo solar de un coche definido por un vin. Se requiere configuración de PIN. Consulta el diálogo de opciones de la integración.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "pin": { "name": "Pin", "description": "PIN de seguridad, requerido si no está almacenado en la configuración." } } }, "sunroof_close": { "name": "Cerrar techo solar", "description": "Cerrar el techo solar de un coche definido por un vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "temperature_configure": { "name": "Configurar temperatura objetivo (preacond/auxheat)", "description": "Configurar las temperaturas objetivo de preacondicionamiento/calefacción auxiliar para zonas en un coche definido por un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "front_left": { "name": "Frente izquierdo", "description": "Temperatura objetivo para la zona frontal izquierda en CELSIUS." }, "front_right": { "name": "Frente derecho", "description": "Temperatura objetivo para la zona frontal derecha en CELSIUS." }, "rear_left": { "name": "Detrás izquierdo", "description": "Temperatura objetivo para la zona trasera izquierda en CELSIUS. (si está disponible)" }, "rear_right": { "name": "Detrás derecho", "description": "Temperatura objetivo para la zona trasera derecha en CELSIUS. (si está disponible)" } } }, "windows_open": { "name": "Abrir ventanas", "description": "Abrir las ventanas de un coche definido por un vin. Se requiere configuración de PIN. Consulta el diálogo de opciones de la integración.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "pin": { "name": "Pin", "description": "PIN de seguridad, requerido si no está almacenado en la configuración." } } }, "windows_close": { "name": "Cerrar ventanas", "description": "Cerrar las ventanas de un coche definido por un vin. Se requiere configuración de PIN. Consulta el diálogo de opciones de la integración.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" } } }, "windows_move": { "name": "Mover ventanas", "description": "Mover las ventanas de un coche definido por un vin a una nueva posición. Se requiere configuración de PIN. Consulta el diálogo de opciones de la integración.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "pin": { "name": "Pin", "description": "PIN de seguridad, requerido si no está almacenado en la configuración." }, "front_left": { "name": "Frente izquierdo", "description": "La nueva posición de la ventana delantera izquierda (0=cerrada, 10=ventilando, 100=abierta)" }, "front_right": { "name": "Frente derecho", "description": "La nueva posición de la ventana delantera derecha (0=cerrada, 10=ventilando, 100=abierta)" }, "rear_left": { "name": "Detrás izquierdo", "description": "La nueva posición de la ventana trasera izquierda (0=cerrada, 10=ventilando, 100=abierta)" }, "rear_right": { "name": "Detrás derecho", "description": "La nueva posición de la ventana trasera derecha (0=cerrada, 10=ventilando, 100=abierta)" } } }, "send_route": { "name": "Enviar ruta", "description": "Envía una ruta al coche. (Ubicación única solamente)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "title": { "name": "Título", "description": "Título de la ruta" }, "latitude": { "name": "Latitud", "description": "Latitud de la ubicación" }, "longitude": { "name": "Longitud", "description": "Longitud de la ubicación" }, "city": { "name": "Ciudad", "description": "Nombre de la ciudad de la ubicación" }, "postcode": { "name": "Código postal", "description": "Código postal de la ubicación" }, "street": { "name": "Calle", "description": "Nombre de la calle de la ubicación" } } }, "charging_break_clocktimer_configure": { "name": "Configurar temporizador de pausa de carga", "description": "Configurar pausas de carga (solo AC). Esto sobrescribirá la configuración completa para todos los slots en tu coche.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin del coche" }, "status_timer_1": { "name": "Estado (Temporizador 1)", "description": "" }, "starttime_timer_1": { "name": "Hora de inicio (Temporizador 1)", "description": "Hora de inicio de la ventana de pausa de carga (Temporizador 1)" }, "stoptime_timer_1": { "name": "Hora de fin (Temporizador 1)", "description": "Hora de fin de la ventana de pausa de carga (Temporizador 1)" }, "status_timer_2": { "name": "Estado (Temporizador 2)", "description": "" }, "starttime_timer_2": { "name": "Hora de inicio (Temporizador 2)", "description": "Hora de inicio de la ventana de pausa de carga (Temporizador 2)" }, "stoptime_timer_2": { "name": "Hora de fin (Temporizador 2)", "description": "Hora de fin de la ventana de pausa de carga (Temporizador 2)" }, "status_timer_3": { "name": "Estado (Temporizador 3)", "description": "" }, "starttime_timer_3": { "name": "Hora de inicio (Temporizador 3)", "description": "Hora de inicio de la ventana de pausa de carga (Temporizador 3)" }, "stoptime_timer_3": { "name": "Hora de fin (Temporizador 3)", "description": "Hora de fin de la ventana de pausa de carga (Temporizador 3)" }, "status_timer_4": { "name": "Estado (Temporizador 4)", "description": "" }, "starttime_timer_4": { "name": "Hora de inicio (Temporizador 4)", "description": "Hora de inicio de la ventana de pausa de carga (Temporizador 4)" }, "stoptime_timer_4": { "name": "Hora de fin (Temporizador 4)", "description": "Hora de fin de la ventana de pausa de carga (Temporizador 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Carga activa" } }, "sensor": { "chargingpowerecolimit": { "name": "Límite de potencia de carga" }, "auxheatstatus": { "state": { "0": "Inactivo", "1": "Calefacción normal", "2": "Ventilación normal", "3": "Calefacción manual", "4": "Calefacción posterior", "5": "Ventilación posterior", "6": "Calefacción automática" } }, "chargeflapacstatus": { "state": { "0": "Abierto", "1": "Cerrado", "2": "Aleta presionada", "3": "Desconocido" } }, "chargeflapdcstatus": { "state": { "0": "Abierto", "1": "Cerrado", "2": "Aleta presionada", "3": "Desconocido" } }, "chargingstatus": { "state": { "0": "Cargando", "1": "Carga finalizada", "2": "Pausa de carga", "3": "Desenchufado", "4": "Fallo", "5": "Lenta", "6": "Rápida", "7": "Descargando", "8": "No cargando", "9": "Carga lenta después de alcanzar el objetivo del viaje", "10": "Cargando después de alcanzar el objetivo del viaje", "11": "Carga rápida después de alcanzar el objetivo del viaje", "12": "Conectado", "13": "Carga AC", "14": "Carga DC", "15": "Calibración de batería activa", "16": "Desconocido" } }, "departuretimemode": { "state": { "0": "Deshabilitado", "1": "Diario", "2": "Semanal" } }, "ignitionstate": { "state": { "0": "Bloqueado", "1": "Apagado", "2": "Accesorio", "4": "Encendido", "5": "Inicio" } }, "interiorprotectionsensorstatus": { "state": { "0": "No activo", "1": "No activo", "2": "Activo" }, "state_attributes": {} }, "lock": { "state": { "0": "Desbloqueado", "1": "Bloqueado int", "2": "Bloqueado", "3": "Parcialmente desbloqueado", "4": "Desconocido" }, "state_attributes": { "decklidstatus": { "name": "Tapa del maletero", "state": { "false": "cerrada", "true": "abierta" } }, "doorstatusfrontleft": { "name": "Puerta delantera izquierda", "state": { "false": "cerrada", "true": "abierta" } }, "doorstatusfrontright": { "name": "Puerta delantera derecha", "state": { "false": "cerrada", "true": "abierta" } }, "doorstatusrearleft": { "name": "Puerta trasera izquierda", "state": { "false": "cerrada", "true": "abierta" } }, "doorstatusrearright": { "name": "Puerta trasera derecha", "state": { "false": "cerrada", "true": "abierta" } }, "doorlockstatusfrontleft": { "name": "Bloqueo de puerta delantera izquierda", "state": { "false": "bloqueada", "true": "desbloqueada" } }, "doorlockstatusfrontright": { "name": "Bloqueo de puerta delantera derecha", "state": { "false": "bloqueada", "true": "desbloqueada" } }, "doorlockstatusrearleft": { "name": "Bloqueo de puerta trasera izquierda", "state": { "false": "bloqueada", "true": "desbloqueada" } }, "doorlockstatusrearright": { "name": "Bloqueo de puerta trasera derecha", "state": { "false": "bloqueada", "true": "desbloqueada" } }, "doorlockstatusgas": { "name": "Bloqueo de gasolina", "state": { "false": "bloqueada", "true": "desbloqueada" } }, "enginehoodstatus": { "name": "Capó del motor", "state": { "false": "cerrado", "true": "abierto" } }, "doorstatusoverall": { "name": "Estado general de la puerta", "state": { "0": "abierta", "1": "cerrada", "2": "no existente", "3": "desconocido" } }, "sunroofstatus": { "name": "Estado del techo solar", "state": { "0": "cerrado", "1": "abierto", "2": "abriendo", "3": "en funcionamiento", "4": "posición anti-bumping", "5": "intermedio deslizante", "6": "intermedio levantando", "7": "abriendo", "8": "cerrando", "9": "levantando anti-bumping", "10": "posición intermedia", "11": "levantando abriendo", "12": "cerrando levantando" } } } }, "sunroofstatus": { "state": { "0": "Cerrado", "1": "Abierto", "2": "Levantando abierto", "3": "En funcionamiento", "4": "Anti-bumping", "5": "Deslizante intermedio", "6": "Levantando intermedio", "7": "Abriendo", "8": "Cerrando", "9": "Levantando anti-bumping", "10": "Posición intermedia", "11": "Levantando abriendo", "12": "Cerrando levantando" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Verde", "1": "Amarillo", "2": "Rojo" } }, "tirewarningsrdk": { "state": { "0": "Sin advertencia", "1": "Advertencia suave", "2": "Baja presión", "3": "Desinflado" } }, "selectedchargeprogram": { "state": { "0": "Estándar", "2": "Casa", "3": "Trabajo", "4": "No compatible" } } }, "switch": { "auxheat": { "name": "Calefacción auxiliar" }, "precond": { "name": "Control climático previo a la entrada" } }, "button": { "btn_preheat_start_now": { "name": "Iniciar preclimatización" }, "btn_preheat_stop_now": { "name": "Detener preclimatización" }, "btn_sigpos_start_now": { "name": "Destellar luces" } } }, "selector": { "charge_program": { "options": { "0": "Predeterminado", "2": "Casa", "3": "Trabajo" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "No establecido", "active": "Activo", "inactive": "Inactivo" } }, "temperature_configure": { "options": { "0": "Bajo", "30": "Alto" } } } } ================================================ FILE: custom_components/mbapi2020/translations/fi.json ================================================ { "config": { "abort": { "already_configured": "Komponentti on jo määritetty.", "reauth_successful": "Uudelleentodennus onnistui! Komponentin uudelleenlataus käynnissä." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Tuntematon virhe. Tarkista Home Assistant -loki lisätietoja varten.", "2fa_required": "Kaksivaiheisen todennuksen (2FA) tilejä ei tueta.", "legal_terms": "Sinun on hyväksyttävä käyttöehdot Mercedes-verkkosivustolla ensin" }, "step": { "user": { "data": { "region": "Alue" }, "description": "Valitse alueesi.", "title": "Mercedes ME 2020 -yhteyden määritys" }, "credentials": { "data": { "username": "MB-käyttäjänimi (sähköpostiosoite)", "password": "Salasana" }, "description": "Syötä tilisi tiedot.", "title": "Mercedes ME 2020 - Kirjautuminen" }, "pin": { "data": { "password": "TAN (vastaanotettu sähköpostilla tai tekstiviestillä)" }, "description": "Syötä sähköpostilla tai tekstiviestillä vastaanottamasi TAN-koodi todennuksen viimeistelemiseksi. Jos et ole vastaanottanut TAN-koodia, tarkista sähköpostisi saapuneet-kansio (ja roskaposti) tai tekstiviestisi.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Home Assistantin uudelleenkäynnistys vaaditaan todennuksen päivityksen viimeistelemiseksi. Napsauta Lähetä käynnistääksesi uudelleen nyt.", "title": "Uudelleenkäynnistys vaaditaan" } } }, "title": "Uudelleenkäynnistys vaaditaan" } }, "options": { "abort": { "already_configured": "Komponentti on jo määritetty.", "reauth_successful": "Uudelleentodennus onnistui! Komponentin uudelleenlataus käynnissä." }, "step": { "init": { "data": { "cap_check_disabled": "Poista ominaisuuksien tarkistus käytöstä", "enable_china_gcj_02": "Ota GCJ-02-muunnos käyttöön (vain Kiina)", "delete_auth_file": "Poista todennuspoletti nyt. Vaatii Home Assistantin uudelleenkäynnistyksen tallennuksen jälkeen.", "excluded_cars": "Poissuljetut VIN-numerot (pilkulla erotettuina)", "pin": "Turva-PIN (luotava mobiilisovelluksessa)", "save_files": "VAIN VIRHEENKORJAUS: Ota palvelinviestien tallennus käyttöön viestikansioon", "overwrite_cap_precondnow": "Kokeellinen: Ylikirjoita precondnow-ominaisuus (aseta todeksi)" }, "description": "Määritä asetuksesi. Jotkin muutokset vaativat Home Assistantin uudelleenkäynnistyksen.", "title": "Mercedes ME 2020 -asetukset" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API tavoitettavissa", "websocket_connection_state": "MB WS -tila", "cars_connected": "Yhdistetyt autot", "version": "Versio" } }, "services": { "refresh_access_token": { "name": "Päivitä käyttöoikeuspoletti", "description": "Päivitä API:n käyttöoikeuspoletti" }, "auxheat_configure": { "name": "Lisälämmittimen määritys", "description": "Komento lisälämmittimen määrittämiseksi. Voit määrittää kolme kellonaikaa ja valita yhden aktiivisen ajan.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "time_selection": { "name": "Aikavalinnan", "description": "Valittu lisälämmityksen esiasetettu aika (0=ei valintaa, 1=aika_1, 2=aika_2, 3=aika_3)" }, "time_1": { "name": "time_1", "description": "Vuorokaudenaika minuutteina keskiyöstä. Esim. klo 8:n arvo olisi 480. Arvoalue on 0–1439." }, "time_2": { "name": "time_2", "description": "Vuorokaudenaika minuutteina keskiyöstä. Esim. klo 8:n arvo olisi 480. Arvoalue on 0–1439." }, "time_3": { "name": "time_3", "description": "Vuorokaudenaika minuutteina keskiyöstä. Esim. klo 8:n arvo olisi 480. Arvoalue on 0–1439." } } }, "auxheat_start": { "name": "Lisälämmittimen käynnistys", "description": "Käynnistä VIN-numerolla määritetyn auton lisälämmitin.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "auxheat_stop": { "name": "Lisälämmittimen pysäytys", "description": "Pysäytä VIN-numerolla määritetyn auton lisälämmitin.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "battery_max_soc_configure": { "name": "Akun maksimi-SOC:n määritys", "description": "Määritä VIN-numerolla määritetyn auton korkeajänniteakun enimmäisvaraustaso.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "max_soc": { "name": "Max Soc", "description": "Korkeajänniteakun enimmäisvaraustaso (arvon on oltava välillä 50 (jotkin uudet autot, kuten 2025 CLA, tukevat arvoa 30) ja 100 ja jaollinen kymmenellä)" }, "charge_program": { "name": "Latausohjelma", "description": "(Valinnainen, oletus=0) Muutettava latausohjelma (0=Oletus, 2=Koti, 3=Työ) (ei käytössä 2025 CLA:ssa)" } } }, "charge_program_configure": { "name": "Latausohjelman määritys", "description": "Komento latausohjelman valitsemiseksi.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "charge_program": { "name": "Latausohjelma", "description": "Valittu latausohjelma (0=Oletus, 2=Koti, 3=Työ)" }, "max_soc": { "name": "Max Soc", "description": "Korkeajänniteakun enimmäisvaraustaso (arvon on oltava välillä 50 ja 100 ja jaollinen kymmenellä)" } } }, "doors_unlock": { "name": "Ovien avaus", "description": "Avaa VIN-numerolla määritetyn auton lukitus. PIN-koodin määritys vaaditaan. Katso integraation asetusvalikko.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "pin": { "name": "Pin", "description": "Turva-PIN, vaaditaan jos ei ole tallennettu asetuksiin." } } }, "doors_lock": { "name": "Ovien lukitus", "description": "Lukitse VIN-numerolla määritetty auto.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "download_images": { "name": "Lataa kuvat", "description": "Lataa sovelluksen kuvat komponentin resurssikansioon VIN-numerolla määritetylle autolle.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "engine_start": { "name": "Moottorin käynnistys", "description": "Käynnistä VIN-numerolla määritetyn auton moottori. PIN-koodin määritys vaaditaan. Katso integraation asetusvalikko.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "pin": { "name": "Pin", "description": "Turva-PIN, vaaditaan jos ei ole tallennettu asetuksiin." } } }, "engine_stop": { "name": "Moottorin sammutus", "description": "Sammuta VIN-numerolla määritetyn auton moottori. PIN-koodin määritys vaaditaan. Katso integraation asetusvalikko.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "hv_battery_start_conditioning": { "name": "Korkeajänniteakun esikäsittelyn käynnistys", "description": "Käynnistä VIN-numerolla määritetyn auton korkeajänniteakun esikäsittely.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "hv_battery_stop_conditioning": { "name": "Korkeajänniteakun esikäsittelyn pysäytys", "description": "Pysäytä VIN-numerolla määritetyn auton korkeajänniteakun esikäsittely.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "preconditioning_configure_seats": { "name": "Istuinten esilämmityksen määritys", "description": "Lähetä istuinten esilämmityskomento VIN-numerolla määritetylle autolle.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "front_left": { "name": "Vasen etuistuin", "description": "Ota käyttöön, jos vasen etuistuin tulisi esilämmittää." }, "front_right": { "name": "Oikea etuistuin", "description": "Ota käyttöön, jos oikea etuistuin tulisi esilämmittää." }, "rear_left": { "name": "Vasen takaistuin", "description": "Ota käyttöön, jos vasen takaistuin tulisi esilämmittää." }, "rear_right": { "name": "Oikea takaistuin", "description": "Ota käyttöön, jos oikea takaistuin tulisi esilämmittää." } } }, "preheat_start": { "name": "Esilämmityksen käynnistys", "description": "Käynnistä VIN-numerolla määritetyn auton esilämmitys.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "type": { "name": "Tyyppi", "description": "Käynnistysprosessin menetelmä. 0=Nyt (oletus), 1=Välitön - Käytä Välitön, jos autosi ei tue Nyt-toimintoa." } } }, "preheat_start_departure_time": { "name": "Esilämmityksen käynnistys lähtöajalla", "description": "Käynnistä VIN-numerolla määritetyn auton esilämmitys annetulla lähtöajalla.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "time": { "name": "Aika", "description": "Lähtöaika minuutteina keskiyöstä. Esim. klo 8:n arvo olisi 480. Arvoalue on 0–1439." } } }, "preheat_stop": { "name": "Esilämmityksen pysäytys", "description": "Pysäytä VIN-numerolla määritetyn auton esilämmitys.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "preheat_stop_departure_time": { "name": "Esilämmityksen lähtöaikatilan pysäytys", "description": "Pysäytä VIN-numerolla määritetyn auton ajastettu lähtöajan esilämmitys.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "preconditioning_configure": { "name": "Esilämmityksen lähtöajan määritys", "description": "Määritä esilämmityksen lähtöaikatila. Käytä tilaa 0 (Pois käytöstä) peruuttaaksesi ajastetun lähtöajan esilämmityksen.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "departure_time_mode": { "name": "Lähtöaikatila", "description": "0=Pois käytöstä, 1=Yksittäinen lähtö, 2=Viikoittainen lähtö" }, "departure_time": { "name": "Lähtöaika", "description": "Lähtöaika minuutteina keskiyöstä (0–1439). Käytetään vain kun tila > 0." } } }, "sigpos_start": { "name": "Käynnistä merkkivalot", "description": "Käynnistä VIN-numerolla määritetyn auton valomerkinanto.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "sunroof_open": { "name": "Kattoikkunan avaus", "description": "Avaa VIN-numerolla määritetyn auton kattoikkuna. PIN-koodin määritys vaaditaan. Katso integraation asetusvalikko.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "pin": { "name": "Pin", "description": "Turva-PIN, vaaditaan jos ei ole tallennettu asetuksiin." } } }, "sunroof_tilt": { "name": "Kattoikkunan kallistus", "description": "Kallista VIN-numerolla määritetyn auton kattoikkuna. PIN-koodin määritys vaaditaan. Katso integraation asetusvalikko.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "pin": { "name": "Pin", "description": "Turva-PIN, vaaditaan jos ei ole tallennettu asetuksiin." } } }, "sunroof_close": { "name": "Kattoikkunan sulkeminen", "description": "Sulje VIN-numerolla määritetyn auton kattoikkuna.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "temperature_configure": { "name": "Kohdelämpötilan määritys (esilämmitys/lisälämmitin)", "description": "Määritä esilämmityksen/lisälämmittimen kohdelämpötilat vyöhykkeittäin VIN-numerolla määritetylle autolle.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "front_left": { "name": "Vasen etu", "description": "Kohdelämpötila vyöhykkeelle vasen etu CELSIUSASTEINA." }, "front_right": { "name": "Oikea etu", "description": "Kohdelämpötila vyöhykkeelle oikea etu CELSIUSASTEINA." }, "rear_left": { "name": "Vasen taka", "description": "Kohdelämpötila vyöhykkeelle vasen taka CELSIUSASTEINA. (jos saatavilla)" }, "rear_right": { "name": "Oikea taka", "description": "Kohdelämpötila vyöhykkeelle oikea taka CELSIUSASTEINA. (jos saatavilla)" } } }, "windows_open": { "name": "Ikkunoiden avaus", "description": "Avaa VIN-numerolla määritetyn auton ikkunat. PIN-koodin määritys vaaditaan. Katso integraation asetusvalikko.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "pin": { "name": "Pin", "description": "Turva-PIN, vaaditaan jos ei ole tallennettu asetuksiin." } } }, "windows_close": { "name": "Ikkunoiden sulkeminen", "description": "Sulje VIN-numerolla määritetyn auton ikkunat. PIN-koodin määritys vaaditaan. Katso integraation asetusvalikko.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" } } }, "windows_move": { "name": "Ikkunoiden siirto", "description": "Siirrä VIN-numerolla määritetyn auton ikkunat uuteen asentoon. PIN-koodin määritys vaaditaan. Katso integraation asetusvalikko.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "pin": { "name": "Pin", "description": "Turva-PIN, vaaditaan jos ei ole tallennettu asetuksiin." }, "front_left": { "name": "Vasen etu", "description": "Vasemman etuikkunan uusi asento (0=suljettu, 10=tuuletus, 100=auki)" }, "front_right": { "name": "Oikea etu", "description": "Oikean etuikkunan uusi asento (0=suljettu, 10=tuuletus, 100=auki)" }, "rear_left": { "name": "Vasen taka", "description": "Vasemman takaikkunan uusi asento (0=suljettu, 10=tuuletus, 100=auki)" }, "rear_right": { "name": "Oikea taka", "description": "Oikean takaikkunan uusi asento (0=suljettu, 10=tuuletus, 100=auki)" } } }, "send_route": { "name": "Reitin lähetys", "description": "Lähettää reitin autoon. (Vain yksittäinen sijainti)", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "title": { "name": "Otsikko", "description": "Reitin otsikko" }, "latitude": { "name": "Leveysaste", "description": "Sijainnin leveysaste" }, "longitude": { "name": "Pituusaste", "description": "Sijainnin pituusaste" }, "city": { "name": "Kaupunki", "description": "Sijainnin kaupungin nimi" }, "postcode": { "name": "Postinumero", "description": "Sijainnin postinumero" }, "street": { "name": "Katu", "description": "Sijainnin kadun nimi" } } }, "charging_break_clocktimer_configure": { "name": "Lataustauon ajastimen määritys", "description": "Määritä lataustauot (vain AC). Tämä korvaa kaikkien aikapaikkojen nykyisen määrityksen autossasi.", "fields": { "vin": { "name": "Vin", "description": "Auton VIN/FIN-numero" }, "status_timer_1": { "name": "Tila (Ajastin 1)", "description": "" }, "starttime_timer_1": { "name": "Alkamisaika (Ajastin 1)", "description": "Lataustaukoikkunan alkamisaika (Ajastin 1)" }, "stoptime_timer_1": { "name": "Päättymisaika (Ajastin 1)", "description": "Lataustaukoikkunan päättymisaika (Ajastin 1)" }, "status_timer_2": { "name": "Tila (Ajastin 2)", "description": "" }, "starttime_timer_2": { "name": "Alkamisaika (Ajastin 2)", "description": "Lataustaukoikkunan alkamisaika (Ajastin 2)" }, "stoptime_timer_2": { "name": "Päättymisaika (Ajastin 2)", "description": "Lataustaukoikkunan päättymisaika (Ajastin 2)" }, "status_timer_3": { "name": "Tila (Ajastin 3)", "description": "" }, "starttime_timer_3": { "name": "Alkamisaika (Ajastin 3)", "description": "Lataustaukoikkunan alkamisaika (Ajastin 3)" }, "stoptime_timer_3": { "name": "Päättymisaika (Ajastin 3)", "description": "Lataustaukoikkunan päättymisaika (Ajastin 3)" }, "status_timer_4": { "name": "Tila (Ajastin 4)", "description": "" }, "starttime_timer_4": { "name": "Alkamisaika (Ajastin 4)", "description": "Lataustaukoikkunan alkamisaika (Ajastin 4)" }, "stoptime_timer_4": { "name": "Päättymisaika (Ajastin 4)", "description": "Lataustaukoikkunan päättymisaika (Ajastin 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Lataus aktiivinen" } }, "sensor": { "chargingpowerecolimit": { "name": "Lataustehon raja" }, "auxheatstatus": { "state": { "0": "Ei aktiivinen", "1": "Normaali lämmitys", "2": "Normaali tuuletus", "3": "Manuaalinen lämmitys", "4": "Jälkilämmitys", "5": "Jälkituuletus", "6": "Automaattinen lämmitys" } }, "chargeflapacstatus": { "state": { "0": "Auki", "1": "Suljettu", "2": "Luukku painettu", "3": "Tuntematon" } }, "chargeflapdcstatus": { "state": { "0": "Auki", "1": "Suljettu", "2": "Luukku painettu", "3": "Tuntematon" } }, "chargingstatus": { "state": { "0": "ladataan", "1": "lataus päättyy", "2": "Lataustauko", "3": "irrotettu", "4": "häiriö", "5": "hidas", "6": "nopea", "7": "purkautuu", "8": "ei lataa", "9": "hidas lataus matkatason saavuttamisen jälkeen", "10": "lataus matkatason saavuttamisen jälkeen", "11": "nopea lataus matkatason saavuttamisen jälkeen", "12": "Yhdistetty", "13": "AC-lataus", "14": "DC-lataus", "15": "Akun kalibrointi aktiivinen", "16": "tuntematon" } }, "departuretimemode": { "state": { "0": "Pois käytöstä", "1": "Päivittäinen", "2": "Viikoittainen" } }, "ignitionstate": { "state": { "0": "Lukittu", "1": "Pois", "2": "Lisälaitteet", "4": "Päällä", "5": "Käynnistys" } }, "interiorprotectionsensorstatus": { "state": { "0": "Ei aktiivinen", "1": "Ei aktiivinen", "2": "Aktiivinen" }, "state_attributes": {} }, "lock": { "state": { "0": "Lukitsematon", "1": "Lukittu sis.", "2": "Lukittu", "3": "Osittain lukitsematon", "4": "Tuntematon" }, "state_attributes": { "decklidstatus": { "name": "Tavaratilan kansi", "state": { "false": "suljettu", "true": "auki" } }, "doorstatusfrontleft": { "name": "Vasen etuovi", "state": { "false": "suljettu", "true": "auki" } }, "doorstatusfrontright": { "name": "Oikea etuovi", "state": { "false": "suljettu", "true": "auki" } }, "doorstatusrearleft": { "name": "Vasen takaovi", "state": { "false": "suljettu", "true": "auki" } }, "doorstatusrearright": { "name": "Oikea takaovi", "state": { "false": "suljettu", "true": "auki" } }, "doorlockstatusfrontleft": { "name": "Vasemman etuoven lukko", "state": { "false": "lukittu", "true": "lukitsematon" } }, "doorlockstatusfrontright": { "name": "Oikean etuoven lukko", "state": { "false": "lukittu", "true": "lukitsematon" } }, "doorlockstatusrearleft": { "name": "Vasemman takaoven lukko", "state": { "false": "lukittu", "true": "lukitsematon" } }, "doorlockstatusrearright": { "name": "Oikean takaoven lukko", "state": { "false": "lukittu", "true": "lukitsematon" } }, "doorlockstatusgas": { "name": "Polttoainelukko", "state": { "false": "lukittu", "true": "lukitsematon" } }, "enginehoodstatus": { "name": "Konepelti", "state": { "false": "suljettu", "true": "auki" } }, "doorstatusoverall": { "name": "Ovien kokonaistila", "state": { "0": "auki", "1": "suljettu", "2": "ei olemassa", "3": "tuntematon" } }, "sunroofstatus": { "name": "Kattoikkunan tila", "state": { "0": "suljettu", "1": "auki", "2": "tuuletusasento auki", "3": "liikkuu", "4": "melunvaimennusasento", "5": "liu'utus välitila", "6": "kallistus välitila", "7": "avautuu", "8": "sulkeutuu", "9": "melunvaimennus kallistettu", "10": "väliasento", "11": "kallistus avautuu", "12": "kallistus sulkeutuu" } } } }, "sunroofstatus": { "state": { "0": "Suljettu", "1": "Auki", "2": "Tuuletusasento auki", "3": "Liikkuu", "4": "Melunvaimennus", "5": "Liu'utus välitila", "6": "Kallistus välitila", "7": "Avautuu", "8": "Sulkeutuu", "9": "Melunvaimennus kallistettu", "10": "Väliasento", "11": "Kallistus avautuu", "12": "Kallistus sulkeutuu" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Vihreä", "1": "Keltainen", "2": "Punainen" } }, "tirewarningsrdk": { "state": { "0": "Ei varoitusta", "1": "Lievä varoitus", "2": "Matala paine", "3": "Tyhjentyminen" } }, "selectedchargeprogram": { "state": { "0": "Vakio", "2": "Koti", "3": "Työ", "4": "Ei tuettu" } } }, "switch": { "auxheat": { "name": "Lisälämmitin" }, "precond": { "name": "Sisääntulon ilmastoinnin esisäätö" } }, "button": { "btn_preheat_start_now": { "name": "Esilämmityksen käynnistys" }, "btn_preheat_stop_now": { "name": "Esilämmityksen pysäytys" }, "btn_sigpos_start_now": { "name": "Vilkuta valoja" } } }, "selector": { "charge_program": { "options": { "0": "Oletus", "2": "Koti", "3": "Työ" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Ei asetettu", "active": "Aktiivinen", "inactive": "Ei aktiivinen" } }, "temperature_configure": { "options": { "0": "Matala", "30": "Korkea" } } } } ================================================ FILE: custom_components/mbapi2020/translations/fr.json ================================================ { "config": { "abort": { "already_configured": "Le composant est deja configure.", "reauth_successful": "Reauthentification reussie ! Rechargement du composant en cours." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Erreur inconnue. Veuillez consulter le journal de Home Assistant pour plus d'informations.", "2fa_required": "Les comptes avec authentification a deux facteurs (2FA) ne sont pas pris en charge.", "legal_terms": "Vous devez d'abord accepter les conditions juridiques sur le site web Mercedes" }, "step": { "user": { "data": { "region": "Region" }, "description": "Selectionnez votre region.", "title": "Configurer la connexion Mercedes ME 2020" }, "credentials": { "data": { "username": "Nom d'utilisateur MB (adresse e-mail)", "password": "Mot de passe" }, "description": "Entrez les details de votre compte.", "title": "Mercedes ME 2020 - Connexion" }, "pin": { "data": { "password": "TAN (recu par e-mail ou SMS)" }, "description": "Entrez le TAN que vous avez recu par e-mail ou SMS pour terminer l'authentification. Si vous n'avez pas recu de TAN, veuillez verifier votre boite de reception (et le dossier spam) ou vos messages SMS.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Un redemarrage de Home Assistant est necessaire pour terminer la mise a jour de l'authentification. Cliquez sur soumettre pour redemarrer maintenant.", "title": "Redemarrage necessaire" } } }, "title": "Redemarrage necessaire" } }, "options": { "abort": { "already_configured": "Le composant est deja configure.", "reauth_successful": "Reauthentification reussie ! Rechargement du composant en cours." }, "step": { "init": { "data": { "cap_check_disabled": "Desactiver la verification des capacites", "enable_china_gcj_02": "Activer la traduction GCJ-02 (Chine uniquement)", "delete_auth_file": "Supprimer le jeton d'authentification maintenant. Necessite un redemarrage de Home Assistant apres la sauvegarde.", "excluded_cars": "VIN exclus (separes par des virgules)", "pin": "PIN de securite (a creer dans l'application mobile)", "save_files": "DEBOGAGE UNIQUEMENT : Activer l'enregistrement des messages du serveur dans le dossier messages", "overwrite_cap_precondnow": "Exp : Remplacer la capacite precondnow (definir sur vrai)" }, "description": "Configurez vos options. Certaines modifications necessitent un redemarrage de Home Assistant.", "title": "Options Mercedes ME 2020" } } }, "system_health": { "info": { "api_endpoint_reachable": "API MB accessible", "websocket_connection_state": "Etat WS MB", "cars_connected": "Voitures connectees", "version": "Version" } }, "services": { "refresh_access_token": { "name": "Actualiser le jeton d'acces", "description": "Actualiser le jeton d'acces de l'API" }, "auxheat_configure": { "name": "Configurer le chauffage auxiliaire", "description": "Commande pour configurer le chauffage auxiliaire. Il est possible de definir trois horaires et de selectionner un horaire actif.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "time_selection": { "name": "Selection de l'horaire", "description": "L'horaire de chauffage auxiliaire preselectionne active (0=aucune_selection, 1=horaire_1, 2=horaire_2, 3=horaire_3)" }, "time_1": { "name": "time_1", "description": "Heure de la journee en minutes apres minuit. Par ex. la valeur valide pour 8h serait 480. La plage de valeurs est de 0 a 1439." }, "time_2": { "name": "time_2", "description": "Heure de la journee en minutes apres minuit. Par ex. la valeur valide pour 8h serait 480. La plage de valeurs est de 0 a 1439." }, "time_3": { "name": "time_3", "description": "Heure de la journee en minutes apres minuit. Par ex. la valeur valide pour 8h serait 480. La plage de valeurs est de 0 a 1439." } } }, "auxheat_start": { "name": "Demarrer le chauffage auxiliaire", "description": "Demarrer le chauffage auxiliaire d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "auxheat_stop": { "name": "Arreter le chauffage auxiliaire", "description": "Arreter le chauffage auxiliaire d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "battery_max_soc_configure": { "name": "Configurer le niveau de charge max de la batterie", "description": "Configurer la valeur maximale de l'etat de charge de la batterie HT d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "max_soc": { "name": "Max Soc", "description": "La valeur maximale de l'etat de charge de la batterie HT (la valeur doit etre comprise entre 50 (certains nouveaux vehicules comme le CLA 2025 prennent en charge 30) et 100 et divisible par dix)" }, "charge_program": { "name": "Programme de charge", "description": "(Optionnel, Defaut=0) Programme de charge a modifier (0=Defaut, 2=Domicile, 3=Travail) (non utilise pour le CLA 2025)" } } }, "charge_program_configure": { "name": "Configurer le programme de charge", "description": "Commande pour selectionner le programme de charge.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "charge_program": { "name": "Programme de charge", "description": "Le programme de charge active (0=Defaut, 2=Domicile, 3=Travail)" }, "max_soc": { "name": "Max Soc", "description": "La valeur maximale de l'etat de charge de la batterie HT (la valeur doit etre comprise entre 50 et 100 et divisible par dix)" } } }, "doors_unlock": { "name": "Deverrouiller les portes", "description": "Deverrouiller un vehicule defini par un VIN. Configuration du PIN requise. Voir la boite de dialogue des options de l'integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "pin": { "name": "Pin", "description": "PIN de securite, requis s'il n'est pas enregistre dans les parametres." } } }, "doors_lock": { "name": "Verrouiller les portes", "description": "Verrouiller un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "download_images": { "name": "Telecharger les images", "description": "Telecharge les images de l'application dans le dossier de ressources du composant pour un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "engine_start": { "name": "Demarrer le moteur", "description": "Demarrer le moteur d'un vehicule defini par un VIN. Configuration du PIN requise. Voir la boite de dialogue des options de l'integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "pin": { "name": "Pin", "description": "PIN de sécurité, requis s'il n'est pas enregistré dans les paramètres." } } }, "engine_stop": { "name": "Arreter le moteur", "description": "Arreter le moteur d'un vehicule defini par un VIN. Configuration du PIN requise. Voir la boite de dialogue des options de l'integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "hv_battery_start_conditioning": { "name": "Demarrer le conditionnement de la batterie HT", "description": "Demarrer le conditionnement de la batterie HT d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "hv_battery_stop_conditioning": { "name": "Arreter le conditionnement de la batterie HT", "description": "Arreter le conditionnement de la batterie HT d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "preconditioning_configure_seats": { "name": "Configurer le preconditionnement des sieges", "description": "Envoyer une commande de configuration de preconditionnement des sieges a un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "front_left": { "name": "Avant gauche", "description": "Activer si le siege avant gauche doit etre preconditionne." }, "front_right": { "name": "Avant droit", "description": "Activer si le siege avant droit doit etre preconditionne." }, "rear_left": { "name": "Arriere gauche", "description": "Activer si le siege arriere gauche doit etre preconditionne." }, "rear_right": { "name": "Arriere droit", "description": "Activer si le siege arriere droit doit etre preconditionne." } } }, "preheat_start": { "name": "Demarrer le preconditionnement", "description": "Demarrer le preconditionnement d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "type": { "name": "Type", "description": "Methode utilisee pour initier le processus de demarrage. 0=Maintenant (Defaut), 1=Immediat - Utilisez Immediat si votre vehicule ne prend pas en charge Maintenant." } } }, "preheat_start_departure_time": { "name": "Demarrer le preconditionnement avec heure de depart", "description": "Demarrer le preconditionnement d'un vehicule defini par un VIN et une heure de depart donnee.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "time": { "name": "Heure", "description": "Heure de depart en minutes apres minuit. Par ex. la valeur valide pour 8h serait 480. La plage de valeurs est de 0 a 1439." } } }, "preheat_stop": { "name": "Arreter le preconditionnement", "description": "Arreter le preconditionnement d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "preheat_stop_departure_time": { "name": "Arreter le preconditionnement mode heure de depart", "description": "Arreter le preconditionnement avec heure de depart configuree d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "preconditioning_configure": { "name": "Configurer le depart preconditionne", "description": "Configurer le mode de preconditionnement avec heure de depart. Utilisez le mode 0 (Desactive) pour annuler le preconditionnement programme.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "departure_time_mode": { "name": "Mode heure de depart", "description": "0=Desactive, 1=Depart unique, 2=Depart hebdomadaire" }, "departure_time": { "name": "Heure de depart", "description": "Heure de depart en minutes apres minuit (0-1439). Utilise uniquement lorsque le mode > 0." } } }, "sigpos_start": { "name": "Demarrer la signalisation lumineuse", "description": "Demarrer la signalisation lumineuse d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "sunroof_open": { "name": "Ouvrir le toit ouvrant", "description": "Ouvrir le toit ouvrant d'un vehicule defini par un VIN. Configuration du PIN requise. Voir la boite de dialogue des options de l'integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "pin": { "name": "Pin", "description": "PIN de sécurité, requis s'il n'est pas enregistré dans les paramètres." } } }, "sunroof_tilt": { "name": "Entrebaillier le toit ouvrant", "description": "Entrebailler le toit ouvrant d'un vehicule defini par un VIN. Configuration du PIN requise. Voir la boite de dialogue des options de l'integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "pin": { "name": "Pin", "description": "PIN de sécurité, requis s'il n'est pas enregistré dans les paramètres." } } }, "sunroof_close": { "name": "Fermer le toit ouvrant", "description": "Fermer le toit ouvrant d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "temperature_configure": { "name": "Configurer la temperature cible (precond/chauffage aux.)", "description": "Configurer les temperatures cibles de preconditionnement/chauffage auxiliaire pour les zones d'un vehicule defini par un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "front_left": { "name": "Avant gauche", "description": "Temperature cible pour la zone avant gauche en CELSIUS." }, "front_right": { "name": "Avant droit", "description": "Temperature cible pour la zone avant droit en CELSIUS." }, "rear_left": { "name": "Arriere gauche", "description": "Temperature cible pour la zone arriere gauche en CELSIUS. (si disponible)" }, "rear_right": { "name": "Arriere droit", "description": "Temperature cible pour la zone arriere droit en CELSIUS. (si disponible)" } } }, "windows_open": { "name": "Ouvrir les vitres", "description": "Ouvrir les vitres d'un vehicule defini par un VIN. Configuration du PIN requise. Voir la boite de dialogue des options de l'integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "pin": { "name": "Pin", "description": "PIN de securite, requis s'il n'est pas enregistre dans les parametres." } } }, "windows_close": { "name": "Fermer les vitres", "description": "Fermer les vitres d'un vehicule defini par un VIN. Configuration du PIN requise. Voir la boite de dialogue des options de l'integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" } } }, "windows_move": { "name": "Deplacer les vitres", "description": "Deplacer les vitres d'un vehicule defini par un VIN vers une nouvelle position. Configuration du PIN requise. Voir la boite de dialogue des options de l'integration.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "pin": { "name": "Pin", "description": "PIN de sécurité, requis s'il n'est pas enregistré dans les paramètres." }, "front_left": { "name": "Avant gauche", "description": "La nouvelle position de la vitre avant gauche (0=fermee, 10=entrebaillee, 100=ouverte)" }, "front_right": { "name": "Avant droit", "description": "La nouvelle position de la vitre avant droite (0=fermee, 10=entrebaillee, 100=ouverte)" }, "rear_left": { "name": "Arriere gauche", "description": "La nouvelle position de la vitre arriere gauche (0=fermee, 10=entrebaillee, 100=ouverte)" }, "rear_right": { "name": "Arriere droit", "description": "La nouvelle position de la vitre arriere droite (0=fermee, 10=entrebaillee, 100=ouverte)" } } }, "send_route": { "name": "Envoyer un itineraire", "description": "Envoie un itineraire au vehicule. (Un seul emplacement uniquement)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "title": { "name": "Titre", "description": "Titre de l'itineraire" }, "latitude": { "name": "Latitude", "description": "Latitude de l'emplacement" }, "longitude": { "name": "Longitude", "description": "Longitude de l'emplacement" }, "city": { "name": "Ville", "description": "Nom de la ville de l'emplacement" }, "postcode": { "name": "Code postal", "description": "Code postal de l'emplacement" }, "street": { "name": "Rue", "description": "Nom de la rue de l'emplacement" } } }, "charging_break_clocktimer_configure": { "name": "Configurer les pauses de charge programmees", "description": "Configurer les pauses de charge (CA uniquement). Cela ecrasera la configuration complete de tous les creneaux de votre vehicule.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin du vehicule" }, "status_timer_1": { "name": "Statut (Minuteur 1)", "description": "" }, "starttime_timer_1": { "name": "Heure de debut (Minuteur 1)", "description": "Heure de debut de la fenetre de pause de charge (Minuteur 1)" }, "stoptime_timer_1": { "name": "Heure de fin (Minuteur 1)", "description": "Heure de fin de la fenetre de pause de charge (Minuteur 1)" }, "status_timer_2": { "name": "Statut (Minuteur 2)", "description": "" }, "starttime_timer_2": { "name": "Heure de debut (Minuteur 2)", "description": "Heure de debut de la fenetre de pause de charge (Minuteur 2)" }, "stoptime_timer_2": { "name": "Heure de fin (Minuteur 2)", "description": "Heure de fin de la fenetre de pause de charge (Minuteur 2)" }, "status_timer_3": { "name": "Statut (Minuteur 3)", "description": "" }, "starttime_timer_3": { "name": "Heure de debut (Minuteur 3)", "description": "Heure de debut de la fenetre de pause de charge (Minuteur 3)" }, "stoptime_timer_3": { "name": "Heure de fin (Minuteur 3)", "description": "Heure de fin de la fenetre de pause de charge (Minuteur 3)" }, "status_timer_4": { "name": "Statut (Minuteur 4)", "description": "" }, "starttime_timer_4": { "name": "Heure de debut (Minuteur 4)", "description": "Heure de debut de la fenetre de pause de charge (Minuteur 4)" }, "stoptime_timer_4": { "name": "Heure de fin (Minuteur 4)", "description": "Heure de fin de la fenetre de pause de charge (Minuteur 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Charge en cours" } }, "sensor": { "chargingpowerecolimit": { "name": "Limite de puissance de charge" }, "auxheatstatus": { "state": { "0": "Inactif", "1": "Chauffage normal", "2": "Ventilation normale", "3": "Chauffage manuel", "4": "Post-chauffage", "5": "Post-ventilation", "6": "Chauffage automatique" } }, "chargeflapacstatus": { "state": { "0": "Ouvert", "1": "Ferme", "2": "Trappe pressee", "3": "Inconnu" } }, "chargeflapdcstatus": { "state": { "0": "Ouvert", "1": "Ferme", "2": "Trappe pressee", "3": "Inconnu" } }, "chargingstatus": { "state": { "0": "en charge", "1": "fin de charge", "2": "Pause de charge", "3": "debranche", "4": "erreur", "5": "lente", "6": "rapide", "7": "en decharge", "8": "pas en charge", "9": "charge lente apres avoir atteint l'objectif du trajet", "10": "en charge apres avoir atteint l'objectif du trajet", "11": "charge rapide apres avoir atteint l'objectif du trajet", "12": "Connecte", "13": "Charge CA", "14": "Charge CC", "15": "Calibrage de la batterie en cours", "16": "inconnu" } }, "departuretimemode": { "state": { "0": "Desactive", "1": "Quotidien", "2": "Hebdomadaire" } }, "ignitionstate": { "state": { "0": "Verrouille", "1": "Eteint", "2": "Accessoire", "4": "Allume", "5": "Demarrage" } }, "interiorprotectionsensorstatus": { "state": { "0": "Non actif", "1": "Non actif", "2": "Actif" }, "state_attributes": {} }, "lock": { "state": { "0": "Deverrouille", "1": "Verrouille int.", "2": "Verrouille", "3": "Partiellement deverrouille", "4": "Inconnu" }, "state_attributes": { "decklidstatus": { "name": "Couvercle de coffre", "state": { "false": "ferme", "true": "ouvert" } }, "doorstatusfrontleft": { "name": "Porte avant gauche", "state": { "false": "fermee", "true": "ouverte" } }, "doorstatusfrontright": { "name": "Porte avant droite", "state": { "false": "fermee", "true": "ouverte" } }, "doorstatusrearleft": { "name": "Porte arriere gauche", "state": { "false": "fermee", "true": "ouverte" } }, "doorstatusrearright": { "name": "Porte arriere droite", "state": { "false": "fermee", "true": "ouverte" } }, "doorlockstatusfrontleft": { "name": "Serrure porte avant gauche", "state": { "false": "verrouillee", "true": "deverrouillee" } }, "doorlockstatusfrontright": { "name": "Serrure porte avant droite", "state": { "false": "verrouillee", "true": "deverrouillee" } }, "doorlockstatusrearleft": { "name": "Serrure porte arriere gauche", "state": { "false": "verrouillee", "true": "deverrouillee" } }, "doorlockstatusrearright": { "name": "Serrure porte arriere droite", "state": { "false": "verrouillee", "true": "deverrouillee" } }, "doorlockstatusgas": { "name": "Serrure du reservoir", "state": { "false": "verrouillee", "true": "deverrouillee" } }, "enginehoodstatus": { "name": "Capot moteur", "state": { "false": "ferme", "true": "ouvert" } }, "doorstatusoverall": { "name": "Etat general des portes", "state": { "0": "ouvert", "1": "ferme", "2": "inexistant", "3": "inconnu" } }, "sunroofstatus": { "name": "Etat du toit ouvrant", "state": { "0": "ferme", "1": "ouvert", "2": "ouverture basculante", "3": "en mouvement", "4": "position anti-vibration", "5": "coulissement intermediaire", "6": "basculement intermediaire", "7": "en ouverture", "8": "en fermeture", "9": "basculement anti-vibration", "10": "position intermediaire", "11": "ouverture basculante", "12": "fermeture basculante" } } } }, "sunroofstatus": { "state": { "0": "Ferme", "1": "Ouvert", "2": "Ouverture basculante", "3": "En mouvement", "4": "Anti-vibration", "5": "Coulissement intermediaire", "6": "Basculement intermediaire", "7": "En ouverture", "8": "En fermeture", "9": "Basculement anti-vibration", "10": "Position intermediaire", "11": "Ouverture basculante", "12": "Fermeture basculante" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Vert", "1": "Jaune", "2": "Rouge" } }, "tirewarningsrdk": { "state": { "0": "Aucun avertissement", "1": "Avertissement leger", "2": "Pression basse", "3": "Degonflement" } }, "selectedchargeprogram": { "state": { "0": "Standard", "2": "Domicile", "3": "Travail", "4": "Non pris en charge" } } }, "switch": { "auxheat": { "name": "Chauffage auxiliaire" }, "precond": { "name": "Climatisation avant montee" } }, "button": { "btn_preheat_start_now": { "name": "Demarrer la preclimatisation" }, "btn_preheat_stop_now": { "name": "Arreter la preclimatisation" }, "btn_sigpos_start_now": { "name": "Appel de phares" } } }, "selector": { "charge_program": { "options": { "0": "Defaut", "2": "Domicile", "3": "Travail" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Non defini", "active": "Actif", "inactive": "Inactif" } }, "temperature_configure": { "options": { "0": "Basse", "30": "Haute" } } } } ================================================ FILE: custom_components/mbapi2020/translations/he.json ================================================ { "config": { "abort": { "already_configured": "הרכיב כבר מוגדר.", "reauth_successful": "האימות החוזר הצליח! הרכיב בתהליך טעינה." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "שגיאה לא מוכרת, בדוק את יומן המערכת לפרטים נוספים.", "2fa_required": "חשבונות עם אימות דו-שלבי (2FA) אינם נתמכים.", "legal_terms": "עליך לאשר את התנאים המשפטיים באתר מרצדס תחילה" }, "step": { "user": { "data": { "region": "אזור" }, "description": "בחר את האזור שלך.", "title": "הגדרת חיבור Mercedes ME 2020" }, "credentials": { "data": { "username": "שם משתמש MB (כתובת דוא\"ל)", "password": "סיסמה" }, "description": "הזן את פרטי החשבון שלך.", "title": "Mercedes ME 2020 - התחברות" }, "pin": { "data": { "password": "TAN (התקבל בדוא\"ל או SMS)" }, "description": "הזן את קוד ה-TAN שקיבלת בדוא\"ל או SMS כדי להשלים את האימות. אם לא קיבלת TAN, בדוק את תיבת הדוא\"ל שלך (כולל תיקיית ספאם) או את הודעות ה-SMS שלך.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "בצע הפעלה מחדש למערכת על מנת לסיים את עדכון האימות.", "title": "דרושה הפעלה מחדש" } } }, "title": "דרושה הפעלה מחדש" } }, "options": { "abort": { "already_configured": "הרכיב כבר מוגדר.", "reauth_successful": "האימות החוזר הצליח! הרכיב בתהליך טעינה." }, "step": { "init": { "data": { "cap_check_disabled": "בטל בדיקת תאימות", "enable_china_gcj_02": "הפעל תרגום GCJ-02 (סין בלבד)", "delete_auth_file": "מחק טוקן אימות עכשיו, מצריך הפעלה מחדש לאחר השמירה.", "excluded_cars": "מספרי VIN להתעלמות (מופרדים בפסיקים)", "pin": "PIN אבטחה (צריך ליצור באפליקציה)", "save_files": "ניפוי באגים בלבד: שמור הודעות שרת לתיקיית הודעות", "overwrite_cap_precondnow": "ניסיוני: דרוס יכולת precondnow (קבע כ-true)" }, "description": "הגדר את האפשרויות. חלק מהשינויים מצריכים הפעלה מחדש.", "title": "אפשרויות Mercedes ME 2020" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API זמין", "websocket_connection_state": "MB WS מצב", "cars_connected": "רכבים מחוברים", "version": "גרסה" } }, "services": { "refresh_access_token": { "name": "רענן טוקן גישה", "description": "רענן את טוקן הגישה ל-API" }, "auxheat_configure": { "name": "הגדרת חימום עזר", "description": "פקודה להגדרת חימום העזר. ניתן להגדיר שלושה זמנים ולבחור זמן פעיל אחד.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "time_selection": { "name": "בחירת זמן", "description": "זמן חימום עזר מוגדר מראש שהופעל (0=ללא בחירה, 1=time_1, 2=time_2, 3=time_3)" }, "time_1": { "name": "time_1", "description": "שעה ביום בדקות לאחר חצות. לדוגמה, ערך תקין עבור 8 בבוקר הוא 480. טווח ערכים הוא 0 עד 1439." }, "time_2": { "name": "time_2", "description": "שעה ביום בדקות לאחר חצות. לדוגמה, ערך תקין עבור 8 בבוקר הוא 480. טווח ערכים הוא 0 עד 1439." }, "time_3": { "name": "time_3", "description": "שעה ביום בדקות לאחר חצות. לדוגמה, ערך תקין עבור 8 בבוקר הוא 480. טווח ערכים הוא 0 עד 1439." } } }, "auxheat_start": { "name": "הפעלת חימום עזר", "description": "הפעל את חימום העזר של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "auxheat_stop": { "name": "כיבוי חימום עזר", "description": "כבה את חימום העזר של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "battery_max_soc_configure": { "name": "הגדרת מקסימום טעינת סוללה", "description": "הגדר את הערך המקסימלי למצב הטעינה של סוללת ה-HV של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "max_soc": { "name": "Max Soc", "description": "הערך המקסימלי למצב הטעינה של סוללת ה-HV (הערך צריך להיות בין 50 (חלק מהרכבים החדשים כמו CLA 2025 תומכים ב-30) ל-100 ומתחלק ב-10)" }, "charge_program": { "name": "תוכנית טעינה", "description": "(אופציונלי, ברירת מחדל=0) תוכנית טעינה לשינוי (0=ברירת מחדל, 2=בית, 3=עבודה) (לא בשימוש ב-CLA 2025)" } } }, "charge_program_configure": { "name": "הגדרת תוכנית טעינה", "description": "פקודה לבחירת תוכנית הטעינה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "charge_program": { "name": "תוכנית טעינה", "description": "תוכנית הטעינה המופעלת (0=ברירת מחדל, 2=בית, 3=עבודה)" }, "max_soc": { "name": "Max Soc", "description": "הערך המקסימלי למצב הטעינה של סוללת ה-HV (הערך צריך להיות בין 50 ל-100 ומתחלק ב-10)" } } }, "doors_unlock": { "name": "פתיחת דלתות", "description": "פתח דלתות רכב לפי מספר Vin. נדרשת הגדרת PIN. ראה דיאלוג אפשרויות האינטגרציה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "pin": { "name": "Pin", "description": "קוד PIN אבטחה, נדרש אם לא נשמר בהגדרות." } } }, "doors_lock": { "name": "נעילת דלתות", "description": "נעל דלתות רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "download_images": { "name": "הורדת תמונות", "description": "הורד את תמונות האפליקציה לתיקיית המשאבים של הרכיב עבור רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "engine_start": { "name": "הפעלת מנוע", "description": "הפעל את מנוע הרכב לפי מספר Vin. נדרשת הגדרת PIN. ראה דיאלוג אפשרויות האינטגרציה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "pin": { "name": "Pin", "description": "קוד PIN אבטחה, נדרש אם לא נשמר בהגדרות." } } }, "engine_stop": { "name": "כיבוי מנוע", "description": "כבה את מנוע הרכב לפי מספר Vin. נדרשת הגדרת PIN. ראה דיאלוג אפשרויות האינטגרציה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "hv_battery_start_conditioning": { "name": "הפעלת מיזוג סוללת HV", "description": "הפעל מיזוג סוללת HV של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "hv_battery_stop_conditioning": { "name": "כיבוי מיזוג סוללת HV", "description": "כבה מיזוג סוללת HV של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "preconditioning_configure_seats": { "name": "הגדרת מיזוג מושבים מראש", "description": "שלח פקודת הגדרת מיזוג מושבים מראש לרכב לפי מספר VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "front_left": { "name": "קדמי שמאלי", "description": "הפעל אם המושב הקדמי השמאלי צריך מיזוג מראש." }, "front_right": { "name": "קדמי ימני", "description": "הפעל אם המושב הקדמי הימני צריך מיזוג מראש." }, "rear_left": { "name": "אחורי שמאלי", "description": "הפעל אם המושב האחורי השמאלי צריך מיזוג מראש." }, "rear_right": { "name": "אחורי ימני", "description": "הפעל אם המושב האחורי הימני צריך מיזוג מראש." } } }, "preheat_start": { "name": "הפעלת מיזוג מראש", "description": "הפעל מיזוג מראש של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "type": { "name": "סוג", "description": "שיטת ההפעלה. 0=עכשיו (ברירת מחדל), 1=מיידי - השתמש במיידי אם הרכב שלך לא תומך בעכשיו." } } }, "preheat_start_departure_time": { "name": "הפעלת מיזוג מראש עם שעת יציאה", "description": "הפעל מיזוג מראש של רכב לפי מספר Vin ושעת יציאה נתונה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "time": { "name": "שעה", "description": "שעת יציאה בדקות לאחר חצות. לדוגמה, ערך תקין עבור 8 בבוקר הוא 480. טווח ערכים הוא 0 עד 1439." } } }, "preheat_stop": { "name": "כיבוי מיזוג מראש", "description": "כבה מיזוג מראש של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "preheat_stop_departure_time": { "name": "כיבוי מיזוג מראש מצב שעת יציאה", "description": "כבה את מיזוג מראש בשעת יציאה מתוזמנת של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "preconditioning_configure": { "name": "הגדרת שעת יציאה למיזוג מראש", "description": "הגדר מצב שעת יציאה למיזוג מראש. השתמש במצב 0 (מושבת) לביטול מיזוג מראש מתוזמן.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "departure_time_mode": { "name": "מצב שעת יציאה", "description": "0=מושבת, 1=יציאה חד-פעמית, 2=יציאה שבועית" }, "departure_time": { "name": "שעת יציאה", "description": "שעת יציאה בדקות לאחר חצות (0-1439). בשימוש רק כאשר מצב > 0." } } }, "sigpos_start": { "name": "הפעלת איתות מיקום", "description": "הפעל איתות אור של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "sunroof_open": { "name": "פתיחת גג שמש", "description": "פתח את גג השמש של רכב לפי מספר Vin. נדרשת הגדרת PIN. ראה דיאלוג אפשרויות האינטגרציה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "pin": { "name": "Pin", "description": "קוד PIN אבטחה, נדרש אם לא נשמר בהגדרות." } } }, "sunroof_tilt": { "name": "הטיית גג שמש", "description": "הטה את גג השמש של רכב לפי מספר Vin. נדרשת הגדרת PIN. ראה דיאלוג אפשרויות האינטגרציה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "pin": { "name": "Pin", "description": "קוד PIN אבטחה, נדרש אם לא נשמר בהגדרות." } } }, "sunroof_close": { "name": "סגירת גג שמש", "description": "סגור את גג השמש של רכב לפי מספר Vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "temperature_configure": { "name": "הגדרת טמפרטורת יעד (מיזוג מראש/חימום עזר)", "description": "הגדר את טמפרטורות היעד למיזוג מראש/חימום עזר עבור אזורים ברכב לפי מספר VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "front_left": { "name": "קדמי שמאלי", "description": "טמפרטורת יעד עבור האזור הקדמי השמאלי בצלזיוס." }, "front_right": { "name": "קדמי ימני", "description": "טמפרטורת יעד עבור האזור הקדמי הימני בצלזיוס." }, "rear_left": { "name": "אחורי שמאלי", "description": "טמפרטורת יעד עבור האזור האחורי השמאלי בצלזיוס. (אם זמין)" }, "rear_right": { "name": "אחורי ימני", "description": "טמפרטורת יעד עבור האזור האחורי הימני בצלזיוס. (אם זמין)" } } }, "windows_open": { "name": "פתיחת חלונות", "description": "פתח את חלונות הרכב לפי מספר Vin. נדרשת הגדרת PIN. ראה דיאלוג אפשרויות האינטגרציה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "pin": { "name": "Pin", "description": "קוד PIN אבטחה, נדרש אם לא נשמר בהגדרות." } } }, "windows_close": { "name": "סגירת חלונות", "description": "סגור את חלונות הרכב לפי מספר Vin. נדרשת הגדרת PIN. ראה דיאלוג אפשרויות האינטגרציה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" } } }, "windows_move": { "name": "הזזת חלונות", "description": "הזז את חלונות הרכב לפי מספר Vin למיקום חדש. נדרשת הגדרת PIN. ראה דיאלוג אפשרויות האינטגרציה.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "pin": { "name": "Pin", "description": "קוד PIN אבטחה, נדרש אם לא נשמר בהגדרות." }, "front_left": { "name": "קדמי שמאלי", "description": "המיקום החדש של החלון הקדמי השמאלי (0=סגור, 10=אוורור, 100=פתוח)" }, "front_right": { "name": "קדמי ימני", "description": "המיקום החדש של החלון הקדמי הימני (0=סגור, 10=אוורור, 100=פתוח)" }, "rear_left": { "name": "אחורי שמאלי", "description": "המיקום החדש של החלון האחורי השמאלי (0=סגור, 10=אוורור, 100=פתוח)" }, "rear_right": { "name": "אחורי ימני", "description": "המיקום החדש של החלון האחורי הימני (0=סגור, 10=אוורור, 100=פתוח)" } } }, "send_route": { "name": "שליחת מסלול", "description": "שלח מסלול לרכב. (מיקום בודד בלבד)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "title": { "name": "כותרת", "description": "כותרת המסלול" }, "latitude": { "name": "קו רוחב", "description": "קו הרוחב של המיקום" }, "longitude": { "name": "קו אורך", "description": "קו האורך של המיקום" }, "city": { "name": "עיר", "description": "שם העיר של המיקום" }, "postcode": { "name": "מיקוד", "description": "מיקוד המיקום" }, "street": { "name": "רחוב", "description": "שם הרחוב של המיקום" } } }, "charging_break_clocktimer_configure": { "name": "הגדרת טיימר הפסקת טעינה", "description": "הגדר הפסקות טעינה (AC בלבד). פעולה זו תדרוס את כל ההגדרות עבור כל החריצים ברכב שלך.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin של הרכב" }, "status_timer_1": { "name": "מצב (טיימר 1)", "description": "" }, "starttime_timer_1": { "name": "שעת התחלה (טיימר 1)", "description": "שעת התחלה של חלון הפסקת הטעינה (טיימר 1)" }, "stoptime_timer_1": { "name": "שעת סיום (טיימר 1)", "description": "שעת סיום של חלון הפסקת הטעינה (טיימר 1)" }, "status_timer_2": { "name": "מצב (טיימר 2)", "description": "" }, "starttime_timer_2": { "name": "שעת התחלה (טיימר 2)", "description": "שעת התחלה של חלון הפסקת הטעינה (טיימר 2)" }, "stoptime_timer_2": { "name": "שעת סיום (טיימר 2)", "description": "שעת סיום של חלון הפסקת הטעינה (טיימר 2)" }, "status_timer_3": { "name": "מצב (טיימר 3)", "description": "" }, "starttime_timer_3": { "name": "שעת התחלה (טיימר 3)", "description": "שעת התחלה של חלון הפסקת הטעינה (טיימר 3)" }, "stoptime_timer_3": { "name": "שעת סיום (טיימר 3)", "description": "שעת סיום של חלון הפסקת הטעינה (טיימר 3)" }, "status_timer_4": { "name": "מצב (טיימר 4)", "description": "" }, "starttime_timer_4": { "name": "שעת התחלה (טיימר 4)", "description": "שעת התחלה של חלון הפסקת הטעינה (טיימר 4)" }, "stoptime_timer_4": { "name": "שעת סיום (טיימר 4)", "description": "שעת סיום של חלון הפסקת הטעינה (טיימר 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "טעינה פעילה" } }, "sensor": { "chargingpowerecolimit": { "name": "מגבלת הספק טעינה" }, "auxheatstatus": { "state": { "0": "לא פעיל", "1": "חימום רגיל", "2": "אוורור רגיל", "3": "חימום ידני", "4": "חימום נוסף", "5": "אוורור נוסף", "6": "חימום אוטומטי" } }, "chargeflapacstatus": { "state": { "0": "פתוח", "1": "סגור", "2": "מכסה לחוץ", "3": "לא ידוע" } }, "chargeflapdcstatus": { "state": { "0": "פתוח", "1": "סגור", "2": "מכסה לחוץ", "3": "לא ידוע" } }, "chargingstatus": { "state": { "0": "טוען", "1": "הטעינה מסתיימת", "2": "הפסקת טעינה", "3": "לא מחובר", "4": "תקלה", "5": "טעינה איטית", "6": "טעינה מהירה", "7": "פורק", "8": "לא טוען", "9": "טעינה איטית לאחר הגעה ליעד נסיעה", "10": "טעינה לאחר הגעה ליעד נסיעה", "11": "טעינה מהירה לאחר הגעה ליעד נסיעה", "12": "מחובר", "13": "טעינת AC", "14": "טעינת DC", "15": "כיול סוללה פעיל", "16": "לא ידוע" } }, "departuretimemode": { "state": { "0": "מושבת", "1": "יומי", "2": "שבועי" } }, "ignitionstate": { "state": { "0": "נעול", "1": "כבוי", "2": "אביזרים", "4": "פועל", "5": "התנעה" } }, "interiorprotectionsensorstatus": { "state": { "0": "לא פעיל", "1": "לא פעיל", "2": "פעיל" }, "state_attributes": {} }, "lock": { "state": { "0": "לא נעול", "1": "נעול פנימית", "2": "נעול", "3": "נעול חלקית", "4": "לא ידוע" }, "state_attributes": { "decklidstatus": { "name": "מכסה תא מטען", "state": { "false": "סגור", "true": "פתוח" } }, "doorstatusfrontleft": { "name": "דלת קדמית שמאלית", "state": { "false": "סגור", "true": "פתוח" } }, "doorstatusfrontright": { "name": "דלת קדמית ימנית", "state": { "false": "סגור", "true": "פתוח" } }, "doorstatusrearleft": { "name": "דלת אחורית שמאלית", "state": { "false": "סגור", "true": "פתוח" } }, "doorstatusrearright": { "name": "דלת אחורית ימנית", "state": { "false": "סגור", "true": "פתוח" } }, "doorlockstatusfrontleft": { "name": "נעילת דלת קדמית שמאלית", "state": { "false": "נעול", "true": "לא נעול" } }, "doorlockstatusfrontright": { "name": "נעילת דלת קדמית ימנית", "state": { "false": "נעול", "true": "לא נעול" } }, "doorlockstatusrearleft": { "name": "נעילת דלת אחורית שמאלית", "state": { "false": "נעול", "true": "לא נעול" } }, "doorlockstatusrearright": { "name": "נעילת דלת אחורית ימנית", "state": { "false": "נעול", "true": "לא נעול" } }, "doorlockstatusgas": { "name": "נעילת פתח דלק", "state": { "false": "נעול", "true": "לא נעול" } }, "enginehoodstatus": { "name": "מכסה מנוע", "state": { "false": "סגור", "true": "פתוח" } }, "doorstatusoverall": { "name": "מצב דלתות כללי", "state": { "0": "פתוח", "1": "סגור", "2": "לא קיים", "3": "לא ידוע" } }, "sunroofstatus": { "name": "מצב גג שמש", "state": { "0": "סגור", "1": "פתוח", "2": "אוורור פתוח", "3": "בתנועה", "4": "מיקום נגד רעש", "5": "הזזה ביניים", "6": "הרמה ביניים", "7": "פותח", "8": "סוגר", "9": "הרמה נגד רעש", "10": "מיקום ביניים", "11": "פתיחה בהרמה", "12": "סגירה בהרמה" } } } }, "sunroofstatus": { "state": { "0": "סגור", "1": "פתוח", "2": "אוורור פתוח", "3": "בתנועה", "4": "נגד רעש", "5": "הזזה ביניים", "6": "הרמה ביניים", "7": "פותח", "8": "סוגר", "9": "הרמה נגד רעש", "10": "מיקום ביניים", "11": "פתיחה בהרמה", "12": "סגירה בהרמה" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "ירוק", "1": "צהוב", "2": "אדום" } }, "tirewarningsrdk": { "state": { "0": "ללא אזהרה", "1": "אזהרה קלה", "2": "לחץ נמוך", "3": "נקר" } }, "selectedchargeprogram": { "state": { "0": "רגיל", "2": "בית", "3": "עבודה", "4": "לא נתמך" } } }, "switch": { "auxheat": { "name": "חימום עזר" }, "precond": { "name": "מיזוג מראש" } }, "button": { "btn_preheat_start_now": { "name": "הפעלת מיזוג מראש" }, "btn_preheat_stop_now": { "name": "כיבוי מיזוג מראש" }, "btn_sigpos_start_now": { "name": "הבזקת אורות" } } }, "selector": { "charge_program": { "options": { "0": "ברירת מחדל", "2": "בית", "3": "עבודה" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "לא מוגדר", "active": "פעיל", "inactive": "לא פעיל" } }, "temperature_configure": { "options": { "0": "נמוך", "30": "גבוה" } } } } ================================================ FILE: custom_components/mbapi2020/translations/it.json ================================================ { "config": { "abort": { "already_configured": "Componente già configurato.", "reauth_successful": "Riautenticazione riuscita! Ricaricamento del componente in corso." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Errore sconosciuto. Controlla il registro di Home Assistant per ulteriori informazioni.", "2fa_required": "Gli account con autenticazione a due fattori (2FA) non sono supportati.", "legal_terms": "Devi prima accettare i termini legali sul sito web Mercedes" }, "step": { "user": { "data": { "region": "Regione" }, "description": "Seleziona la tua regione.", "title": "Configura la connessione Mercedes ME 2020" }, "credentials": { "data": { "username": "Nome utente MB (indirizzo email)", "password": "Password" }, "description": "Inserisci i dati del tuo account.", "title": "Mercedes ME 2020 - Accesso" }, "pin": { "data": { "password": "TAN (ricevuto via email o SMS)" }, "description": "Inserisci il TAN ricevuto via email o SMS per completare l'autenticazione. Se non hai ricevuto un TAN, controlla la tua casella email (e la cartella spam) o i tuoi messaggi SMS.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Il riavvio di Home Assistant è necessario per completare l'aggiornamento dell'autenticazione. Clicca su invia per riavviare ora.", "title": "Riavvio necessario" } } }, "title": "Riavvio necessario" } }, "options": { "abort": { "already_configured": "Componente già configurato.", "reauth_successful": "Riautenticazione riuscita! Ricaricamento del componente in corso." }, "step": { "init": { "data": { "cap_check_disabled": "Disabilita il controllo delle capacità", "enable_china_gcj_02": "Abilita traduzione GCJ-02 (solo Cina)", "delete_auth_file": "Elimina ora il token di autenticazione. Richiede il riavvio di Home Assistant dopo il salvataggio.", "excluded_cars": "VIN esclusi (separati da virgola)", "pin": "PIN di sicurezza (da creare nell'app mobile)", "save_files": "SOLO DEBUG: Abilita il salvataggio dei messaggi del server nella cartella messaggi", "overwrite_cap_precondnow": "Esp: Sovrascrivi capacità precondnow (imposta su true)" }, "description": "Configura le opzioni. Alcuni cambiamenti richiedono il riavvio di Home Assistant.", "title": "Mercedes ME 2020 - Opzioni" } } }, "system_health": { "info": { "api_endpoint_reachable": "API MB raggiungibile", "websocket_connection_state": "Stato WS MB", "cars_connected": "Auto connesse", "version": "Versione" } }, "services": { "refresh_access_token": { "name": "Aggiorna token di accesso", "description": "Aggiorna il token di accesso API" }, "auxheat_configure": { "name": "Configura riscaldamento ausiliario", "description": "Comando per configurare il riscaldamento ausiliario. È possibile definire tre orari e selezionare un orario attivo.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "time_selection": { "name": "Selezione orario", "description": "L'orario preimpostato attivato per il riscaldamento ausiliario (0=nessuna_selezione, 1=orario_1, 2=orario_2, 3=orario_3)" }, "time_1": { "name": "time_1", "description": "Orario in minuti dopo la mezzanotte. Es. il valore valido per le 8:00 sarebbe 480. L'intervallo va da 0 a 1439." }, "time_2": { "name": "time_2", "description": "Orario in minuti dopo la mezzanotte. Es. il valore valido per le 8:00 sarebbe 480. L'intervallo va da 0 a 1439." }, "time_3": { "name": "time_3", "description": "Orario in minuti dopo la mezzanotte. Es. il valore valido per le 8:00 sarebbe 480. L'intervallo va da 0 a 1439." } } }, "auxheat_start": { "name": "Avvia riscaldamento ausiliario", "description": "Avvia il riscaldamento ausiliario di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "auxheat_stop": { "name": "Arresta riscaldamento ausiliario", "description": "Arresta il riscaldamento ausiliario di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "battery_max_soc_configure": { "name": "Configura SOC massimo batteria", "description": "Configura il valore massimo per lo stato di carica della batteria HV di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "max_soc": { "name": "SOC massimo", "description": "Il valore massimo per lo stato di carica della batteria HV (il valore deve essere compreso tra 50 (alcune auto nuove come la CLA 2025 supportano 30) e 100 e divisibile per dieci)" }, "charge_program": { "name": "Programma di ricarica", "description": "(Opzionale, Predefinito=0) Programma di ricarica da modificare (0=Predefinito, 2=Casa, 3=Lavoro) (non utilizzato per la CLA 2025)" } } }, "charge_program_configure": { "name": "Configura programma di ricarica", "description": "Comando per selezionare il programma di ricarica.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "charge_program": { "name": "Programma di ricarica", "description": "Il programma di ricarica attivato (0=Predefinito, 2=Casa, 3=Lavoro)" }, "max_soc": { "name": "SOC massimo", "description": "Il valore massimo per lo stato di carica della batteria HV (il valore deve essere compreso tra 50 e 100 e divisibile per dieci)" } } }, "doors_unlock": { "name": "Sblocca portiere", "description": "Sblocca un'auto definita da un VIN. Configurazione PIN necessaria. Vedi la finestra opzioni dell'integrazione.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "pin": { "name": "Pin", "description": "PIN di sicurezza, necessario se non memorizzato nelle impostazioni." } } }, "doors_lock": { "name": "Blocca portiere", "description": "Blocca un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "download_images": { "name": "Scarica immagini", "description": "Scarica le immagini dell'app nella cartella risorse del componente per un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "engine_start": { "name": "Avvia motore", "description": "Avvia il motore di un'auto definita da un VIN. Configurazione PIN necessaria. Vedi la finestra opzioni dell'integrazione.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "pin": { "name": "Pin", "description": "PIN di sicurezza, necessario se non memorizzato nelle impostazioni." } } }, "engine_stop": { "name": "Arresta motore", "description": "Arresta il motore di un'auto definita da un VIN. Configurazione PIN necessaria. Vedi la finestra opzioni dell'integrazione.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "hv_battery_start_conditioning": { "name": "Avvia condizionamento batteria HV", "description": "Avvia il condizionamento della batteria HV di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "hv_battery_stop_conditioning": { "name": "Arresta condizionamento batteria HV", "description": "Arresta il condizionamento della batteria HV di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "preconditioning_configure_seats": { "name": "Configura precondizionamento sedili", "description": "Invia un comando di configurazione precondizionamento sedili a un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "front_left": { "name": "Anteriore sinistro", "description": "Attiva se il sedile anteriore sinistro deve essere precondizionato." }, "front_right": { "name": "Anteriore destro", "description": "Attiva se il sedile anteriore destro deve essere precondizionato." }, "rear_left": { "name": "Posteriore sinistro", "description": "Attiva se il sedile posteriore sinistro deve essere precondizionato." }, "rear_right": { "name": "Posteriore destro", "description": "Attiva se il sedile posteriore destro deve essere precondizionato." } } }, "preheat_start": { "name": "Avvia precondizionamento", "description": "Avvia il precondizionamento di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "type": { "name": "Tipo", "description": "Metodo utilizzato per avviare il processo. 0=Ora (Predefinito), 1=Immediato - Usa Immediato se la tua auto non supporta Ora." } } }, "preheat_start_departure_time": { "name": "Avvia precondizionamento con orario di partenza", "description": "Avvia il precondizionamento di un'auto definita da un VIN e un orario di partenza specificato.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "time": { "name": "Orario", "description": "Orario di partenza in minuti dopo la mezzanotte. Es. il valore valido per le 8:00 sarebbe 480. L'intervallo va da 0 a 1439." } } }, "preheat_stop": { "name": "Arresta precondizionamento", "description": "Arresta il precondizionamento di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "preheat_stop_departure_time": { "name": "Arresta precondizionamento modalità orario di partenza", "description": "Arresta il precondizionamento con orario di partenza configurato di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "preconditioning_configure": { "name": "Configura partenza precondizionamento", "description": "Configura la modalità orario di partenza del precondizionamento. Usa la modalità 0 (Disabilitato) per annullare il precondizionamento programmato.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "departure_time_mode": { "name": "Modalità orario di partenza", "description": "0=Disabilitato, 1=Partenza singola, 2=Partenza settimanale" }, "departure_time": { "name": "Orario di partenza", "description": "Orario di partenza in minuti dopo la mezzanotte (0-1439). Utilizzato solo quando la modalità > 0." } } }, "sigpos_start": { "name": "Avvia segnalazione posizione", "description": "Avvia la segnalazione luminosa di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "sunroof_open": { "name": "Apri tetto apribile", "description": "Apri il tetto apribile di un'auto definita da un VIN. Configurazione PIN necessaria. Vedi la finestra opzioni dell'integrazione.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "pin": { "name": "Pin", "description": "PIN di sicurezza, necessario se non memorizzato nelle impostazioni." } } }, "sunroof_tilt": { "name": "Inclina tetto apribile", "description": "Inclina il tetto apribile di un'auto definita da un VIN. Configurazione PIN necessaria. Vedi la finestra opzioni dell'integrazione.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "pin": { "name": "Pin", "description": "PIN di sicurezza, necessario se non memorizzato nelle impostazioni." } } }, "sunroof_close": { "name": "Chiudi tetto apribile", "description": "Chiudi il tetto apribile di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "temperature_configure": { "name": "Configura temperatura target (precond/auxheat)", "description": "Configura le temperature target di precondizionamento/riscaldamento ausiliario per le zone di un'auto definita da un VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "front_left": { "name": "Anteriore sinistro", "description": "Temperatura target per la zona anteriore sinistra in CELSIUS." }, "front_right": { "name": "Anteriore destro", "description": "Temperatura target per la zona anteriore destra in CELSIUS." }, "rear_left": { "name": "Posteriore sinistro", "description": "Temperatura target per la zona posteriore sinistra in CELSIUS. (se disponibile)" }, "rear_right": { "name": "Posteriore destro", "description": "Temperatura target per la zona posteriore destra in CELSIUS. (se disponibile)" } } }, "windows_open": { "name": "Apri finestrini", "description": "Apri i finestrini di un'auto definita da un VIN. Configurazione PIN necessaria. Vedi la finestra opzioni dell'integrazione.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "pin": { "name": "Pin", "description": "PIN di sicurezza, necessario se non memorizzato nelle impostazioni." } } }, "windows_close": { "name": "Chiudi finestrini", "description": "Chiudi i finestrini di un'auto definita da un VIN. Configurazione PIN necessaria. Vedi la finestra opzioni dell'integrazione.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" } } }, "windows_move": { "name": "Muovi finestrini", "description": "Muovi i finestrini di un'auto definita da un VIN in una nuova posizione. Configurazione PIN necessaria. Vedi la finestra opzioni dell'integrazione.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "pin": { "name": "Pin", "description": "PIN di sicurezza, necessario se non memorizzato nelle impostazioni." }, "front_left": { "name": "Anteriore sinistro", "description": "La nuova posizione del finestrino anteriore sinistro (0=chiuso, 10=ventilazione, 100=aperto)" }, "front_right": { "name": "Anteriore destro", "description": "La nuova posizione del finestrino anteriore destro (0=chiuso, 10=ventilazione, 100=aperto)" }, "rear_left": { "name": "Posteriore sinistro", "description": "La nuova posizione del finestrino posteriore sinistro (0=chiuso, 10=ventilazione, 100=aperto)" }, "rear_right": { "name": "Posteriore destro", "description": "La nuova posizione del finestrino posteriore destro (0=chiuso, 10=ventilazione, 100=aperto)" } } }, "send_route": { "name": "Invia percorso", "description": "Invia un percorso all'auto. (Solo posizione singola)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "title": { "name": "Titolo", "description": "Titolo del percorso" }, "latitude": { "name": "Latitudine", "description": "Latitudine della posizione" }, "longitude": { "name": "Longitudine", "description": "Longitudine della posizione" }, "city": { "name": "Città", "description": "Nome della città della posizione" }, "postcode": { "name": "Codice postale", "description": "Codice postale della posizione" }, "street": { "name": "Via", "description": "Nome della via della posizione" } } }, "charging_break_clocktimer_configure": { "name": "Configura timer pause di ricarica", "description": "Configura le pause di ricarica (solo AC). Questo sovrascriverà la configurazione completa per tutti gli slot nella tua auto.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin dell'auto" }, "status_timer_1": { "name": "Stato (Timer 1)", "description": "" }, "starttime_timer_1": { "name": "Orario di inizio (Timer 1)", "description": "Orario di inizio della finestra di pausa di ricarica (Timer 1)" }, "stoptime_timer_1": { "name": "Orario di fine (Timer 1)", "description": "Orario di fine della finestra di pausa di ricarica (Timer 1)" }, "status_timer_2": { "name": "Stato (Timer 2)", "description": "" }, "starttime_timer_2": { "name": "Orario di inizio (Timer 2)", "description": "Orario di inizio della finestra di pausa di ricarica (Timer 2)" }, "stoptime_timer_2": { "name": "Orario di fine (Timer 2)", "description": "Orario di fine della finestra di pausa di ricarica (Timer 2)" }, "status_timer_3": { "name": "Stato (Timer 3)", "description": "" }, "starttime_timer_3": { "name": "Orario di inizio (Timer 3)", "description": "Orario di inizio della finestra di pausa di ricarica (Timer 3)" }, "stoptime_timer_3": { "name": "Orario di fine (Timer 3)", "description": "Orario di fine della finestra di pausa di ricarica (Timer 3)" }, "status_timer_4": { "name": "Stato (Timer 4)", "description": "" }, "starttime_timer_4": { "name": "Orario di inizio (Timer 4)", "description": "Orario di inizio della finestra di pausa di ricarica (Timer 4)" }, "stoptime_timer_4": { "name": "Orario di fine (Timer 4)", "description": "Orario di fine della finestra di pausa di ricarica (Timer 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Ricarica attiva" } }, "sensor": { "chargingpowerecolimit": { "name": "Limite potenza di ricarica" }, "auxheatstatus": { "state": { "0": "Inattivo", "1": "Riscaldamento normale", "2": "Ventilazione normale", "3": "Riscaldamento manuale", "4": "Post riscaldamento", "5": "Post ventilazione", "6": "Riscaldamento automatico" } }, "chargeflapacstatus": { "state": { "0": "Aperto", "1": "Chiuso", "2": "Sportellino premuto", "3": "Sconosciuto" } }, "chargeflapdcstatus": { "state": { "0": "Aperto", "1": "Chiuso", "2": "Sportellino premuto", "3": "Sconosciuto" } }, "chargingstatus": { "state": { "0": "In ricarica", "1": "Ricarica in completamento", "2": "Pausa di ricarica", "3": "Scollegato", "4": "Errore", "5": "Lenta", "6": "Veloce", "7": "In scarica", "8": "Non in ricarica", "9": "Ricarica lenta dopo raggiungimento obiettivo viaggio", "10": "In ricarica dopo raggiungimento obiettivo viaggio", "11": "Ricarica veloce dopo raggiungimento obiettivo viaggio", "12": "Collegato", "13": "Ricarica AC", "14": "Ricarica DC", "15": "Calibrazione batteria attiva", "16": "Sconosciuto" } }, "departuretimemode": { "state": { "0": "Disabilitato", "1": "Giornaliero", "2": "Settimanale" } }, "ignitionstate": { "state": { "0": "Bloccato", "1": "Spento", "2": "Accessorio", "4": "Acceso", "5": "Avviamento" } }, "interiorprotectionsensorstatus": { "state": { "0": "Non attivo", "1": "Non attivo", "2": "Attivo" }, "state_attributes": {} }, "lock": { "state": { "0": "Sbloccato", "1": "Bloccato internamente", "2": "Bloccato", "3": "Parzialmente sbloccato", "4": "Sconosciuto" }, "state_attributes": { "decklidstatus": { "name": "Cofano posteriore", "state": { "false": "chiuso", "true": "aperto" } }, "doorstatusfrontleft": { "name": "Portiera anteriore sinistra", "state": { "false": "chiusa", "true": "aperta" } }, "doorstatusfrontright": { "name": "Portiera anteriore destra", "state": { "false": "chiusa", "true": "aperta" } }, "doorstatusrearleft": { "name": "Portiera posteriore sinistra", "state": { "false": "chiusa", "true": "aperta" } }, "doorstatusrearright": { "name": "Portiera posteriore destra", "state": { "false": "chiusa", "true": "aperta" } }, "doorlockstatusfrontleft": { "name": "Serratura anteriore sinistra", "state": { "false": "bloccata", "true": "sbloccata" } }, "doorlockstatusfrontright": { "name": "Serratura anteriore destra", "state": { "false": "bloccata", "true": "sbloccata" } }, "doorlockstatusrearleft": { "name": "Serratura posteriore sinistra", "state": { "false": "bloccata", "true": "sbloccata" } }, "doorlockstatusrearright": { "name": "Serratura posteriore destra", "state": { "false": "bloccata", "true": "sbloccata" } }, "doorlockstatusgas": { "name": "Serratura serbatoio", "state": { "false": "bloccata", "true": "sbloccata" } }, "enginehoodstatus": { "name": "Cofano motore", "state": { "false": "chiuso", "true": "aperto" } }, "doorstatusoverall": { "name": "Stato generale portiere", "state": { "0": "aperto", "1": "chiuso", "2": "non esistente", "3": "sconosciuto" } }, "sunroofstatus": { "name": "Stato tetto apribile", "state": { "0": "chiuso", "1": "aperto", "2": "sollevamento aperto", "3": "in movimento", "4": "posizione anti-vibrazione", "5": "scorrimento intermedio", "6": "sollevamento intermedio", "7": "in apertura", "8": "in chiusura", "9": "sollevamento anti-vibrazione", "10": "posizione intermedia", "11": "apertura in sollevamento", "12": "chiusura in sollevamento" } } } }, "sunroofstatus": { "state": { "0": "Chiuso", "1": "Aperto", "2": "Sollevamento aperto", "3": "In movimento", "4": "Anti vibrazione", "5": "Scorrimento intermedio", "6": "Sollevamento intermedio", "7": "In apertura", "8": "In chiusura", "9": "Sollevamento anti vibrazione", "10": "Posizione intermedia", "11": "Apertura in sollevamento", "12": "Chiusura in sollevamento" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Verde", "1": "Giallo", "2": "Rosso" } }, "tirewarningsrdk": { "state": { "0": "Nessun avviso", "1": "Avviso leggero", "2": "Pressione bassa", "3": "Sgonfiamento" } }, "selectedchargeprogram": { "state": { "0": "Standard", "2": "Casa", "3": "Lavoro", "4": "Non supportato" } } }, "switch": { "auxheat": { "name": "Riscaldamento ausiliario" }, "precond": { "name": "Climatizzazione pre-ingresso" } }, "button": { "btn_preheat_start_now": { "name": "Avvia preclimatizzazione" }, "btn_preheat_stop_now": { "name": "Arresta preclimatizzazione" }, "btn_sigpos_start_now": { "name": "Lampeggia luci" } } }, "selector": { "charge_program": { "options": { "0": "Predefinito", "2": "Casa", "3": "Lavoro" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Non impostato", "active": "Attivo", "inactive": "Inattivo" } }, "temperature_configure": { "options": { "0": "Bassa", "30": "Alta" } } } } ================================================ FILE: custom_components/mbapi2020/translations/nb_NO.json ================================================ { "config": { "abort": { "already_configured": "Komponenten er allerede konfigurert.", "reauth_successful": "Ny autentisering vellykket! Komponent lastes inn på nytt." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Ukjent feil. Sjekk Home Assistant-loggen for mer informasjon.", "2fa_required": "Kontoer med tofaktorautentisering (2FA) støttes ikke.", "legal_terms": "Du må godta de juridiske vilkårene på Mercedes-nettsiden først" }, "step": { "user": { "data": { "region": "Region" }, "description": "Velg din region.", "title": "Sett opp Mercedes ME 2020-tilkoblingen" }, "credentials": { "data": { "username": "MB brukernavn (e-postadresse)", "password": "Passord" }, "description": "Skriv inn kontoinformasjonen din.", "title": "Mercedes ME 2020 - Innlogging" }, "pin": { "data": { "password": "TAN (mottatt via e-post eller SMS)" }, "description": "Skriv inn TAN-koden du har mottatt via e-post eller SMS for å fullføre autentiseringen. Hvis du ikke har mottatt en TAN, sjekk innboksen din (og søppelpostmappen) eller SMS-meldingene dine.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Omstart av Home Assistant er nødvendig for å fullføre autentiseringsoppdateringen. Klikk send for å starte på nytt nå.", "title": "Omstart påkrevd" } } }, "title": "Omstart påkrevd" } }, "options": { "abort": { "already_configured": "Komponenten er allerede konfigurert.", "reauth_successful": "Ny autentisering vellykket! Komponent lastes inn på nytt." }, "step": { "init": { "data": { "cap_check_disabled": "Deaktiver funksjonssjekk", "enable_china_gcj_02": "Aktiver GCJ-02-oversettelse (kun Kina)", "delete_auth_file": "Slett autentiseringstoken nå. Krever omstart av Home Assistant etter lagring.", "excluded_cars": "Ekskluderte VIN-numre (kommaseparert)", "pin": "Sikkerhets-PIN (opprettes i mobilappen)", "save_files": "KUN FEILSØKING: Aktiver lagring av servermeldinger til meldingsmappen", "overwrite_cap_precondnow": "Eksp: Overskriv funksjon precondnow (sett til sann)" }, "description": "Konfigurer alternativene dine. Noen endringer krever omstart av Home Assistant.", "title": "Mercedes ME 2020-alternativer" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API tilgjengelig", "websocket_connection_state": "MB WS-tilstand", "cars_connected": "Tilkoblede biler", "version": "Versjon" } }, "services": { "refresh_access_token": { "name": "Oppdater tilgangstoken", "description": "Oppdater API-tilgangstokenet" }, "auxheat_configure": { "name": "Konfigurer tilleggsvarme", "description": "Kommando for å konfigurere tilleggsvarmen. Det er mulig å definere tre tidspunkter og velge ett aktivt tidspunkt.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "time_selection": { "name": "Tidsvalg", "description": "Det aktiverte forhåndsinnstilte tidspunktet for tilleggsvarme (0=ingen_valg, 1=tid_1, 2=tid_2, 3=tid_3)" }, "time_1": { "name": "time_1", "description": "Tidspunkt i minutter etter midnatt. F.eks. er 480 en gyldig verdi for kl. 08.00. Verdiområdet er 0 til 1439." }, "time_2": { "name": "time_2", "description": "Tidspunkt i minutter etter midnatt. F.eks. er 480 en gyldig verdi for kl. 08.00. Verdiområdet er 0 til 1439." }, "time_3": { "name": "time_3", "description": "Tidspunkt i minutter etter midnatt. F.eks. er 480 en gyldig verdi for kl. 08.00. Verdiområdet er 0 til 1439." } } }, "auxheat_start": { "name": "Start tilleggsvarme", "description": "Start tilleggsvarmen for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "auxheat_stop": { "name": "Stopp tilleggsvarme", "description": "Stopp tilleggsvarmen for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "battery_max_soc_configure": { "name": "Konfigurer maks ladenivå for batteri", "description": "Konfigurer maksimalverdien for ladenivå (SoC) til høyspentbatteriet for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "max_soc": { "name": "Maks ladenivå", "description": "Maksimalverdien for høyspentbatteriets ladenivå (verdien må være mellom 50 (noen nye biler som 2025 CLA støtter 30) og 100 og delelig med ti)" }, "charge_program": { "name": "Ladeprogram", "description": "(Valgfritt, Standard=0) Ladeprogram som skal endres (0=Standard, 2=Hjem, 3=Jobb) (brukes ikke for 2025 CLA)" } } }, "charge_program_configure": { "name": "Konfigurer ladeprogram", "description": "Kommando for å velge ladeprogram.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "charge_program": { "name": "Ladeprogram", "description": "Det aktiverte ladeprogrammet (0=Standard, 2=Hjem, 3=Jobb)" }, "max_soc": { "name": "Maks ladenivå", "description": "Maksimalverdien for høyspentbatteriets ladenivå (verdien må være mellom 50 og 100 og delelig med ti)" } } }, "doors_unlock": { "name": "Lås opp dører", "description": "Lås opp en bil definert av et VIN-nummer. PIN-oppsett påkrevd. Se alternativdialogen for integrasjonen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhetskode, påkrevd hvis den ikke er lagret i innstillingene." } } }, "doors_lock": { "name": "Lås dører", "description": "Lås en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "download_images": { "name": "Last ned bilder", "description": "Laster ned app-bilder til komponentens ressursmappe for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "engine_start": { "name": "Start motor", "description": "Start motoren på en bil definert av et VIN-nummer. PIN-oppsett påkrevd. Se alternativdialogen for integrasjonen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhetskode, påkrevd hvis den ikke er lagret i innstillingene." } } }, "engine_stop": { "name": "Stopp motor", "description": "Stopp motoren på en bil definert av et VIN-nummer. PIN-oppsett påkrevd. Se alternativdialogen for integrasjonen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "hv_battery_start_conditioning": { "name": "Start kondisjonering av høyspentbatteri", "description": "Start kondisjoneringen av høyspentbatteriet for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "hv_battery_stop_conditioning": { "name": "Stopp kondisjonering av høyspentbatteri", "description": "Stopp kondisjoneringen av høyspentbatteriet for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preconditioning_configure_seats": { "name": "Konfigurer seter for forklimatisering", "description": "Send en konfigureringskommando for seteklimatisering til en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "front_left": { "name": "Venstre foran", "description": "Aktiver hvis venstre forsete skal forklimatiseres." }, "front_right": { "name": "Høyre foran", "description": "Aktiver hvis høyre forsete skal forklimatiseres." }, "rear_left": { "name": "Venstre bak", "description": "Aktiver hvis venstre baksete skal forklimatiseres." }, "rear_right": { "name": "Høyre bak", "description": "Aktiver hvis høyre baksete skal forklimatiseres." } } }, "preheat_start": { "name": "Start forklimatisering", "description": "Start forklimatiseringen for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "type": { "name": "Type", "description": "Metode som brukes for å starte prosessen. 0=Nå (Standard), 1=Umiddelbart - Bruk Umiddelbart hvis bilen din ikke støtter Nå." } } }, "preheat_start_departure_time": { "name": "Start forklimatisering med avreisetid", "description": "Start forklimatiseringen for en bil definert av et VIN-nummer og en angitt avreisetid.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "time": { "name": "Tid", "description": "Avreisetid i minutter etter midnatt. F.eks. er 480 en gyldig verdi for kl. 08.00. Verdiområdet er 0 til 1439." } } }, "preheat_stop": { "name": "Stopp forklimatisering", "description": "Stopp forklimatiseringen for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preheat_stop_departure_time": { "name": "Stopp forklimatisering for avreisetid", "description": "Stopp den konfigurerte forklimatiseringen for avreisetid for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preconditioning_configure": { "name": "Konfigurer forklimatisering for avreise", "description": "Konfigurer modus for forklimatisering ved avreise. Bruk modus 0 (Deaktivert) for å avbryte planlagt forklimatisering ved avreise.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "departure_time_mode": { "name": "Avreisetidsmodus", "description": "0=Deaktivert, 1=Enkeltavreise, 2=Ukentlig avreise" }, "departure_time": { "name": "Avreisetid", "description": "Avreisetid i minutter etter midnatt (0-1439). Brukes kun når modus > 0." } } }, "sigpos_start": { "name": "Start signalposisjon", "description": "Start lyssignalering for en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "sunroof_open": { "name": "Åpne soltak", "description": "Åpne soltaket på en bil definert av et VIN-nummer. PIN-oppsett påkrevd. Se alternativdialogen for integrasjonen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhetskode, påkrevd hvis den ikke er lagret i innstillingene." } } }, "sunroof_tilt": { "name": "Vipp soltak", "description": "Vipp soltaket på en bil definert av et VIN-nummer. PIN-oppsett påkrevd. Se alternativdialogen for integrasjonen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhetskode, påkrevd hvis den ikke er lagret i innstillingene." } } }, "sunroof_close": { "name": "Lukk soltak", "description": "Lukk soltaket på en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "temperature_configure": { "name": "Konfigurer måltemperatur (forklimatisering/tilleggsvarme)", "description": "Konfigurer måltemperaturer for forklimatisering/tilleggsvarme for soner i en bil definert av et VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "front_left": { "name": "Venstre foran", "description": "Måltemperatur for sonen venstre foran i CELSIUS." }, "front_right": { "name": "Høyre foran", "description": "Måltemperatur for sonen høyre foran i CELSIUS." }, "rear_left": { "name": "Venstre bak", "description": "Måltemperatur for sonen venstre bak i CELSIUS. (hvis tilgjengelig)" }, "rear_right": { "name": "Høyre bak", "description": "Måltemperatur for sonen høyre bak i CELSIUS. (hvis tilgjengelig)" } } }, "windows_open": { "name": "Åpne vinduer", "description": "Åpne vinduene på en bil definert av et VIN-nummer. PIN-oppsett påkrevd. Se alternativdialogen for integrasjonen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhetskode, påkrevd hvis den ikke er lagret i innstillingene." } } }, "windows_close": { "name": "Lukk vinduer", "description": "Lukk vinduene på en bil definert av et VIN-nummer. PIN-oppsett påkrevd. Se alternativdialogen for integrasjonen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "windows_move": { "name": "Flytt vinduer", "description": "Flytt vinduene på en bil definert av et VIN-nummer til en ny posisjon. PIN-oppsett påkrevd. Se alternativdialogen for integrasjonen.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kode", "description": "Sikkerhetskode, påkrevd hvis den ikke er lagret i innstillingene." }, "front_left": { "name": "Venstre foran", "description": "Den nye posisjonen til venstre frontvindu (0=lukket, 10=ventilering, 100=åpent)" }, "front_right": { "name": "Høyre foran", "description": "Den nye posisjonen til høyre frontvindu (0=lukket, 10=ventilering, 100=åpent)" }, "rear_left": { "name": "Venstre bak", "description": "Den nye posisjonen til venstre bakvindu (0=lukket, 10=ventilering, 100=åpent)" }, "rear_right": { "name": "Høyre bak", "description": "Den nye posisjonen til høyre bakvindu (0=lukket, 10=ventilering, 100=åpent)" } } }, "send_route": { "name": "Send rute", "description": "Sender en rute til bilen. (Kun enkelt lokasjon)", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "title": { "name": "Tittel", "description": "Rutens tittel" }, "latitude": { "name": "Breddegrad", "description": "Lokasjonens breddegrad" }, "longitude": { "name": "Lengdegrad", "description": "Lokasjonens lengdegrad" }, "city": { "name": "By", "description": "Lokasjonens bynavn" }, "postcode": { "name": "Postnummer", "description": "Lokasjonens postnummer" }, "street": { "name": "Gate", "description": "Lokasjonens gatenavn" } } }, "charging_break_clocktimer_configure": { "name": "Konfigurer tidtaker for ladepause", "description": "Konfigurer ladepauser (kun AC). Dette vil overskrive hele konfigurasjonen for alle plasser i bilen din.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "status_timer_1": { "name": "Status (Tidtaker 1)", "description": "" }, "starttime_timer_1": { "name": "Starttid (Tidtaker 1)", "description": "Starttid for ladepausevinduet (Tidtaker 1)" }, "stoptime_timer_1": { "name": "Sluttid (Tidtaker 1)", "description": "Sluttid for ladepausevinduet (Tidtaker 1)" }, "status_timer_2": { "name": "Status (Tidtaker 2)", "description": "" }, "starttime_timer_2": { "name": "Starttid (Tidtaker 2)", "description": "Starttid for ladepausevinduet (Tidtaker 2)" }, "stoptime_timer_2": { "name": "Sluttid (Tidtaker 2)", "description": "Sluttid for ladepausevinduet (Tidtaker 2)" }, "status_timer_3": { "name": "Status (Tidtaker 3)", "description": "" }, "starttime_timer_3": { "name": "Starttid (Tidtaker 3)", "description": "Starttid for ladepausevinduet (Tidtaker 3)" }, "stoptime_timer_3": { "name": "Sluttid (Tidtaker 3)", "description": "Sluttid for ladepausevinduet (Tidtaker 3)" }, "status_timer_4": { "name": "Status (Tidtaker 4)", "description": "" }, "starttime_timer_4": { "name": "Starttid (Tidtaker 4)", "description": "Starttid for ladepausevinduet (Tidtaker 4)" }, "stoptime_timer_4": { "name": "Sluttid (Tidtaker 4)", "description": "Sluttid for ladepausevinduet (Tidtaker 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Lading aktiv" } }, "sensor": { "chargingpowerecolimit": { "name": "Ladeeffektgrense" }, "auxheatstatus": { "state": { "0": "Inaktiv", "1": "Normal oppvarming", "2": "Normal ventilasjon", "3": "Manuell oppvarming", "4": "Ettervarming", "5": "Etterventilasjon", "6": "Automatisk oppvarming" } }, "chargeflapacstatus": { "state": { "0": "Åpen", "1": "Lukket", "2": "Luke trykket inn", "3": "Ukjent" } }, "chargeflapdcstatus": { "state": { "0": "Åpen", "1": "Lukket", "2": "Luke trykket inn", "3": "Ukjent" } }, "chargingstatus": { "state": { "0": "lader", "1": "lading avsluttes", "2": "Ladepause", "3": "frakoblet", "4": "feil", "5": "langsom", "6": "rask", "7": "lader ut", "8": "lader ikke", "9": "langsom lading etter å ha nådd reisemål", "10": "lading etter å ha nådd reisemål", "11": "rask lading etter å ha nådd reisemål", "12": "Tilkoblet", "13": "AC-lading", "14": "DC-lading", "15": "Batterikalibrering aktiv", "16": "ukjent" } }, "departuretimemode": { "state": { "0": "Deaktivert", "1": "Daglig", "2": "Ukentlig" } }, "ignitionstate": { "state": { "0": "Låst", "1": "Av", "2": "Tilbehør", "4": "På", "5": "Start" } }, "interiorprotectionsensorstatus": { "state": { "0": "Ikke aktiv", "1": "Ikke aktiv", "2": "Aktiv" }, "state_attributes": {} }, "lock": { "state": { "0": "Ulåst", "1": "Låst internt", "2": "Låst", "3": "Delvis ulåst", "4": "Ukjent" }, "state_attributes": { "decklidstatus": { "name": "Bagasjelokk", "state": { "false": "lukket", "true": "åpen" } }, "doorstatusfrontleft": { "name": "Dør venstre foran", "state": { "false": "lukket", "true": "åpen" } }, "doorstatusfrontright": { "name": "Dør høyre foran", "state": { "false": "lukket", "true": "åpen" } }, "doorstatusrearleft": { "name": "Dør venstre bak", "state": { "false": "lukket", "true": "åpen" } }, "doorstatusrearright": { "name": "Dør høyre bak", "state": { "false": "lukket", "true": "åpen" } }, "doorlockstatusfrontleft": { "name": "Dørlås venstre foran", "state": { "false": "låst", "true": "ulåst" } }, "doorlockstatusfrontright": { "name": "Dørlås høyre foran", "state": { "false": "låst", "true": "ulåst" } }, "doorlockstatusrearleft": { "name": "Dørlås venstre bak", "state": { "false": "låst", "true": "ulåst" } }, "doorlockstatusrearright": { "name": "Dørlås høyre bak", "state": { "false": "låst", "true": "ulåst" } }, "doorlockstatusgas": { "name": "Tanklokk", "state": { "false": "låst", "true": "ulåst" } }, "enginehoodstatus": { "name": "Motorpanser", "state": { "false": "lukket", "true": "åpen" } }, "doorstatusoverall": { "name": "Samlet dørstatus", "state": { "0": "åpen", "1": "lukket", "2": "finnes ikke", "3": "ukjent" } }, "sunroofstatus": { "name": "Soltakstatus", "state": { "0": "lukket", "1": "åpen", "2": "vipp åpen", "3": "i bevegelse", "4": "vindavvisende posisjon", "5": "mellomposisjon glidende", "6": "mellomposisjon vipp", "7": "åpner", "8": "lukker", "9": "vindavvisende vipp", "10": "mellomposisjon", "11": "åpner vipp", "12": "lukker vipp" } } } }, "sunroofstatus": { "state": { "0": "Lukket", "1": "Åpen", "2": "Vipp åpen", "3": "I bevegelse", "4": "Vindavvisende posisjon", "5": "Mellomposisjon glidende", "6": "Mellomposisjon vipp", "7": "Åpner", "8": "Lukker", "9": "Vindavvisende vipp", "10": "Mellomposisjon", "11": "Åpner vipp", "12": "Lukker vipp" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Grønn", "1": "Gul", "2": "Rød" } }, "tirewarningsrdk": { "state": { "0": "Ingen advarsel", "1": "Myk advarsel", "2": "Lavt trykk", "3": "Punktering" } }, "selectedchargeprogram": { "state": { "0": "Standard", "2": "Hjem", "3": "Jobb", "4": "Støttes ikke" } } }, "switch": { "auxheat": { "name": "Tilleggsvarme" }, "precond": { "name": "Forklimatisering" } }, "button": { "btn_preheat_start_now": { "name": "Start forklimatisering" }, "btn_preheat_stop_now": { "name": "Stopp forklimatisering" }, "btn_sigpos_start_now": { "name": "Blink med lysene" } } }, "selector": { "charge_program": { "options": { "0": "Standard", "2": "Hjem", "3": "Jobb" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Ikke satt", "active": "Aktiv", "inactive": "Inaktiv" } }, "temperature_configure": { "options": { "0": "Lav", "30": "Høy" } } } } ================================================ FILE: custom_components/mbapi2020/translations/nl.json ================================================ { "config": { "abort": { "already_configured": "Component is al geconfigureerd.", "reauth_successful": "Herautorisatie succesvol! Component wordt opnieuw geladen." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Onbekende fout. Controleer de Home Assistant-log voor meer informatie.", "2fa_required": "Tweefactorauthenticatie (2FA) accounts worden niet ondersteund.", "legal_terms": "Je moet eerst de juridische voorwaarden op de Mercedes-website accepteren" }, "step": { "user": { "data": { "region": "Regio" }, "description": "Selecteer je regio.", "title": "Mercedes ME 2020 verbinding instellen" }, "credentials": { "data": { "username": "MB gebruikersnaam (e-mailadres)", "password": "Wachtwoord" }, "description": "Voer je accountgegevens in.", "title": "Mercedes ME 2020 - Inloggen" }, "pin": { "data": { "password": "TAN (ontvangen via e-mail of sms)" }, "description": "Voer de TAN in die je via e-mail of sms hebt ontvangen om de authenticatie te voltooien. Als je geen TAN hebt ontvangen, controleer dan je e-mailinbox (en spammap) of je sms-berichten.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Een herstart van Home Assistant is vereist om de autorisatie-update te voltooien. Klik op verzenden om nu opnieuw op te starten.", "title": "Herstart vereist" } } }, "title": "Herstart vereist" } }, "options": { "abort": { "already_configured": "Component is al geconfigureerd.", "reauth_successful": "Herautorisatie succesvol! Component wordt opnieuw geladen." }, "step": { "init": { "data": { "cap_check_disabled": "Schakel functiecontrole uit", "enable_china_gcj_02": "Schakel GCJ-02-vertaling in (alleen China)", "delete_auth_file": "Verwijder authenticatietoken nu. Vereist een herstart van Home Assistant na opslaan.", "excluded_cars": "Uitgesloten chassisnummers (komma-gescheiden)", "pin": "PIN-code (aan te maken in de mobiele app)", "save_files": "ALLEEN DEBUG: Schakel het opslaan van serverberichten in de berichtenmap in", "overwrite_cap_precondnow": "Exp: Overschrijf capability precondnow (zet op true)" }, "description": "Configureer je opties. Sommige wijzigingen vereisen een herstart van Home Assistant.", "title": "Mercedes ME 2020-opties" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API bereikbaar", "websocket_connection_state": "MB WS-status", "cars_connected": "Verbonden auto's", "version": "Versie" } }, "services": { "refresh_access_token": { "name": "Toegangstoken vernieuwen", "description": "Vernieuw het API-toegangstoken" }, "auxheat_configure": { "name": "Hulpverwarming configureren", "description": "Commando voor het configureren van de hulpverwarming. Het is mogelijk om drie dagtijden in te stellen en één actieve tijd te selecteren.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "time_selection": { "name": "Tijdselectie", "description": "De geactiveerde vooraf ingestelde tijd voor de extra verwarming (0=geen_selectie, 1=tijd_1, 2=tijd_2, 3=tijd_3)" }, "time_1": { "name": "tijd_1", "description": "Tijd in minuten na middernacht. Bijvoorbeeld: een geldige waarde voor 8 uur 's ochtends is 480. Waardenbereik is 0 tot 1439." }, "time_2": { "name": "tijd_2", "description": "Tijd in minuten na middernacht. Bijvoorbeeld: een geldige waarde voor 8 uur 's ochtends is 480. Waardenbereik is 0 tot 1439." }, "time_3": { "name": "tijd_3", "description": "Tijd in minuten na middernacht. Bijvoorbeeld: een geldige waarde voor 8 uur 's ochtends is 480. Waardenbereik is 0 tot 1439." } } }, "auxheat_start": { "name": "Hulpverwarming starten", "description": "Start de hulpverwarming van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "auxheat_stop": { "name": "Hulpverwarming stoppen", "description": "Stop de hulpverwarming van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "battery_max_soc_configure": { "name": "Maximale batterijladingswaarde configureren", "description": "Configureer de maximale waarde voor de laadstatus van de HV-batterij van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "max_soc": { "name": "Maximale lading", "description": "De maximale waarde voor de laadstatus van de HV-batterij (waarde moet tussen 50 (sommige nieuwe auto's zoals 2025 CLA ondersteunen 30) en 100 liggen en deelbaar zijn door tien)" }, "charge_program": { "name": "Laadprogramma", "description": "(Optioneel, standaard=0) Het laadprogramma om te wijzigen (0=Standaard, 2=Thuis, 3=Werk) (niet gebruikt voor 2025 CLA)" } } }, "charge_program_configure": { "name": "Laadprogramma configureren", "description": "Commando om het laadprogramma te selecteren.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "charge_program": { "name": "Laadprogramma", "description": "Het geactiveerde laadprogramma (0=Standaard, 2=Thuis, 3=Werk)" }, "max_soc": { "name": "Maximale lading", "description": "De maximale waarde voor de laadstatus van de HV-batterij (waarde moet tussen 50 en 100 liggen en deelbaar zijn door tien)" } } }, "doors_unlock": { "name": "Deuren ontgrendelen", "description": "Ontgrendel een auto die wordt gedefinieerd door een VIN. PIN-instelling vereist. Zie de optiedialoog van de integratie.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "pin": { "name": "Pin", "description": "PIN-code, vereist als deze niet is opgeslagen in de instellingen." } } }, "doors_lock": { "name": "Deuren vergrendelen", "description": "Vergrendel een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "download_images": { "name": "Afbeeldingen downloaden", "description": "Download de app-afbeeldingen naar de resource-map van de componenten voor een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "engine_start": { "name": "Motor starten", "description": "Start de motor van een auto die wordt gedefinieerd door een VIN. PIN-instelling vereist. Zie de optiedialoog van de integratie.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "pin": { "name": "Pin", "description": "PIN-code, vereist als deze niet is opgeslagen in de instellingen." } } }, "engine_stop": { "name": "Motor stoppen", "description": "Stop de motor van een auto die wordt gedefinieerd door een VIN. PIN-instelling vereist. Zie de optiedialoog van de integratie.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "hv_battery_start_conditioning": { "name": "HV-batterij conditionering starten", "description": "Start de HV-batterijconditionering van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "hv_battery_stop_conditioning": { "name": "HV-batterij conditionering stoppen", "description": "Stop de HV-batterijconditionering van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "preconditioning_configure_seats": { "name": "Stoelvoorverwarming configureren", "description": "Verstuur een configuratie-opdracht voor stoelvoorverwarming naar een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "front_left": { "name": "Voor links", "description": "Activeer als de voorste linkerstoel moet worden voorverwarmd." }, "front_right": { "name": "Voor rechts", "description": "Activeer als de voorste rechterstoel moet worden voorverwarmd." }, "rear_left": { "name": "Achter links", "description": "Activeer als de achterste linkerstoel moet worden voorverwarmd." }, "rear_right": { "name": "Achter rechts", "description": "Activeer als de achterste rechterstoel moet worden voorverwarmd." } } }, "preheat_start": { "name": "Voorverwarming starten", "description": "Start de voorverwarming van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "type": { "name": "Type", "description": "De methode die wordt gebruikt om het startproces te initiëren. 0=Nu (standaard), 1=Onmiddellijk - gebruik 'Onmiddellijk' als je auto 'Nu' niet ondersteunt." } } }, "preheat_start_departure_time": { "name": "Voorverwarming starten met vertrektijd", "description": "Start de voorverwarming van een auto die wordt gedefinieerd door een VIN en een opgegeven vertrektijd.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "time": { "name": "Tijd", "description": "Vertrektijd in minuten na middernacht. Bijvoorbeeld: een geldige waarde voor 8 uur 's ochtends is 480. Waardenbereik is 0 tot 1439." } } }, "preheat_stop": { "name": "Voorverwarming stoppen", "description": "Stop de voorverwarming van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "preheat_stop_departure_time": { "name": "Voorverwarming stoppen (vertrektijd-modus)", "description": "Stop de geconfigureerde vertrektijd voor voorverwarming van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "preconditioning_configure": { "name": "Voorverwarming vertrek configureren", "description": "Configureer de vertrektijdmodus voor voorverwarming. Gebruik modus 0 (Uitgeschakeld) om geplande vertrekvoorverwarming te annuleren.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "departure_time_mode": { "name": "Vertrektijdmodus", "description": "0=Uitgeschakeld, 1=Eenmalig vertrek, 2=Wekelijks vertrek" }, "departure_time": { "name": "Vertrektijd", "description": "Vertrektijd in minuten na middernacht (0-1439). Alleen gebruikt wanneer modus > 0." } } }, "sigpos_start": { "name": "Starten lichtsignalisatie", "description": "Start de lichtsignalisatie van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "sunroof_open": { "name": "Schuifdak openen", "description": "Open het schuifdak van een auto die wordt gedefinieerd door een VIN. PIN-instelling vereist. Zie de optiedialoog van de integratie.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "pin": { "name": "Pin", "description": "PIN-code, vereist als deze niet is opgeslagen in de instellingen." } } }, "sunroof_tilt": { "name": "Schuifdak kantelen", "description": "Kantel het schuifdak van een auto die wordt gedefinieerd door een VIN. PIN-instelling vereist. Zie de optiedialoog van de integratie.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "pin": { "name": "Pin", "description": "PIN-code, vereist als deze niet is opgeslagen in de instellingen." } } }, "sunroof_close": { "name": "Schuifdak sluiten", "description": "Sluit het schuifdak van een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "temperature_configure": { "name": "Doeltemperatuur configureren (voorverwarming/extra verwarming)", "description": "Configureer de doeltemperaturen voor voorverwarming/extra verwarming voor zones in een auto die wordt gedefinieerd door een VIN.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "front_left": { "name": "Voor links", "description": "Doeltemperatuur voor de zone voor links in CELSIUS." }, "front_right": { "name": "Voor rechts", "description": "Doeltemperatuur voor de zone voor rechts in CELSIUS." }, "rear_left": { "name": "Achter links", "description": "Doeltemperatuur voor de zone achter links in CELSIUS (indien beschikbaar)" }, "rear_right": { "name": "Achter rechts", "description": "Doeltemperatuur voor de zone achter rechts in CELSIUS (indien beschikbaar)" } } }, "windows_open": { "name": "Ramen openen", "description": "Open de ramen van een auto die wordt gedefinieerd door een VIN. PIN-instelling vereist. Zie de optiedialoog van de integratie.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "pin": { "name": "Pin", "description": "PIN-code, vereist als deze niet is opgeslagen in de instellingen." } } }, "windows_close": { "name": "Ramen sluiten", "description": "Sluit de ramen van een auto die wordt gedefinieerd door een VIN. PIN-instelling vereist. Zie de optiedialoog van de integratie.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" } } }, "windows_move": { "name": "Ramen bewegen", "description": "Beweeg de ramen van een auto die wordt gedefinieerd door een VIN naar een nieuwe positie. PIN-instelling vereist. Zie de optiedialoog van de integratie.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "pin": { "name": "Pin", "description": "PIN-code, vereist als deze niet is opgeslagen in de instellingen." }, "front_left": { "name": "Voor links", "description": "De nieuwe positie van het linker voorraam (0=gesloten, 10=ventileren, 100=open)" }, "front_right": { "name": "Voor rechts", "description": "De nieuwe positie van het rechter voorraam (0=gesloten, 10=ventileren, 100=open)" }, "rear_left": { "name": "Achter links", "description": "De nieuwe positie van het linker achterraam (0=gesloten, 10=ventileren, 100=open)" }, "rear_right": { "name": "Achter rechts", "description": "De nieuwe positie van het rechter achterraam (0=gesloten, 10=ventileren, 100=open)" } } }, "send_route": { "name": "Route verzenden", "description": "Verzend een route naar de auto. (Enkel één locatie)", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "title": { "name": "Titel", "description": "Titel van de route" }, "latitude": { "name": "Breedtegraad", "description": "Breedtegraad van de locatie" }, "longitude": { "name": "Lengtegraad", "description": "Lengtegraad van de locatie" }, "city": { "name": "Stad", "description": "Naam van de stad van de locatie" }, "postcode": { "name": "Postcode", "description": "Postcode van de locatie" }, "street": { "name": "Straat", "description": "Straatnaam van de locatie" } } }, "charging_break_clocktimer_configure": { "name": "Oplaadpauze kloktimer configureren", "description": "Configureer oplaadpauzes (alleen AC). Dit zal de volledige configuratie voor alle slots in je auto overschrijven.", "fields": { "vin": { "name": "Chassisnummer", "description": "Chassisnummer van de auto" }, "status_timer_1": { "name": "Status (Timer 1)", "description": "" }, "starttime_timer_1": { "name": "Starttijd (Timer 1)", "description": "Starttijd van het oplaadpauzevenster (Timer 1)" }, "stoptime_timer_1": { "name": "Eindtijd (Timer 1)", "description": "Eindtijd van het oplaadpauzevenster (Timer 1)" }, "status_timer_2": { "name": "Status (Timer 2)", "description": "" }, "starttime_timer_2": { "name": "Starttijd (Timer 2)", "description": "Starttijd van het oplaadpauzevenster (Timer 2)" }, "stoptime_timer_2": { "name": "Eindtijd (Timer 2)", "description": "Eindtijd van het oplaadpauzevenster (Timer 2)" }, "status_timer_3": { "name": "Status (Timer 3)", "description": "" }, "starttime_timer_3": { "name": "Starttijd (Timer 3)", "description": "Starttijd van het oplaadpauzevenster (Timer 3)" }, "stoptime_timer_3": { "name": "Eindtijd (Timer 3)", "description": "Eindtijd van het oplaadpauzevenster (Timer 3)" }, "status_timer_4": { "name": "Status (Timer 4)", "description": "" }, "starttime_timer_4": { "name": "Starttijd (Timer 4)", "description": "Starttijd van het oplaadpauzevenster (Timer 4)" }, "stoptime_timer_4": { "name": "Eindtijd (Timer 4)", "description": "Eindtijd van het oplaadpauzevenster (Timer 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Opladen actief" } }, "sensor": { "chargingpowerecolimit": { "name": "Laadvermogen Limiet" }, "auxheatstatus": { "state": { "0": "Inactief", "1": "Normaal verwarmen", "2": "Normale ventilatie", "3": "Handmatig verwarmen", "4": "Naverwarmen", "5": "Naventileren", "6": "Automatisch verwarmen" } }, "chargeflapacstatus": { "state": { "0": "Open", "1": "Gesloten", "2": "Klep ingedrukt", "3": "Onbekend" } }, "chargeflapdcstatus": { "state": { "0": "Open", "1": "Gesloten", "2": "Klep ingedrukt", "3": "Onbekend" } }, "chargingstatus": { "state": { "0": "Opladen", "1": "Opladen beëindigd", "2": "Oplaadpauze", "3": "Losgekoppeld", "4": "Fout", "5": "Langzaam", "6": "Snel", "7": "Ontladen", "8": "Niet aan het opladen", "9": "Langzaam opladen na bereiken ritdoel", "10": "Opladen na bereiken ritdoel", "11": "Snel opladen na bereiken ritdoel", "12": "Verbonden", "13": "AC opladen", "14": "DC opladen", "15": "Batterijkalibratie actief", "16": "Onbekend" } }, "departuretimemode": { "state": { "0": "Uitgeschakeld", "1": "Dagelijks", "2": "Wekelijks" } }, "ignitionstate": { "state": { "0": "Vergrendeld", "1": "Uit", "2": "Accessoire", "4": "Aan", "5": "Start" } }, "interiorprotectionsensorstatus": { "state": { "0": "Niet actief", "1": "Niet actief", "2": "Actief" }, "state_attributes": {} }, "lock": { "state": { "0": "Ontgrendeld", "1": "Intern vergrendeld", "2": "Vergrendeld", "3": "Deels ontgrendeld", "4": "Onbekend" }, "state_attributes": { "decklidstatus": { "name": "Bagageklep", "state": { "false": "gesloten", "true": "open" } }, "doorstatusfrontleft": { "name": "Deur voor links", "state": { "false": "gesloten", "true": "open" } }, "doorstatusfrontright": { "name": "Deur voor rechts", "state": { "false": "gesloten", "true": "open" } }, "doorstatusrearleft": { "name": "Deur achter links", "state": { "false": "gesloten", "true": "open" } }, "doorstatusrearright": { "name": "Deur achter rechts", "state": { "false": "gesloten", "true": "open" } }, "doorlockstatusfrontleft": { "name": "Deurslot voor links", "state": { "false": "vergrendeld", "true": "ontgrendeld" } }, "doorlockstatusfrontright": { "name": "Deurslot voor rechts", "state": { "false": "vergrendeld", "true": "ontgrendeld" } }, "doorlockstatusrearleft": { "name": "Deurslot achter links", "state": { "false": "vergrendeld", "true": "ontgrendeld" } }, "doorlockstatusrearright": { "name": "Deurslot achter rechts", "state": { "false": "vergrendeld", "true": "ontgrendeld" } }, "doorlockstatusgas": { "name": "Tankdopslot", "state": { "false": "vergrendeld", "true": "ontgrendeld" } }, "enginehoodstatus": { "name": "Motorkap", "state": { "false": "gesloten", "true": "open" } }, "doorstatusoverall": { "name": "Algemene deurstatus", "state": { "0": "open", "1": "gesloten", "2": "niet aanwezig", "3": "onbekend" } }, "sunroofstatus": { "name": "Schuifdak status", "state": { "0": "gesloten", "1": "open", "2": "open gekanteld", "3": "in beweging", "4": "anti-dreunstand", "5": "tussenpositie schuifstand", "6": "tussenpositie kantelstand", "7": "aan het openen", "8": "aan het sluiten", "9": "anti-dreun kantelstand", "10": "tussenpositie", "11": "openen kantelstand", "12": "sluiten kantelstand" } } } }, "sunroofstatus": { "state": { "0": "Gesloten", "1": "Open", "2": "Open gekanteld", "3": "In beweging", "4": "Anti-dreunstand", "5": "Tussenpositie schuifstand", "6": "Tussenpositie kantelstand", "7": "Aan het openen", "8": "Aan het sluiten", "9": "Anti-dreunstand kantelstand", "10": "Tussenpositie", "11": "Openen kantelstand", "12": "Sluiten kantelstand" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Groen", "1": "Geel", "2": "Rood" } }, "tirewarningsrdk": { "state": { "0": "Geen waarschuwing", "1": "Zachte waarschuwing", "2": "Lage druk", "3": "Lekkage" } }, "selectedchargeprogram": { "state": { "0": "Standaard", "2": "Thuis", "3": "Werk", "4": "Niet ondersteund" } } }, "switch": { "auxheat": { "name": "Hulpverwarming" }, "precond": { "name": "Voorverwarming klimaatregeling" } }, "button": { "btn_preheat_start_now": { "name": "Voorverwarming starten" }, "btn_preheat_stop_now": { "name": "Voorverwarming stoppen" }, "btn_sigpos_start_now": { "name": "Lichtsignaal knipperen" } } }, "selector": { "charge_program": { "options": { "0": "Standaard", "2": "Thuis", "3": "Werk" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Niet ingesteld", "active": "Actief", "inactive": "Inactief" } }, "temperature_configure": { "options": { "0": "Laag", "30": "Hoog" } } } } ================================================ FILE: custom_components/mbapi2020/translations/pl.json ================================================ { "config": { "abort": { "already_configured": "Komponent jest już skonfigurowany.", "reauth_successful": "Re-autoryzacja udana. Trwa ponowne ładowanie komponentu." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Nieznany błąd. Proszę sprawdzić logi Home Assistanta.", "2fa_required": "Konta z uwierzytelnianiem dwuskładnikowym (2FA) nie są obsługiwane.", "legal_terms": "Musisz najpierw zaakceptować warunki prawne na stronie Mercedes" }, "step": { "user": { "data": { "region": "Region" }, "description": "Wybierz swój region.", "title": "Skonfiguruj połączenie Mercedes ME 2020" }, "credentials": { "data": { "username": "Nazwa użytkownika MB (adres e-mail)", "password": "Hasło" }, "description": "Wprowadź dane swojego konta.", "title": "Mercedes ME 2020 - Logowanie" }, "pin": { "data": { "password": "TAN (otrzymany przez e-mail lub SMS)" }, "description": "Wprowadź kod TAN otrzymany przez e-mail lub SMS, aby zakończyć uwierzytelnianie. Jeśli nie otrzymałeś kodu TAN, sprawdź swoją skrzynkę e-mail (w tym folder spam) lub wiadomości SMS.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Ponowne uruchomienie Home Assistant jest wymagane aby ukończyć aktualizację autoryzacji. Kliknij \"wyślij\" aby uruchomić teraz.", "title": "Wymagane ponowne uruchomienie" } } }, "title": "Wymagane ponowne uruchomienie" } }, "options": { "abort": { "already_configured": "Komponent jest już skonfigurowany.", "reauth_successful": "Ponowne uwierzytelnianie powiodło się. Trwa ponowne ładowanie komponentu." }, "step": { "init": { "data": { "cap_check_disabled": "Wyłącz sprawdzanie funkcji", "enable_china_gcj_02": "Włącz transkrypcję GCJ-02 (tylko dla Chin)", "delete_auth_file": "Usuń dane uwierzytelniania. Wymaga ponownego uruchomienia Home Assistanta po zapisaniu.", "excluded_cars": "Wykluczone VINy (oddzielone przecinkami)", "pin": "PIN zabezpieczający (utworzony w aplikacji mobilnej)", "save_files": "TRYB DEBUGOWANIA: Zezwól na zapisywanie wiadomości z serwera do folderu", "overwrite_cap_precondnow": "Exp: Nadpisz zdolność precondnow (ustaw na true)" }, "description": "Ustaw swoje opcje. Część zmian wymaga ponownego uruchomienia Home Assistanta.", "title": "Opcje Mercedes ME 2020" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API dostępne", "websocket_connection_state": "Stan MB WS", "cars_connected": "Połączone samochody", "version": "Wersja" } }, "services": { "refresh_access_token": { "name": "Odśwież token dostępu", "description": "Odśwież token dostępu do API" }, "auxheat_configure": { "name": "Ustawienia ogrzewania dodatkowego", "description": "Komendy do konfiguracji ogrzewania dodatkowego. Można zdefiniować trzy czasy uruchomienia i wybrać jeden aktywny.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "time_selection": { "name": "Wybór czasu", "description": "Wybrany czas startu ogrzewania dodatkowego (0=brak_wyboru, 1=czas_1, 2=czas_2, 3=czas_3)" }, "time_1": { "name": "time_1", "description": "Czas w minutach po północy. Np. dla 8:00 jest to 480. Dostępne wartości 0 do 1439." }, "time_2": { "name": "time_2", "description": "Czas w minutach po północy. Np. dla 8:00 jest to 480. Dostępne wartości 0 do 1439." }, "time_3": { "name": "time_3", "description": "Czas w minutach po północy. Np. dla 8:00 jest to 480. Dostępne wartości 0 do 1439." } } }, "auxheat_start": { "name": "Włącz ogrzewanie dodatkowe", "description": "Włącz ogrzewanie dodatkowe pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "auxheat_stop": { "name": "Wyłącz ogrzewanie dodatkowe", "description": "Wyłącz ogrzewanie dodatkowe pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "battery_max_soc_configure": { "name": "Ustawienie maksymalnego stanu naładowania baterii", "description": "Ustaw wartość maksymalnego stanu naładowania baterii pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "max_soc": { "name": "Maksymalny stan naładowania", "description": "Maksymalna wartość naładowania baterii pojazdu (Wartość musi zawierać się między 50 (niektóre nowe samochody jak CLA 2025 obsługują 30) a 100 i być podzielna przez 10)" }, "charge_program": { "name": "Program ładowania", "description": "(Opcjonalnie, Domyślnie=0) Zmiana programu ładowania (0=Domyślny, 2=Dom, 3=Praca) (nie używane dla CLA 2025)" } } }, "charge_program_configure": { "name": "Konfiguracja programu ładowania", "description": "Komenda wyboru programu ładowania.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "charge_program": { "name": "Program ładowania", "description": "Aktywny program ładowania (0=Domyślny, 2=Dom, 3=Praca)" }, "max_soc": { "name": "Maksymalny stan naładowania", "description": "Maksymalna wartość naładowania baterii pojazdu (Wartość musi zawierać się między 50 a 100 i być podzielna przez 10)" } } }, "doors_unlock": { "name": "Odblokowanie drzwi", "description": "Odblokuj pojazd zdefiniowany VIN. Wymagany PIN. Sprawdź opcje w ustawieniach integracji.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "pin": { "name": "PIN", "description": "PIN bezpieczeństwa, wymagany gdy nie jest zapisany w ustawieniach." } } }, "doors_lock": { "name": "Zablokowanie drzwi", "description": "Zablokuj pojazd zdefiniowany VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "download_images": { "name": "Pobierz obrazy", "description": "Pobierz zdjęcia pojazdu do folderu komponentu dla pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "engine_start": { "name": "Uruchom silnik", "description": "Uruchom silnik pojazdu zdefiniowanego VIN. Wymagany PIN. Sprawdź opcje w ustawieniach integracji.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "pin": { "name": "PIN", "description": "PIN bezpieczeństwa, wymagany gdy nie zapisano w ustawieniach." } } }, "engine_stop": { "name": "Wyłącz silnik", "description": "Wyłącz silnik pojazdu zdefiniowanego VIN. Wymagany PIN. Sprawdź opcje w ustawieniach integracji.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "hv_battery_start_conditioning": { "name": "Rozpocznij kondycjonowanie baterii HV", "description": "Rozpocznij kondycjonowanie baterii HV pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "hv_battery_stop_conditioning": { "name": "Zatrzymaj kondycjonowanie baterii HV", "description": "Zatrzymaj kondycjonowanie baterii HV pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "preconditioning_configure_seats": { "name": "Konfiguracja klimatyzacji wstępnej siedzeń", "description": "Wyślij komendę konfiguracji klimatyzacji wstępnej siedzeń do pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "front_left": { "name": "Lewe przednie", "description": "Aktywuj jeśli lewe przednie siedzenie ma być podgrzane." }, "front_right": { "name": "Prawe przednie", "description": "Aktywuj jeśli prawe przednie siedzenie ma być podgrzane." }, "rear_left": { "name": "Lewe tylne", "description": "Aktywuj jeśli lewe tylne siedzenie ma być podgrzane." }, "rear_right": { "name": "Prawe tylne", "description": "Aktywuj jeśli prawe tylne siedzenie ma być podgrzane." } } }, "preheat_start": { "name": "Włącz klimatyzację wstępną", "description": "Włącz klimatyzację wstępną pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "type": { "name": "Typ", "description": "Metoda używana do włączania. 0=Teraz (Domyślne), 1=Natychmiast - Użyj Natychmiast w przypadku gdy Twój pojazd nie obsługuje Teraz." } } }, "preheat_start_departure_time": { "name": "Klimatyzacja wstępna z czasem odjazdu", "description": "Ustaw klimatyzację wstępną pojazdu zdefiniowanego VIN na podaną godzinę.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "time": { "name": "Czas", "description": "Czas odjazdu w minutach po północy. Np. dla 8:00 wartość to 480. Dostępne wartości od 0 do 1439." } } }, "preheat_stop": { "name": "Wyłącz wstępną klimatyzację", "description": "Wyłącz wstępną klimatyzację pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "preheat_stop_departure_time": { "name": "Wyłącz wstępną klimatyzację dla trybu z czasem odjazdu", "description": "Wyłącz wstępną klimatyzację z czasem odjazdu dla pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "preconditioning_configure": { "name": "Konfiguracja odjazdu z klimatyzacją wstępną", "description": "Konfiguracja trybu czasu odjazdu klimatyzacji wstępnej. Użyj trybu 0 (Wyłączony) aby anulować zaplanowaną klimatyzację wstępną.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "departure_time_mode": { "name": "Tryb czasu odjazdu", "description": "0=Wyłączony, 1=Pojedynczy odjazd, 2=Tygodniowy odjazd" }, "departure_time": { "name": "Czas odjazdu", "description": "Czas odjazdu w minutach po północy (0-1439). Używany tylko gdy tryb > 0." } } }, "sigpos_start": { "name": "Włącz sygnalizację światłami", "description": "Włącz sygnalizację światłami pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "sunroof_open": { "name": "Otwórz szyberdach", "description": "Otwórz szyberdach pojazdu zdefiniowanego VIN. Wymagany PIN. Sprawdź opcje w ustawieniach integracji.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "pin": { "name": "PIN", "description": "PIN bezpieczeństwa, wymagany gdy nie zapisano w ustawieniach." } } }, "sunroof_tilt": { "name": "Uchyl szyberdach", "description": "Uchyl szyberdach pojazdu zdefiniowanego VIN. Wymagany PIN. Sprawdź opcje w ustawieniach integracji.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "pin": { "name": "PIN", "description": "PIN bezpieczeństwa, wymagany gdy nie zapisano w ustawieniach." } } }, "sunroof_close": { "name": "Zamknij szyberdach", "description": "Zamknij szyberdach pojazdu zdefiniowanego VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "temperature_configure": { "name": "Konfiguracja temperatury docelowej (klimatyzacja/ogrzewanie)", "description": "Skonfiguruj docelowe temperatury klimatyzacji wstępnej/ogrzewania dodatkowego dla stref w pojeździe zdefiniowanym VIN.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "front_left": { "name": "Lewe przednie", "description": "Temperatura docelowa dla strefy przedniej lewej w stopniach Celsjusza." }, "front_right": { "name": "Prawe przednie", "description": "Temperatura docelowa dla strefy przedniej prawej w stopniach Celsjusza." }, "rear_left": { "name": "Lewe tylne", "description": "Temperatura docelowa dla strefy tylnej lewej w stopniach Celsjusza (jeśli dostępna)." }, "rear_right": { "name": "Prawe tylne", "description": "Temperatura docelowa dla strefy tylnej prawej w stopniach Celsjusza (jeśli dostępna)." } } }, "windows_open": { "name": "Otwórz okna", "description": "Otwórz okna pojazdu zdefiniowanego VIN. Wymagany PIN. Sprawdź opcje w ustawieniach integracji.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "pin": { "name": "PIN", "description": "PIN bezpieczeństwa, wymagany gdy nie zapisano w ustawieniach." } } }, "windows_close": { "name": "Zamknij okna", "description": "Zamknij okna pojazdu zdefiniowanego VIN. Wymagany PIN. Sprawdź opcje w ustawieniach integracji.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" } } }, "windows_move": { "name": "Ruch okien", "description": "Przesuń okna pojazdu zdefiniowanego VIN do nowej pozycji. Wymagany PIN. Sprawdź opcje w ustawieniach integracji.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "pin": { "name": "PIN", "description": "PIN bezpieczeństwa, wymagany gdy nie zapisano w ustawieniach." }, "front_left": { "name": "Lewe przednie", "description": "Nowa pozycja przedniego lewego okna (0=zamknięte, 10=wentylacja, 100=otwarte)" }, "front_right": { "name": "Prawe przednie", "description": "Nowa pozycja przedniego prawego okna (0=zamknięte, 10=wentylacja, 100=otwarte)" }, "rear_left": { "name": "Lewe tylne", "description": "Nowa pozycja tylnego lewego okna (0=zamknięte, 10=wentylacja, 100=otwarte)" }, "rear_right": { "name": "Prawe tylne", "description": "Nowa pozycja tylnego prawego okna (0=zamknięte, 10=wentylacja, 100=otwarte)" } } }, "send_route": { "name": "Wyślij trasę", "description": "Wyślij trasę do pojazdu (tylko jeden cel).", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "title": { "name": "Nazwa", "description": "Nazwa trasy" }, "latitude": { "name": "Szerokość geograficzna", "description": "Szerokość geograficzna celu" }, "longitude": { "name": "Długość geograficzna", "description": "Długość geograficzna celu" }, "city": { "name": "Miejscowość", "description": "Nazwa miejscowości lokalizacji" }, "postcode": { "name": "Kod pocztowy", "description": "Kod pocztowy celu" }, "street": { "name": "Ulica", "description": "Nazwa ulicy lokalizacji" } } }, "charging_break_clocktimer_configure": { "name": "Konfiguracja przerw w ładowaniu", "description": "Skonfiguruj przerwy w ładowaniu (tylko AC). To nadpisze całą konfigurację dla wszystkich slotów w Twoim pojeździe.", "fields": { "vin": { "name": "VIN", "description": "VIN/FIN pojazdu" }, "status_timer_1": { "name": "Status (Timer 1)", "description": "" }, "starttime_timer_1": { "name": "Czas rozpoczęcia (Timer 1)", "description": "Czas rozpoczęcia okna przerwy w ładowaniu (Timer 1)" }, "stoptime_timer_1": { "name": "Czas zakończenia (Timer 1)", "description": "Czas zakończenia okna przerwy w ładowaniu (Timer 1)" }, "status_timer_2": { "name": "Status (Timer 2)", "description": "" }, "starttime_timer_2": { "name": "Czas rozpoczęcia (Timer 2)", "description": "Czas rozpoczęcia okna przerwy w ładowaniu (Timer 2)" }, "stoptime_timer_2": { "name": "Czas zakończenia (Timer 2)", "description": "Czas zakończenia okna przerwy w ładowaniu (Timer 2)" }, "status_timer_3": { "name": "Status (Timer 3)", "description": "" }, "starttime_timer_3": { "name": "Czas rozpoczęcia (Timer 3)", "description": "Czas rozpoczęcia okna przerwy w ładowaniu (Timer 3)" }, "stoptime_timer_3": { "name": "Czas zakończenia (Timer 3)", "description": "Czas zakończenia okna przerwy w ładowaniu (Timer 3)" }, "status_timer_4": { "name": "Status (Timer 4)", "description": "" }, "starttime_timer_4": { "name": "Czas rozpoczęcia (Timer 4)", "description": "Czas rozpoczęcia okna przerwy w ładowaniu (Timer 4)" }, "stoptime_timer_4": { "name": "Czas zakończenia (Timer 4)", "description": "Czas zakończenia okna przerwy w ładowaniu (Timer 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Ładowanie aktywne" } }, "sensor": { "chargingpowerecolimit": { "name": "Limit mocy ładowania" }, "auxheatstatus": { "state": { "0": "Nieaktywne", "1": "Ogrzewanie normalne", "2": "Wentylacja normalna", "3": "Ogrzewanie ręczne", "4": "Dogrzewanie", "5": "Wentylacja końcowa", "6": "Ogrzewanie automatyczne" } }, "chargeflapacstatus": { "state": { "0": "Otwarta", "1": "Zamknięta", "2": "Klapa naciśnięta", "3": "Nieznany" } }, "chargeflapdcstatus": { "state": { "0": "Otwarta", "1": "Zamknięta", "2": "Klapa naciśnięta", "3": "Nieznany" } }, "chargingstatus": { "state": { "0": "ładowanie", "1": "ładowanie kończy się", "2": "Przerwa w ładowaniu", "3": "odłączony", "4": "awaria", "5": "wolne", "6": "szybkie", "7": "rozładowywanie", "8": "nie ładuje", "9": "wolne ładowanie po osiągnięciu celu podróży", "10": "ładowanie po osiągnięciu celu podróży", "11": "szybkie ładowanie po osiągnięciu celu podróży", "12": "Podłączony", "13": "Ładowanie AC", "14": "Ładowanie DC", "15": "Kalibracja baterii aktywna", "16": "nieznany" } }, "departuretimemode": { "state": { "0": "Wyłączony", "1": "Dzienny", "2": "Tygodniowy" } }, "ignitionstate": { "state": { "0": "Zablokowany", "1": "Wyłączony", "2": "Akcesoria", "4": "Włączony", "5": "Rozruch" } }, "interiorprotectionsensorstatus": { "state": { "0": "Nieaktywne", "1": "Nieaktywne", "2": "Aktywne" }, "state_attributes": {} }, "lock": { "state": { "0": "Odblokowany", "1": "Zablokowany od środka", "2": "Zablokowany", "3": "Częściowo odblokowany", "4": "Nieznany" }, "state_attributes": { "decklidstatus": { "name": "Klapa bagażnika", "state": { "false": "zamknięta", "true": "otwarta" } }, "doorstatusfrontleft": { "name": "Drzwi przednie lewe", "state": { "false": "zamknięte", "true": "otwarte" } }, "doorstatusfrontright": { "name": "Drzwi przednie prawe", "state": { "false": "zamknięte", "true": "otwarte" } }, "doorstatusrearleft": { "name": "Drzwi tylne lewe", "state": { "false": "zamknięte", "true": "otwarte" } }, "doorstatusrearright": { "name": "Drzwi tylne prawe", "state": { "false": "zamknięte", "true": "otwarte" } }, "doorlockstatusfrontleft": { "name": "Zamek drzwi przednich lewych", "state": { "false": "zablokowany", "true": "odblokowany" } }, "doorlockstatusfrontright": { "name": "Zamek drzwi przednich prawych", "state": { "false": "zablokowany", "true": "odblokowany" } }, "doorlockstatusrearleft": { "name": "Zamek drzwi tylnych lewych", "state": { "false": "zablokowany", "true": "odblokowany" } }, "doorlockstatusrearright": { "name": "Zamek drzwi tylnych prawych", "state": { "false": "zablokowany", "true": "odblokowany" } }, "doorlockstatusgas": { "name": "Klapka wlewu paliwa", "state": { "false": "zablokowana", "true": "odblokowana" } }, "enginehoodstatus": { "name": "Maska silnika", "state": { "false": "zamknięta", "true": "otwarta" } }, "doorstatusoverall": { "name": "Ogólny stan drzwi", "state": { "0": "otwarte", "1": "zamknięte", "2": "nieistniejące", "3": "nieznany" } }, "sunroofstatus": { "name": "Stan szyberdachu", "state": { "0": "zamknięty", "1": "otwarty", "2": "uchylanie", "3": "działa", "4": "pozycja cicha", "5": "przesuwanie średnie", "6": "unoszenie średnie", "7": "otwieranie", "8": "zamykanie", "9": "unoszenie do pozycji cichej", "10": "pozycja pośrednia", "11": "otwieranie unoszenie", "12": "zamykanie podnoszące" } } } }, "sunroofstatus": { "state": { "0": "Zamknięty", "1": "Otwarty", "2": "Otwarty unoszący", "3": "W ruchu", "4": "Pozycja cicha", "5": "Średnie przesuwanie", "6": "Średnie unoszenie", "7": "Otwieranie", "8": "Zamykanie", "9": "Uchylony do pozycji cichej", "10": "Pozycja pośrednia", "11": "Otwieranie uchylenia", "12": "Zamykanie uchylenia" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Zielony", "1": "Żółty", "2": "Czerwony" } }, "tirewarningsrdk": { "state": { "0": "Brak ostrzeżenia", "1": "Łagodne ostrzeżenie", "2": "Niskie ciśnienie", "3": "Utrata powietrza" } }, "selectedchargeprogram": { "state": { "0": "Standardowy", "2": "Dom", "3": "Praca", "4": "Nieobsługiwany" } } }, "switch": { "auxheat": { "name": "Ogrzewanie dodatkowe" }, "precond": { "name": "Klimatyzacja wstępna" } }, "button": { "btn_preheat_start_now": { "name": "Rozpocznij klimatyzację wstępną" }, "btn_preheat_stop_now": { "name": "Zatrzymaj klimatyzację wstępną" }, "btn_sigpos_start_now": { "name": "Błysk świateł" } } }, "selector": { "charge_program": { "options": { "0": "Domyślny", "2": "Dom", "3": "Praca" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Nie ustawiono", "active": "Aktywny", "inactive": "Nieaktywny" } }, "temperature_configure": { "options": { "0": "Niska", "30": "Wysoka" } } } } ================================================ FILE: custom_components/mbapi2020/translations/pt.json ================================================ { "config": { "abort": { "already_configured": "O componente já está configurado.", "reauth_successful": "Reautenticação bem-sucedida! Recarregamento do componente em curso." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Erro desconhecido. Por favor, verifique o registo do Home Assistant para mais informações.", "2fa_required": "Contas com autenticação de dois fatores (2FA) não são suportadas.", "legal_terms": "É necessário aceitar os termos legais no site da Mercedes primeiro" }, "step": { "user": { "data": { "region": "Região" }, "description": "Selecione a sua região.", "title": "Configurar a ligação Mercedes ME 2020" }, "credentials": { "data": { "username": "Utilizador MB (endereço de e-mail)", "password": "Palavra-passe" }, "description": "Introduza os dados da sua conta.", "title": "Mercedes ME 2020 - Iniciar sessão" }, "pin": { "data": { "password": "TAN (recebido por e-mail ou SMS)" }, "description": "Introduza o TAN que recebeu por e-mail ou SMS para concluir a autenticação. Se não recebeu um TAN, verifique a sua caixa de entrada de e-mail (e pasta de spam) ou as suas mensagens SMS.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "É necessário reiniciar o Home Assistant para concluir a atualização de autenticação. Clique em submeter para reiniciar agora.", "title": "Reinício necessário" } } }, "title": "Reinício necessário" } }, "options": { "abort": { "already_configured": "O componente já está configurado.", "reauth_successful": "Reautenticação bem-sucedida! Recarregamento do componente em curso." }, "step": { "init": { "data": { "cap_check_disabled": "Desativar verificação de capacidades", "enable_china_gcj_02": "Ativar tradução GCJ-02 (apenas China)", "delete_auth_file": "Eliminar o token de autenticação agora. Requer um reinício do Home Assistant após guardar.", "excluded_cars": "VINs excluídos (separados por vírgula)", "pin": "PIN de segurança (a criar na aplicação móvel)", "save_files": "APENAS DEBUG: Ativar guardar mensagens do servidor na pasta de mensagens", "overwrite_cap_precondnow": "Exp: Substituir capacidade precondnow (definir como verdadeiro)" }, "description": "Configure as suas opções. Algumas alterações requerem um reinício do Home Assistant.", "title": "Opções Mercedes ME 2020" } } }, "system_health": { "info": { "api_endpoint_reachable": "API MB acessível", "websocket_connection_state": "Estado WS MB", "cars_connected": "Carros ligados", "version": "Versão" } }, "services": { "refresh_access_token": { "name": "Atualizar token de acesso", "description": "Atualizar o token de acesso à API" }, "auxheat_configure": { "name": "Configurar aquecimento auxiliar", "description": "Comando para configurar o aquecimento auxiliar. É possível definir três horários e selecionar um horário ativo.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "time_selection": { "name": "Seleção de horário", "description": "O horário predefinido de aquecimento auxiliar ativado (0=sem_seleção, 1=time_1, 2=time_2, 3=time_3)" }, "time_1": { "name": "time_1", "description": "Hora do dia em minutos após a meia-noite. Ex.: o valor válido para as 8h seria 480. O intervalo de valores é de 0 a 1439." }, "time_2": { "name": "time_2", "description": "Hora do dia em minutos após a meia-noite. Ex.: o valor válido para as 8h seria 480. O intervalo de valores é de 0 a 1439." }, "time_3": { "name": "time_3", "description": "Hora do dia em minutos após a meia-noite. Ex.: o valor válido para as 8h seria 480. O intervalo de valores é de 0 a 1439." } } }, "auxheat_start": { "name": "Iniciar aquecimento auxiliar", "description": "Iniciar o aquecimento auxiliar de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "auxheat_stop": { "name": "Parar aquecimento auxiliar", "description": "Parar o aquecimento auxiliar de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "battery_max_soc_configure": { "name": "Configurar SOC máximo da bateria", "description": "Configurar o valor máximo para o estado de carga da bateria HV de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "max_soc": { "name": "SOC Máx", "description": "O valor máximo para o estado de carga da bateria HV (o valor deve estar entre 50 (alguns carros novos como o CLA 2025 suportam 30) e 100 e ser divisível por dez)" }, "charge_program": { "name": "Programa de carregamento", "description": "(Opcional, Predefinido=0) Programa de carregamento a alterar (0=Predefinido, 2=Casa, 3=Trabalho) (não utilizado para o CLA 2025)" } } }, "charge_program_configure": { "name": "Configurar programa de carregamento", "description": "Comando para selecionar o programa de carregamento.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "charge_program": { "name": "Programa de carregamento", "description": "O programa de carregamento ativado (0=Predefinido, 2=Casa, 3=Trabalho)" }, "max_soc": { "name": "SOC Máx", "description": "O valor máximo para o estado de carga da bateria HV (o valor deve estar entre 50 e 100 e ser divisível por dez)" } } }, "doors_unlock": { "name": "Destrancar portas", "description": "Destrancar um carro definido por um vin. Configuração de PIN necessária. Consulte o diálogo de opções da integração.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "pin": { "name": "Pin", "description": "PIN de segurança, necessário se não estiver guardado nas definições." } } }, "doors_lock": { "name": "Trancar portas", "description": "Trancar um carro definido por um vin", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "download_images": { "name": "Transferir imagens", "description": "Transfere as imagens da aplicação para a pasta de recursos do componente para um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "engine_start": { "name": "Ligar motor", "description": "Ligar o motor de um carro definido por um vin. Configuração de PIN necessária. Consulte o diálogo de opções da integração.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "pin": { "name": "Pin", "description": "PIN de segurança, necessário se não estiver guardado nas definições." } } }, "engine_stop": { "name": "Desligar motor", "description": "Desligar o motor de um carro definido por um vin. Configuração de PIN necessária. Consulte o diálogo de opções da integração.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "hv_battery_start_conditioning": { "name": "Iniciar condicionamento da bateria HV", "description": "Iniciar o condicionamento da bateria HV de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "hv_battery_stop_conditioning": { "name": "Parar condicionamento da bateria HV", "description": "Parar o condicionamento da bateria HV de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "preconditioning_configure_seats": { "name": "Configurar pré-condicionamento dos bancos", "description": "Enviar um comando de configuração de pré-condicionamento dos bancos para um carro definido por um VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "front_left": { "name": "Dianteiro esquerdo", "description": "Ativar se o banco dianteiro esquerdo deve ser pré-condicionado." }, "front_right": { "name": "Dianteiro direito", "description": "Ativar se o banco dianteiro direito deve ser pré-condicionado." }, "rear_left": { "name": "Traseiro esquerdo", "description": "Ativar se o banco traseiro esquerdo deve ser pré-condicionado." }, "rear_right": { "name": "Traseiro direito", "description": "Ativar se o banco traseiro direito deve ser pré-condicionado." } } }, "preheat_start": { "name": "Iniciar pré-condicionamento", "description": "Iniciar o pré-condicionamento de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "type": { "name": "Tipo", "description": "Método utilizado para iniciar o processo. 0=Agora (Predefinido), 1=Imediato - Utilize Imediato caso o seu carro não suporte Agora." } } }, "preheat_start_departure_time": { "name": "Iniciar pré-condicionamento com hora de partida", "description": "Iniciar o pré-condicionamento de um carro definido por um vin e uma hora de partida especificada.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "time": { "name": "Hora", "description": "Hora de partida em minutos após a meia-noite. Ex.: o valor válido para as 8h seria 480. O intervalo de valores é de 0 a 1439." } } }, "preheat_stop": { "name": "Parar pré-condicionamento", "description": "Parar o pré-condicionamento de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "preheat_stop_departure_time": { "name": "Parar modo de pré-condicionamento com hora de partida", "description": "Parar o pré-condicionamento com hora de partida configurada de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "preconditioning_configure": { "name": "Configurar partida com pré-condicionamento", "description": "Configurar o modo de hora de partida do pré-condicionamento. Utilize o modo 0 (Desativado) para cancelar o pré-condicionamento de partida agendado.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "departure_time_mode": { "name": "Modo de hora de partida", "description": "0=Desativado, 1=Partida única, 2=Partida semanal" }, "departure_time": { "name": "Hora de partida", "description": "Hora de partida em minutos após a meia-noite (0-1439). Utilizado apenas quando o modo > 0." } } }, "sigpos_start": { "name": "Iniciar sinal de posição", "description": "Iniciar sinalização luminosa de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "sunroof_open": { "name": "Abrir teto de abrir", "description": "Abrir o teto de abrir de um carro definido por um vin. Configuração de PIN necessária. Consulte o diálogo de opções da integração.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "pin": { "name": "Pin", "description": "PIN de segurança, necessário se não estiver guardado nas definições." } } }, "sunroof_tilt": { "name": "Inclinar teto de abrir", "description": "Inclinar o teto de abrir de um carro definido por um vin. Configuração de PIN necessária. Consulte o diálogo de opções da integração.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "pin": { "name": "Pin", "description": "PIN de segurança, necessário se não estiver guardado nas definições." } } }, "sunroof_close": { "name": "Fechar teto de abrir", "description": "Fechar o teto de abrir de um carro definido por um vin.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "temperature_configure": { "name": "Configurar temperatura alvo (pré-cond/aquec. auxiliar)", "description": "Configurar as temperaturas alvo de pré-condicionamento/aquecimento auxiliar para zonas num carro definido por um VIN.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "front_left": { "name": "Dianteiro esquerdo", "description": "Temperatura alvo para a zona dianteira esquerda em CELSIUS." }, "front_right": { "name": "Dianteiro direito", "description": "Temperatura alvo para a zona dianteira direita em CELSIUS." }, "rear_left": { "name": "Traseiro esquerdo", "description": "Temperatura alvo para a zona traseira esquerda em CELSIUS. (se disponível)" }, "rear_right": { "name": "Traseiro direito", "description": "Temperatura alvo para a zona traseira direita em CELSIUS. (se disponível)" } } }, "windows_open": { "name": "Abrir janelas", "description": "Abrir as janelas de um carro definido por um vin. Configuração de PIN necessária. Consulte o diálogo de opções da integração.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "pin": { "name": "Pin", "description": "PIN de segurança, necessário se não estiver guardado nas definições." } } }, "windows_close": { "name": "Fechar janelas", "description": "Fechar as janelas de um carro definido por um vin. Configuração de PIN necessária. Consulte o diálogo de opções da integração.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" } } }, "windows_move": { "name": "Mover janelas", "description": "Mover as janelas de um carro definido por um vin para uma nova posição. Configuração de PIN necessária. Consulte o diálogo de opções da integração.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "pin": { "name": "Pin", "description": "PIN de segurança, necessário se não estiver guardado nas definições." }, "front_left": { "name": "Dianteira esquerda", "description": "A nova posição da janela dianteira esquerda (0=fechada, 10=ventilação, 100=aberta)" }, "front_right": { "name": "Dianteira direita", "description": "A nova posição da janela dianteira direita (0=fechada, 10=ventilação, 100=aberta)" }, "rear_left": { "name": "Traseira esquerda", "description": "A nova posição da janela traseira esquerda (0=fechada, 10=ventilação, 100=aberta)" }, "rear_right": { "name": "Traseira direita", "description": "A nova posição da janela traseira direita (0=fechada, 10=ventilação, 100=aberta)" } } }, "send_route": { "name": "Enviar rota", "description": "Envia uma rota para o carro. (Apenas localização única)", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "title": { "name": "Título", "description": "Título da rota" }, "latitude": { "name": "Latitude", "description": "Latitude da localização" }, "longitude": { "name": "Longitude", "description": "Longitude da localização" }, "city": { "name": "Cidade", "description": "Nome da cidade da localização" }, "postcode": { "name": "Código postal", "description": "Código postal da localização" }, "street": { "name": "Rua", "description": "Nome da rua da localização" } } }, "charging_break_clocktimer_configure": { "name": "Configurar temporizador de pausa de carregamento", "description": "Configurar pausas de carregamento (apenas AC). Isto irá substituir a configuração completa para todos os slots no seu carro.", "fields": { "vin": { "name": "Vin", "description": "Vin/Fin do carro" }, "status_timer_1": { "name": "Estado (Temporizador 1)", "description": "" }, "starttime_timer_1": { "name": "Hora de início (Temporizador 1)", "description": "Hora de início da janela de pausa de carregamento (Temporizador 1)" }, "stoptime_timer_1": { "name": "Hora de fim (Temporizador 1)", "description": "Hora de fim da janela de pausa de carregamento (Temporizador 1)" }, "status_timer_2": { "name": "Estado (Temporizador 2)", "description": "" }, "starttime_timer_2": { "name": "Hora de início (Temporizador 2)", "description": "Hora de início da janela de pausa de carregamento (Temporizador 2)" }, "stoptime_timer_2": { "name": "Hora de fim (Temporizador 2)", "description": "Hora de fim da janela de pausa de carregamento (Temporizador 2)" }, "status_timer_3": { "name": "Estado (Temporizador 3)", "description": "" }, "starttime_timer_3": { "name": "Hora de início (Temporizador 3)", "description": "Hora de início da janela de pausa de carregamento (Temporizador 3)" }, "stoptime_timer_3": { "name": "Hora de fim (Temporizador 3)", "description": "Hora de fim da janela de pausa de carregamento (Temporizador 3)" }, "status_timer_4": { "name": "Estado (Temporizador 4)", "description": "" }, "starttime_timer_4": { "name": "Hora de início (Temporizador 4)", "description": "Hora de início da janela de pausa de carregamento (Temporizador 4)" }, "stoptime_timer_4": { "name": "Hora de fim (Temporizador 4)", "description": "Hora de fim da janela de pausa de carregamento (Temporizador 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Carregamento ativo" } }, "sensor": { "chargingpowerecolimit": { "name": "Limite de potência de carregamento" }, "auxheatstatus": { "state": { "0": "Inativo", "1": "Aquecimento normal", "2": "Ventilação normal", "3": "Aquecimento manual", "4": "Pós-aquecimento", "5": "Pós-ventilação", "6": "Aquecimento automático" } }, "chargeflapacstatus": { "state": { "0": "Aberta", "1": "Fechada", "2": "Aba pressionada", "3": "Desconhecido" } }, "chargeflapdcstatus": { "state": { "0": "Aberta", "1": "Fechada", "2": "Aba pressionada", "3": "Desconhecido" } }, "chargingstatus": { "state": { "0": "A carregar", "1": "Carregamento a terminar", "2": "Pausa de carregamento", "3": "Desligado", "4": "Falha", "5": "Lento", "6": "Rápido", "7": "A descarregar", "8": "Sem carregamento", "9": "Carregamento lento após atingir meta de viagem", "10": "A carregar após atingir meta de viagem", "11": "Carregamento rápido após atingir meta de viagem", "12": "Ligado", "13": "Carregamento AC", "14": "Carregamento DC", "15": "Calibração da bateria ativa", "16": "Desconhecido" } }, "departuretimemode": { "state": { "0": "Desativado", "1": "Diário", "2": "Semanal" } }, "ignitionstate": { "state": { "0": "Trancado", "1": "Desligado", "2": "Acessório", "4": "Ligado", "5": "Arranque" } }, "interiorprotectionsensorstatus": { "state": { "0": "Não ativo", "1": "Não ativo", "2": "Ativo" }, "state_attributes": {} }, "lock": { "state": { "0": "Destrancado", "1": "Trancado int", "2": "Trancado", "3": "Parcialmente destrancado", "4": "Desconhecido" }, "state_attributes": { "decklidstatus": { "name": "Tampa da mala", "state": { "false": "fechada", "true": "aberta" } }, "doorstatusfrontleft": { "name": "Porta dianteira esquerda", "state": { "false": "fechada", "true": "aberta" } }, "doorstatusfrontright": { "name": "Porta dianteira direita", "state": { "false": "fechada", "true": "aberta" } }, "doorstatusrearleft": { "name": "Porta traseira esquerda", "state": { "false": "fechada", "true": "aberta" } }, "doorstatusrearright": { "name": "Porta traseira direita", "state": { "false": "fechada", "true": "aberta" } }, "doorlockstatusfrontleft": { "name": "Fecho da porta dianteira esquerda", "state": { "false": "trancada", "true": "destrancada" } }, "doorlockstatusfrontright": { "name": "Fecho da porta dianteira direita", "state": { "false": "trancada", "true": "destrancada" } }, "doorlockstatusrearleft": { "name": "Fecho da porta traseira esquerda", "state": { "false": "trancada", "true": "destrancada" } }, "doorlockstatusrearright": { "name": "Fecho da porta traseira direita", "state": { "false": "trancada", "true": "destrancada" } }, "doorlockstatusgas": { "name": "Fecho do depósito", "state": { "false": "trancado", "true": "destrancado" } }, "enginehoodstatus": { "name": "Capô do motor", "state": { "false": "fechado", "true": "aberto" } }, "doorstatusoverall": { "name": "Estado geral das portas", "state": { "0": "aberta", "1": "fechada", "2": "não existente", "3": "desconhecido" } }, "sunroofstatus": { "name": "Estado do teto de abrir", "state": { "0": "fechado", "1": "aberto", "2": "abertura por elevação", "3": "em funcionamento", "4": "posição anti-vibração", "5": "deslizamento intermédio", "6": "elevação intermédia", "7": "a abrir", "8": "a fechar", "9": "elevação anti-vibração", "10": "posição intermédia", "11": "abertura por elevação", "12": "fecho por elevação" } } } }, "sunroofstatus": { "state": { "0": "Fechado", "1": "Aberto", "2": "Abertura por elevação", "3": "Em funcionamento", "4": "Anti-vibração", "5": "Deslizamento intermédio", "6": "Elevação intermédia", "7": "A abrir", "8": "A fechar", "9": "Elevação anti-vibração", "10": "Posição intermédia", "11": "Abertura por elevação", "12": "Fecho por elevação" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Verde", "1": "Amarelo", "2": "Vermelho" } }, "tirewarningsrdk": { "state": { "0": "Sem aviso", "1": "Aviso suave", "2": "Pressão baixa", "3": "Furo" } }, "selectedchargeprogram": { "state": { "0": "Padrão", "2": "Casa", "3": "Trabalho", "4": "Não suportado" } } }, "switch": { "auxheat": { "name": "Aquecimento auxiliar" }, "precond": { "name": "Climatização pré-entrada" } }, "button": { "btn_preheat_start_now": { "name": "Iniciar pré-climatização" }, "btn_preheat_stop_now": { "name": "Parar pré-climatização" }, "btn_sigpos_start_now": { "name": "Piscar luzes" } } }, "selector": { "charge_program": { "options": { "0": "Predefinido", "2": "Casa", "3": "Trabalho" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Não definido", "active": "Ativo", "inactive": "Inativo" } }, "temperature_configure": { "options": { "0": "Baixo", "30": "Alto" } } } } ================================================ FILE: custom_components/mbapi2020/translations/sv.json ================================================ { "config": { "abort": { "already_configured": "Komponenten är redan konfigurerad.", "reauth_successful": "Återautentisering lyckades! Komponenten laddas om." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "Okänt fel. Kontrollera Home Assistant-loggen för mer information.", "2fa_required": "Tvåfaktorsautentisering (2FA)-konton stöds inte.", "legal_terms": "Du måste först godkänna de juridiska villkoren på Mercedes webbplats" }, "step": { "user": { "data": { "region": "Region" }, "description": "Välj region.", "title": "Konfigurera Mercedes ME 2020-anslutningen" }, "credentials": { "data": { "username": "MB användarnamn (e-postadress)", "password": "Lösenord" }, "description": "Ange dina kontouppgifter.", "title": "Mercedes ME 2020 - Inloggningsuppgifter" }, "pin": { "data": { "password": "TAN (mottaget via e-post eller SMS)" }, "description": "Ange det TAN-nummer du har fått via e-post eller SMS för att slutföra autentiseringen. Om du inte har fått något TAN, kontrollera din e-postinkorg (och skräppostmappen) eller dina SMS-meddelanden.", "title": "Mercedes ME 2020 - TAN" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "Omstart av Home Assistant krävs för att slutföra autentiseringsuppdateringen. Klicka på skicka för att starta om nu.", "title": "Omstart krävs" } } }, "title": "Omstart krävs" } }, "options": { "abort": { "already_configured": "Komponenten är redan konfigurerad.", "reauth_successful": "Återautentisering lyckades! Komponenten laddas om." }, "step": { "init": { "data": { "cap_check_disabled": "Inaktivera kompabilitetskontroll", "enable_china_gcj_02": "Aktivera GCJ-02-översättning (endast Kina)", "delete_auth_file": "Ta bort autentiseringstoken nu. Kräver att Home Assistant startas om efter att du har sparat.", "excluded_cars": "VIN-nummer exkluderade (komma-separerade)", "pin": "Säkerhets-PIN (ska skapas i mobilappen)", "save_files": "ENDAST DEBUG: Aktivera spara servermeddelanden i mappen meddelanden", "overwrite_cap_precondnow": "Exp: Skriv över funktionsförutsättning nu (inställd på sant)" }, "description": "Konfigurera dina inställningar. Vissa ändringar kräver att Home Assistant startas om.", "title": "Mercedes ME 2020 Inställningar" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API är nåbart", "websocket_connection_state": "MB WS-tillstånd", "cars_connected": "Anslutna bilar", "version": "Version" } }, "services": { "refresh_access_token": { "name": "Uppdatera åtkomsttoken", "description": "Uppdatera API-åtkomsttoken" }, "auxheat_configure": { "name": "Konfigurera parkeringsvärmare", "description": "Kommando för att konfigurera parkeringsvärmaren. Det är möjligt att definiera tre tidpunkter och välja en aktiv tid.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "time_selection": { "name": "Välj tid", "description": "Den aktiverade förinställda tiden för extravärmaren (0=inget_val, 1=tid_1, 2=tid_2, 3=tid_3)" }, "time_1": { "name": "time_1", "description": "Tidpunkt i minuter efter midnatt. Exempelvis är 480 ett giltigt värde för kl. 08.00. Värdeområdet är 0 till 1439." }, "time_2": { "name": "time_2", "description": "Tidpunkt i minuter efter midnatt. T.ex. är 480 ett giltigt värde för kl. 08.00. Värdeområdet är 0 till 1439." }, "time_3": { "name": "time_3", "description": "Tidpunkt i minuter efter midnatt. T.ex. är 480 ett giltigt värde för kl. 08.00. Värdeområdet är 0 till 1439." } } }, "auxheat_start": { "name": "Starta parkeringsvärmare", "description": "Starta parkeringsvärmaren för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "auxheat_stop": { "name": "Stoppa parkeringsvärmare", "description": "Stoppa parkeringsvärmaren för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "battery_max_soc_configure": { "name": "Konfigurera batteriets maximala laddningsnivå (SoC)", "description": "Konfigurera det maximala värdet för laddningsnivån (SoC) i högspänningsbatteriet för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "max_soc": { "name": "Maximal laddningsnivå (SoC)", "description": "Det maximala värdet för högspänningsbatteriets laddningsnivå (SoC). Värdet måste vara mellan 50 (vissa nya bilar, som 2025 års CLA, stöder 30) och 100, samt vara jämnt delbart med tio." }, "charge_program": { "name": "Laddningsprogram", "description": "(Valfritt, förvalt=0) Laddningsprogram som ska ändras (0=Förvalt, 2=Hem, 3=Arbete) (används ej för 2025 års CLA)" } } }, "charge_program_configure": { "name": "Konfigurera laddningsprogram", "description": "Kommando för att välja laddningsprogram.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "charge_program": { "name": "Laddningsprogram", "description": "Det aktiverade laddningsprogrammet (0=Förvalt, 2=Hem, 3=Arbete)" }, "max_soc": { "name": "Maximal laddningsnivå (SoC)", "description": "Det maximala värdet för högspänningsbatteriets laddningsnivå (SoC). Värdet måste vara mellan 50 och 100 och vara jämnt delbart med tio." } } }, "doors_unlock": { "name": "Lås upp dörrar", "description": "Lås upp en bil definierad av ett VIN-nummer. Konfiguration av PIN-kod krävs. Se integreringsalternativen i inställningarna.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kod", "description": "Säkerhetskod (PIN), krävs om den inte finns sparad i inställningarna." } } }, "doors_lock": { "name": "Lås dörrar", "description": "Lås en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "download_images": { "name": "Hämta bilder", "description": "Hämtar app-bilder till komponentens resursmapp för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "engine_start": { "name": "Starta motor", "description": "Starta motorn på en bil definierad av ett VIN-nummer. Konfiguration av PIN-kod krävs. Se integreringsalternativen i inställningarna.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kod", "description": "Säkerhetskod (PIN), krävs om den inte finns sparad i inställningarna." } } }, "engine_stop": { "name": "Stäng av motor", "description": "Stäng av motorn på en bil definierad av ett VIN-nummer. Konfiguration av PIN-kod krävs. Se integreringsalternativen i inställningarna.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "hv_battery_start_conditioning": { "name": "Starta konditionering av högspänningsbatteri", "description": "Starta konditioneringen av högspänningsbatteriet för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "hv_battery_stop_conditioning": { "name": "Stoppa konditionering av högspänningsbatteri", "description": "Stoppa konditioneringen av högspänningsbatteriet för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preconditioning_configure_seats": { "name": "Konfigurera säten för förklimatisering", "description": "Skicka ett konfigurationskommando för sätesförklimatisering till en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "front_left": { "name": "Vänster fram", "description": "Aktivera om det vänstra framsätet ska förklimatiseras." }, "front_right": { "name": "Höger fram", "description": "Aktivera om det högra framsätet ska förklimatiseras." }, "rear_left": { "name": "Vänster bak", "description": "Aktivera om det vänstra baksätet ska förklimatiseras." }, "rear_right": { "name": "Höger bak", "description": "Aktivera om det högra baksätet ska förklimatiseras." } } }, "preheat_start": { "name": "Starta förklimatisering", "description": "Starta förklimatiseringen för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "type": { "name": "Typ", "description": "Metod som används för att initiera startprocessen. 0=Nu (Standard), 1=Omedelbart - Använd Omedelbart om din bil inte stöder Nu." } } }, "preheat_start_departure_time": { "name": "Starta förklimatisering med avresetid", "description": "Starta förklimatiseringen för en bil definierad av ett VIN-nummer och en angiven avresetid.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "time": { "name": "Tid", "description": "Avresetid i minuter efter midnatt. Exempelvis är 480 ett giltigt värde för kl. 08.00. Värdeområdet är 0 till 1439." } } }, "preheat_stop": { "name": "Stoppa förklimatisering", "description": "Stoppa förklimatiseringen för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preheat_stop_departure_time": { "name": "Stoppa förklimatisering för avresetid", "description": "Stoppa den konfigurerade förklimatiseringen för avresetid för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "preconditioning_configure": { "name": "Konfigurera förklimatisering för avresa", "description": "Konfigurera läge för förklimatisering vid avresa. Använd läge 0 (Inaktiverad) för att avbryta schemalagd förklimatisering vid avresa.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "departure_time_mode": { "name": "Läge för avresetid", "description": "0=Inaktiverad, 1=Enskild avresa, 2=Veckovis avresa" }, "departure_time": { "name": "Avresetid", "description": "Avresetid i minuter efter midnatt (0-1439). Används endast när läget är > 0." } } }, "sigpos_start": { "name": "Starta signalposition", "description": "Starta ljussignalering för en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "sunroof_open": { "name": "Öppna taklucka", "description": "Öppna takluckan på en bil definierad av ett VIN-nummer. Konfiguration av PIN-kod krävs. Se integreringsalternativen i inställningarna.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kod", "description": "Säkerhetskod (PIN), krävs om den inte finns sparad i inställningarna." } } }, "sunroof_tilt": { "name": "Vinkla taklucka", "description": "Vinkla takluckan på en bil definierad av ett VIN-nummer. Konfiguration av PIN-kod krävs. Se integreringsalternativen i inställningarna.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kod", "description": "Säkerhetskod (PIN), krävs om den inte finns sparad i inställningarna." } } }, "sunroof_close": { "name": "Stäng taklucka", "description": "Stäng takluckan på en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "temperature_configure": { "name": "Konfigurera måltemperatur (förklimatisering/parkeringsvärmare)", "description": "Konfigurera måltemperaturer för förklimatisering/parkeringsvärmare för zoner i en bil definierad av ett VIN-nummer.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "front_left": { "name": "Vänster fram", "description": "Måltemperatur för zonen vänster fram i CELSIUS." }, "front_right": { "name": "Höger fram", "description": "Måltemperatur för zonen höger fram i CELSIUS." }, "rear_left": { "name": "Vänster bak", "description": "Måltemperatur för zonen vänster bak i CELSIUS. (om tillgängligt)" }, "rear_right": { "name": "Höger bak", "description": "Måltemperatur för zonen höger bak i CELSIUS. (om tillgängligt)" } } }, "windows_open": { "name": "Öppna fönster", "description": "Öppna fönstren på en bil definierad av ett VIN-nummer. Konfiguration av PIN-kod krävs. Se integreringsalternativen i inställningarna.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kod", "description": "Säkerhetskod (PIN), krävs om den inte finns sparad i inställningarna." } } }, "windows_close": { "name": "Stäng fönster", "description": "Stäng fönstren på en bil definierad av ett VIN-nummer. Konfiguration av PIN-kod krävs. Se integreringsalternativen i inställningarna.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" } } }, "windows_move": { "name": "Flytta fönster", "description": "Flytta fönstren på en bil definierad av ett VIN-nummer till en ny position. Konfiguration av PIN-kod krävs. Se integreringsalternativen i inställningarna.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "pin": { "name": "PIN-kod", "description": "Säkerhetskod (PIN), krävs om den inte finns sparad i inställningarna." }, "front_left": { "name": "Vänster fram", "description": "Den nya positionen för vänster framfönster (0=stängt, 10=vädring, 100=öppet)" }, "front_right": { "name": "Höger fram", "description": "Den nya positionen för höger framfönster (0=stängt, 10=vädring, 100=öppet)" }, "rear_left": { "name": "Vänster bak", "description": "Den nya positionen för vänster bakfönster (0=stängt, 10=vädring, 100=öppet)" }, "rear_right": { "name": "Höger bak", "description": "Den nya positionen för höger bakfönster (0=stängt, 10=vädring, 100=öppet)" } } }, "send_route": { "name": "Skicka rutt", "description": "Skickar en rutt till bilen. (Endast en plats)", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "title": { "name": "Titel", "description": "Ruttens titel" }, "latitude": { "name": "Latitud", "description": "Platsens latitud" }, "longitude": { "name": "Longitud", "description": "Platsens longitud" }, "city": { "name": "Stad", "description": "Platsens stadsnamn" }, "postcode": { "name": "Postnummer", "description": "Platsens postnummer" }, "street": { "name": "Gata", "description": "Platsens gatunamn" } } }, "charging_break_clocktimer_configure": { "name": "Konfigurera tidsinställning för laddningspaus", "description": "Konfigurera laddningspauser (endast AC). Detta kommer att skriva över hela konfigurationen för alla platser i din bil.", "fields": { "vin": { "name": "Vin", "description": "Bilens Vin/Fin" }, "status_timer_1": { "name": "Status (Timer 1)", "description": "" }, "starttime_timer_1": { "name": "Starttid (Timer 1)", "description": "Starttid för laddningspausfönstret (Timer 1)" }, "stoptime_timer_1": { "name": "Sluttid (Timer 1)", "description": "Sluttid för laddningspausfönstret (Timer 1)" }, "status_timer_2": { "name": "Status (Timer 2)", "description": "" }, "starttime_timer_2": { "name": "Starttid (Timer 2)", "description": "Starttid för laddningspausfönstret (Timer 2)" }, "stoptime_timer_2": { "name": "Sluttid (Timer 2)", "description": "Sluttid för laddningspausfönstret (Timer 2)" }, "status_timer_3": { "name": "Status (Timer 3)", "description": "" }, "starttime_timer_3": { "name": "Starttid (Timer 3)", "description": "Starttid för laddningspausfönstret (Timer 3)" }, "stoptime_timer_3": { "name": "Sluttid (Timer 3)", "description": "Sluttid för laddningspausfönstret (Timer 3)" }, "status_timer_4": { "name": "Status (Timer 4)", "description": "" }, "starttime_timer_4": { "name": "Starttid (Timer 4)", "description": "Starttid för laddningspausfönstret (Timer 4)" }, "stoptime_timer_4": { "name": "Sluttid (Timer 4)", "description": "Sluttid för laddningspausfönstret (Timer 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "Laddning aktiv" } }, "sensor": { "chargingpowerecolimit": { "name": "Laddningseffektgräns" }, "auxheatstatus": { "state": { "0": "Inaktiv", "1": "Normal uppvärmning", "2": "Normal ventilation", "3": "Manuell uppvärmning", "4": "Eftervärmning", "5": "Efterventilation", "6": "Automatisk uppvärmning" } }, "chargeflapacstatus": { "state": { "0": "Öppen", "1": "Stängd", "2": "Lucka nedtryckt", "3": "Okänd" } }, "chargeflapdcstatus": { "state": { "0": "Öppen", "1": "Stängd", "2": "Lucka nedtryckt", "3": "Okänd" } }, "chargingstatus": { "state": { "0": "laddar", "1": "laddning avslutas", "2": "Laddningspaus", "3": "urkopplad", "4": "fel", "5": "långsam", "6": "snabb", "7": "laddar ur", "8": "laddar inte", "9": "långsam laddning efter att ha nått resemål", "10": "laddning efter att ha nått resemål", "11": "snabb laddning efter att ha nått resemål", "12": "Ansluten", "13": "AC-laddning", "14": "DC-laddning", "15": "Batterikalibrering aktiv", "16": "okänd" } }, "departuretimemode": { "state": { "0": "Inaktiverad", "1": "Dagligen", "2": "Veckovis" } }, "ignitionstate": { "state": { "0": "Låst", "1": "Av", "2": "Tillbehör", "4": "På", "5": "Start" } }, "interiorprotectionsensorstatus": { "state": { "0": "Ej aktiv", "1": "Ej aktiv", "2": "Aktiv" }, "state_attributes": {} }, "lock": { "state": { "0": "Upplåst", "1": "Låst internt", "2": "Låst", "3": "Delvis upplåst", "4": "Okänd" }, "state_attributes": { "decklidstatus": { "name": "Bagagelucka", "state": { "false": "stängd", "true": "öppen" } }, "doorstatusfrontleft": { "name": "Dörr vänster fram", "state": { "false": "stängd", "true": "öppen" } }, "doorstatusfrontright": { "name": "Dörr höger fram", "state": { "false": "stängd", "true": "öppen" } }, "doorstatusrearleft": { "name": "Dörr vänster bak", "state": { "false": "stängd", "true": "öppen" } }, "doorstatusrearright": { "name": "Dörr höger bak", "state": { "false": "stängd", "true": "öppen" } }, "doorlockstatusfrontleft": { "name": "Dörrlås vänster fram", "state": { "false": "låst", "true": "upplåst" } }, "doorlockstatusfrontright": { "name": "Dörrlås höger fram", "state": { "false": "låst", "true": "upplåst" } }, "doorlockstatusrearleft": { "name": "Dörrlås vänster bak", "state": { "false": "låst", "true": "upplåst" } }, "doorlockstatusrearright": { "name": "Dörrlås höger bak", "state": { "false": "låst", "true": "upplåst" } }, "doorlockstatusgas": { "name": "Tanklucka", "state": { "false": "låst", "true": "upplåst" } }, "enginehoodstatus": { "name": "Motorhuv", "state": { "false": "stängd", "true": "öppen" } }, "doorstatusoverall": { "name": "Övergripande dörrstatus", "state": { "0": "öppen", "1": "stängd", "2": "finns ej", "3": "okänd" } }, "sunroofstatus": { "name": "Takluckestatus", "state": { "0": "stängd", "1": "öppen", "2": "lyft öppen", "3": "körs", "4": "vindavvisande läge", "5": "mellanläge glidande", "6": "mellanläge lyftande", "7": "öppnar", "8": "stänger", "9": "vindavvisande lyftning", "10": "mellanläge", "11": "öppnar lyftning", "12": "stänger lyftning" } } } }, "sunroofstatus": { "state": { "0": "Stängd", "1": "Öppen", "2": "Öppen lyftning", "3": "Körs", "4": "Vindavvisande läge", "5": "Mellanläge glidande", "6": "Mellanläge lyftande", "7": "Öppnar", "8": "Stänger", "9": "Vindavvisande lyftning", "10": "Mellanposition", "11": "Öppnar lyftning", "12": "Stänger lyftning" }, "state_attributes": {} }, "starterbatterystate": { "state": { "0": "Grön", "1": "Gul", "2": "Röd" } }, "tirewarningsrdk": { "state": { "0": "Ingen varning", "1": "Mjuk varning", "2": "Lågt tryck", "3": "Punktering" } }, "selectedchargeprogram": { "state": { "0": "Standard", "2": "Hem", "3": "Arbete", "4": "Stöds inte" } } }, "switch": { "auxheat": { "name": "Parkeringsvärmare" }, "precond": { "name": "Förklimatisering" } }, "button": { "btn_preheat_start_now": { "name": "Starta förklimatisering" }, "btn_preheat_stop_now": { "name": "Stoppa förklimatisering" }, "btn_sigpos_start_now": { "name": "Blinka lampor" } } }, "selector": { "charge_program": { "options": { "0": "Förvalt", "2": "Hem", "3": "Arbete" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "Inte inställd", "active": "Aktiv", "inactive": "Inaktiv" } }, "temperature_configure": { "options": { "0": "Låg", "30": "Hög" } } } } ================================================ FILE: custom_components/mbapi2020/translations/ta.json ================================================ { "config": { "abort": { "already_configured": "கூறு ஏற்கனவே கட்டமைக்கப்பட்டுள்ளது.", "reauth_successful": "மறுஅங்கீகாரம் வெற்றிகரமாக! கூறு மறுஏற்றம் முன்னேற்றத்தில்." }, "error": { "cannot_connect": "cannot_connect", "invalid_auth": "invalid_auth", "unknown": "தெரியாத பிழை. மேலும் தகவலுக்கு ஹோம் அசிஸ்டன்ட் பதிவை சரிபார்க்கவும்.", "2fa_required": "இரு-காரணி அங்கீகாரம் (2FA) கணக்குகள் ஆதரிக்கப்படவில்லை.", "legal_terms": "முதலில் மெர்சிடிஸ் இணையதளத்தில் சட்ட விதிமுறைகளை ஏற்றுக்கொள்ள வேண்டும்" }, "step": { "user": { "data": { "region": "பகுதி" }, "description": "உங்கள் பகுதியைத் தேர்ந்தெடுக்கவும்.", "title": "Mercedes ME 2020 இணைப்பை அமைக்கவும்" }, "credentials": { "data": { "username": "MB பயனர்பெயர் (மின்னஞ்சல் முகவரி)", "password": "கடவுச்சொல்" }, "description": "உங்கள் கணக்கு விவரங்களை உள்ளிடவும்.", "title": "Mercedes ME 2020 - உள்நுழைவு" }, "pin": { "data": { "password": "TAN (மின்னஞ்சல் அல்லது SMS மூலம் பெறப்பட்டது)" }, "description": "அங்கீகாரத்தை முடிக்க மின்னஞ்சல் அல்லது SMS மூலம் பெற்ற TAN ஐ உள்ளிடவும். நீங்கள் TAN பெறவில்லை என்றால், உங்கள் மின்னஞ்சல் இன்பாக்ஸ் (மற்றும் ஸ்பேம் கோப்புறை) அல்லது உங்கள் SMS செய்திகளைச் சரிபார்க்கவும்.", "title": "Mercedes ME 2020 - டான்" } } }, "issues": { "restart_required": { "fix_flow": { "step": { "confirm_restart": { "description": "அங்கீகார புதுப்பிப்பை முடிக்க ஹோம் அசிஸ்டன்ட் மறுதொடக்கம் தேவை, இப்போது மறுதொடக்கம் செய்ய சமர்ப்பிக்கவும்.", "title": "மறுதொடக்கம் தேவை" } } }, "title": "மறுதொடக்கம் தேவை" } }, "options": { "abort": { "already_configured": "கூறு ஏற்கனவே கட்டமைக்கப்பட்டுள்ளது.", "reauth_successful": "மறுஅங்கீகாரம் வெற்றிகரமாக! கூறு மறுஏற்றம் முன்னேற்றத்தில்." }, "step": { "init": { "data": { "cap_check_disabled": "திறன்கள் சரிபார்ப்பை முடக்கு", "enable_china_gcj_02": "GCJ-02 மொழிபெயர்ப்பை இயக்கவும் (சீனா மட்டும்)", "delete_auth_file": "அங்கீகார டோக்கனை இப்போது நீக்கு. சேமித்த பிறகு ஹோம் அசிஸ்டன்ட் மறுதொடக்கம் தேவை.", "excluded_cars": "விலக்கப்பட்ட VIN கள் (கமா-பிரிப்பு)", "pin": "பாதுகாப்பு PIN (மொபைல் பயன்பாட்டில் உருவாக்கப்பட வேண்டும்)", "save_files": "பிழைத்திருத்தம் மட்டும்: சேவையக செய்திகளை செய்திகள் கோப்புறையில் சேமிக்கவும்", "overwrite_cap_precondnow": "சோதனை: precondnow திறனை மேலெழுதவும் (உண்மை என அமைக்கவும்)" }, "description": "உங்கள் விருப்பங்களை உள்ளமைக்கவும். சில மாற்றங்களுக்கு ஹோம் அசிஸ்டன்ட் மறுதொடக்கம் தேவைப்படுகிறது.", "title": "Mercedes ME 2020 விருப்பங்கள்" } } }, "system_health": { "info": { "api_endpoint_reachable": "MB API அடையக்கூடியது", "websocket_connection_state": "MB WS நிலை", "cars_connected": "இணைக்கப்பட்ட கார்கள்", "version": "பதிப்பு" } }, "services": { "refresh_access_token": { "name": "அணுகல் டோக்கனைப் புதுப்பிக்கவும்", "description": "API அணுகல் டோக்கனைப் புதுப்பிக்கவும்" }, "auxheat_configure": { "name": "துணை வெப்பமாக்கல் உள்ளமைவு", "description": "துணை வெப்பத்தை உள்ளமைப்பதற்கான கட்டளை. மூன்று பகல் நேரங்களை வரையறுத்து ஒரு செயலில் நேரத்தைத் தேர்ந்தெடுக்க முடியும்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "time_selection": { "name": "நேர தேர்வு", "description": "செயல்படுத்தப்பட்ட துணை வெப்பமாக்கல் முன்னமைக்கப்பட்ட நேரம் (0=தேர்வு_இல்லை, 1=நேரம்_1, 2=நேரம்_2, 3=நேரம்_3)" }, "time_1": { "name": "time_1", "description": "நள்ளிரவுக்குப் பிறகு நிமிடங்களில் பகல் நேரம். எ.கா. காலை 8 மணிக்கு செல்லுபடியாகும் மதிப்பு 480 ஆக இருக்கும். மதிப்பு வரம்பு 0 முதல் 1439 வரை." }, "time_2": { "name": "time_2", "description": "நள்ளிரவுக்குப் பிறகு நிமிடங்களில் பகல் நேரம். எ.கா. காலை 8 மணிக்கு செல்லுபடியாகும் மதிப்பு 480 ஆக இருக்கும். மதிப்பு வரம்பு 0 முதல் 1439 வரை." }, "time_3": { "name": "time_3", "description": "நள்ளிரவுக்குப் பிறகு நிமிடங்களில் பகல் நேரம். எ.கா. காலை 8 மணிக்கு செல்லுபடியாகும் மதிப்பு 480 ஆக இருக்கும். மதிப்பு வரம்பு 0 முதல் 1439 வரை." } } }, "auxheat_start": { "name": "துணை வெப்பமாக்கல் தொடக்கம்", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் துணை வெப்பத்தைத் தொடங்குங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "auxheat_stop": { "name": "துணை வெப்பமாக்கல் நிறுத்தம்", "description": "ஒரு வின் ஆல் வரையறுக்கப்பட்ட காரின் துணை வெப்பத்தை நிறுத்துங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "battery_max_soc_configure": { "name": "பேட்டரி அதிகபட்ச soc உள்ளமைவு", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் HV பேட்டரியின் சார்ஜ் நிலைக்கான அதிகபட்ச மதிப்பை உள்ளமைக்கவும்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "max_soc": { "name": "அதிகபட்ச soc", "description": "HV பேட்டரியின் சார்ஜ் நிலைக்கான அதிகபட்ச மதிப்பு (மதிப்பு 50 (2025 CLA போன்ற சில புதிய கார்கள் 30 ஐ ஆதரிக்கின்றன) முதல் 100 வரை இருக்க வேண்டும் மற்றும் பத்தால் வகுபடக்கூடியதாக இருக்க வேண்டும்)" }, "charge_program": { "name": "சார்ஜிங் நிரல்", "description": "(விரும்பினால், இயல்புநிலை=0) மாற்ற வேண்டிய சார்ஜ் நிரல் (0=இயல்புநிலை, 2=வீடு, 3=வேலை) (2025 CLA க்கு பயன்படுத்தப்படாது)" } } }, "charge_program_configure": { "name": "சார்ஜ் நிரல் உள்ளமைவு", "description": "சார்ஜ் நிரலைத் தேர்ந்தெடுக்க கட்டளை.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "charge_program": { "name": "சார்ஜிங் நிரல்", "description": "செயல்படுத்தப்பட்ட சார்ஜிங் நிரல் (0=இயல்புநிலை, 2=வீடு, 3=வேலை)" }, "max_soc": { "name": "அதிகபட்ச soc", "description": "எச்வி பேட்டரியின் சார்ஜ் நிலைக்கான அதிகபட்ச மதிப்பு (50 முதல் 100 வரை மதிப்பு இருக்க வேண்டும் மற்றும் பத்தால் வகுபடக்கூடியதாக இருக்க வேண்டும்)" } } }, "doors_unlock": { "name": "கதவுகள் திறப்பு", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரைத் திறக்கவும். PIN அமைப்பு தேவை. ஒருங்கிணைப்பின் விருப்பங்கள் உரையாடலைக் காண்க.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "pin": { "name": "பின்", "description": "பாதுகாப்பு பின், அமைப்புகளில் சேமிக்கப்படாவிட்டால் தேவை." } } }, "doors_lock": { "name": "கதவுகள் பூட்டு", "description": "ஒரு வின் ஆல் வரையறுக்கப்பட்ட காரைப் பூட்டவும்", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "download_images": { "name": "படங்களைப் பதிவிறக்கவும்", "description": "ஒரு வின் ஆல் வரையறுக்கப்பட்ட காருக்கான பயன்பாட்டு படங்களைக் கூறுகளின் வள கோப்புறையில் பதிவிறக்குகிறது.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "engine_start": { "name": "எஞ்சின் தொடக்கம்", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் இயந்திரத்தைத் தொடங்குங்கள். PIN அமைப்பு தேவை. ஒருங்கிணைப்பின் விருப்பங்கள் உரையாடலைக் காண்க.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "pin": { "name": "பின்", "description": "பாதுகாப்பு பின், அமைப்புகளில் சேமிக்கப்படாவிட்டால் தேவை." } } }, "engine_stop": { "name": "எஞ்சின் நிறுத்தம்", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் இயந்திரத்தை நிறுத்துங்கள். PIN அமைப்பு தேவை. ஒருங்கிணைப்பின் விருப்பங்கள் உரையாடலைக் காண்க.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "hv_battery_start_conditioning": { "name": "HV பேட்டரி கண்டிஷனிங் தொடக்கம்", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் HV பேட்டரி கண்டிஷனிங்கைத் தொடங்குங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "hv_battery_stop_conditioning": { "name": "HV பேட்டரி கண்டிஷனிங் நிறுத்தம்", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் HV பேட்டரி கண்டிஷனிங்கை நிறுத்துங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "preconditioning_configure_seats": { "name": "முன்நிபந்தனை இருக்கைகள் உள்ளமைவு", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காருக்கு முன்நிபந்தனை இருக்கை உள்ளமைவு கட்டளையை அனுப்பவும்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "front_left": { "name": "முன் இடது", "description": "முன் இடது இருக்கை முன்நிபந்தனை செய்யப்பட வேண்டும் என்றால் செயல்படுத்தவும்." }, "front_right": { "name": "முன் வலது", "description": "முன் வலது இருக்கை முன்நிபந்தனை செய்யப்பட வேண்டும் என்றால் செயல்படுத்தவும்." }, "rear_left": { "name": "பின்புற இடது", "description": "பின்புற இடது இருக்கை முன்நிபந்தனை செய்யப்பட வேண்டும் என்றால் செயல்படுத்தவும்." }, "rear_right": { "name": "பின்புற வலது", "description": "பின்புற வலது இருக்கை முன்நிபந்தனை செய்யப்பட வேண்டும் என்றால் செயல்படுத்தவும்." } } }, "preheat_start": { "name": "முன்நிபந்தனை தொடக்கம்", "description": "ஒரு வின் ஆல் வரையறுக்கப்பட்ட காரின் முன்நிபந்தனையைத் தொடங்குங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "type": { "name": "வகை", "description": "தொடக்க செயல்முறையைத் தொடங்கப் பயன்படும் முறை. 0=இப்போது (இயல்புநிலை), 1=உடனடி - உங்கள் கார் 'இப்போது' ஆதரிக்காவிட்டால் 'உடனடி' பயன்படுத்தவும்." } } }, "preheat_start_departure_time": { "name": "புறப்படும் நேரத்துடன் முன்நிபந்தனை தொடக்கம்", "description": "ஒரு வின் மற்றும் கொடுக்கப்பட்ட புறப்படும் நேரத்தால் வரையறுக்கப்பட்ட காரின் முன்நிபந்தனையைத் தொடங்குங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "time": { "name": "நேரம்", "description": "நள்ளிரவுக்குப் பிறகு நிமிடங்களில் புறப்படும் நேரம். எ.கா. காலை 8 மணிக்கு செல்லுபடியாகும் மதிப்பு 480 ஆக இருக்கும். மதிப்பு வரம்பு 0 முதல் 1439 வரை." } } }, "preheat_stop": { "name": "முன்நிபந்தனை நிறுத்தம்", "description": "ஒரு வின் ஆல் வரையறுக்கப்பட்ட காரின் முன்நிபந்தனையை நிறுத்துங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "preheat_stop_departure_time": { "name": "முன்நிபந்தனை நிறுத்த முறை புறப்படும் நேரம்", "description": "ஒரு வின் ஆல் வரையறுக்கப்பட்ட காரின் கட்டமைக்கப்பட்ட புறப்படும் நேர முன்நிபந்தனையை நிறுத்துங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "preconditioning_configure": { "name": "முன்நிபந்தனை புறப்படுதலை உள்ளமைக்கவும்", "description": "முன்நிபந்தனை புறப்படும் நேர முறையை உள்ளமைக்கவும். திட்டமிடப்பட்ட புறப்படுதல் முன்நிபந்தனையை ரத்து செய்ய முறை 0 (முடக்கப்பட்டது) பயன்படுத்தவும்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "departure_time_mode": { "name": "புறப்படும் நேர முறை", "description": "0=முடக்கப்பட்டது, 1=ஒற்றை புறப்படுதல், 2=வாராந்திர புறப்படுதல்" }, "departure_time": { "name": "புறப்படும் நேரம்", "description": "நள்ளிரவுக்குப் பிறகு நிமிடங்களில் புறப்படும் நேரம் (0-1439). முறை > 0 ஆக இருக்கும்போது மட்டும் பயன்படுத்தப்படும்." } } }, "sigpos_start": { "name": "சமிக்ஞை நிலை தொடக்கம்", "description": "ஒரு வின் ஆல் வரையறுக்கப்பட்ட காரின் ஒளி சமிக்ஞையைத் தொடங்குங்கள்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "sunroof_open": { "name": "சன்ரூஃப் திறப்பு", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் சன்ரூஃப்பைத் திறக்கவும். PIN அமைப்பு தேவை. ஒருங்கிணைப்பின் விருப்பங்கள் உரையாடலைக் காண்க.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "pin": { "name": "பின்", "description": "பாதுகாப்பு பின், அமைப்புகளில் சேமிக்கப்படாவிட்டால் தேவை." } } }, "sunroof_tilt": { "name": "சன்ரூஃப் சாய்வு", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் சன்ரூஃப்பை சாய்க்கவும். PIN அமைப்பு தேவை. ஒருங்கிணைப்பின் விருப்பங்கள் உரையாடலைக் காண்க.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "pin": { "name": "பின்", "description": "பாதுகாப்பு பின், அமைப்புகளில் சேமிக்கப்படாவிட்டால் தேவை." } } }, "sunroof_close": { "name": "சன்ரூஃப் மூடல்", "description": "ஒரு வின் ஆல் வரையறுக்கப்பட்ட காரின் சன்ரூஃப்பை மூடவும்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "temperature_configure": { "name": "இலக்கு வெப்பநிலை உள்ளமைவு (முன்நிபந்தனை/துணை வெப்பமாக்கல்)", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரில் மண்டலங்களுக்கான இலக்கு முன்நிபந்தனை/துணை வெப்பமாக்கல் வெப்பநிலையை உள்ளமைக்கவும்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "front_left": { "name": "முன் இடது", "description": "செல்சியசில் முன்_இடது மண்டலத்திற்கான இலக்கு வெப்பநிலை." }, "front_right": { "name": "முன் வலது", "description": "செல்சியசில் முன்_வலது மண்டலத்திற்கான இலக்கு வெப்பநிலை." }, "rear_left": { "name": "பின்புற இடது", "description": "செல்சியசில் பின்புற_இடது மண்டலத்திற்கான இலக்கு வெப்பநிலை. (கிடைத்தால்)" }, "rear_right": { "name": "பின்புற வலது", "description": "செல்சியசில் பின்புற_வலது மண்டலத்திற்கான இலக்கு வெப்பநிலை. (கிடைத்தால்)" } } }, "windows_open": { "name": "சாளரங்கள் திறப்பு", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் சாளரங்களைத் திறக்கவும். PIN அமைப்பு தேவை. ஒருங்கிணைப்பின் விருப்பங்கள் உரையாடலைக் காண்க.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "pin": { "name": "பின்", "description": "பாதுகாப்பு பின், அமைப்புகளில் சேமிக்கப்படாவிட்டால் தேவை." } } }, "windows_close": { "name": "சாளரங்கள் மூடல்", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் சாளரங்களை மூடவும். PIN அமைப்பு தேவை. ஒருங்கிணைப்பின் விருப்பங்கள் உரையாடலைக் காண்க.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" } } }, "windows_move": { "name": "சாளரங்கள் நகர்வு", "description": "ஒரு VIN ஆல் வரையறுக்கப்பட்ட காரின் சாளரங்களை புதிய நிலைக்கு நகர்த்தவும். PIN அமைப்பு தேவை. ஒருங்கிணைப்பின் விருப்பங்கள் உரையாடலைக் காண்க.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "pin": { "name": "பின்", "description": "பாதுகாப்பு பின், அமைப்புகளில் சேமிக்கப்படாவிட்டால் தேவை." }, "front_left": { "name": "முன் இடது", "description": "முன் இடது சாளரத்தின் புதிய நிலை (0=மூடியது, 10=காற்றோட்டம், 100=திறந்தது)" }, "front_right": { "name": "முன் வலது", "description": "முன் இடது சாளரத்தின் புதிய நிலை (0=மூடியது, 10=காற்றோட்டம், 100=திறந்தது)" }, "rear_left": { "name": "பின்புற இடது", "description": "முன் இடது சாளரத்தின் புதிய நிலை (0=மூடியது, 10=காற்றோட்டம், 100=திறந்தது)" }, "rear_right": { "name": "பின்புற வலது", "description": "முன் இடது சாளரத்தின் புதிய நிலை (0=மூடியது, 10=காற்றோட்டம், 100=திறந்தது)" } } }, "send_route": { "name": "வழி அனுப்பு", "description": "காருக்கு ஒரு வழியை அனுப்புகிறது. (ஒற்றை இடம் மட்டும்)", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "title": { "name": "தலைப்பு", "description": "வழியின் தலைப்பு" }, "latitude": { "name": "அகலாங்கு", "description": "இருப்பிடத்தின் அட்சரேகை" }, "longitude": { "name": "நெட்டாங்கு", "description": "இருப்பிடத்தின் தீர்க்கரேகை" }, "city": { "name": "நகரம்", "description": "இருப்பிடத்தின் நகரப் பெயர்" }, "postcode": { "name": "அஞ்சல் குறியீடு", "description": "இருப்பிடத்தின் அஞ்சல் குறியீடு" }, "street": { "name": "தெரு", "description": "இருப்பிடத்தின் தெருப் பெயர்" } } }, "charging_break_clocktimer_configure": { "name": "சார்ஜிங் இடைவெளி கடிகார நேரமிடல் உள்ளமைவு", "description": "சார்ஜிங் இடைவெளிகளை உள்ளமைக்கவும் (AC மட்டும்). இது உங்கள் காரில் உள்ள அனைத்து இடங்களுக்கும் முழுமையான உள்ளமைவை மேலெழுதும்.", "fields": { "vin": { "name": "வின்", "description": "காரின் வின்/ஃபின்" }, "status_timer_1": { "name": "நிலை (டைமர் 1)", "description": "Services.charging_break_clocktimer_configure.fields.status_timer_1.விளக்கம்" }, "starttime_timer_1": { "name": "தொடக்க நேரம் (டைமர் 1)", "description": "சார்ஜ் இடைவெளி சாளரத்தின் தொடக்க நேரம் (டைமர் 1)" }, "stoptime_timer_1": { "name": "இறுதி நேரம் (டைமர் 1)", "description": "சார்ஜ் இடைவெளி சாளரத்தின் இறுதி நேரம் (டைமர் 1)" }, "status_timer_2": { "name": "நிலை (டைமர் 2)", "description": "Services.charging_break_clocktimer_configure.fields.status_timer_2.description" }, "starttime_timer_2": { "name": "தொடக்க நேரம் (டைமர் 2)", "description": "சார்ஜ் இடைவெளி சாளரத்தின் தொடக்க நேரம் (டைமர் 2)" }, "stoptime_timer_2": { "name": "இறுதி நேரம் (டைமர் 2)", "description": "சார்ஜ் இடைவெளி சாளரத்தின் இறுதி நேரம் (டைமர் 2)" }, "status_timer_3": { "name": "நிலை (டைமர் 3)", "description": "services.charging_break_clocktimer_configure.fields.status_timer_3.description" }, "starttime_timer_3": { "name": "தொடக்க நேரம் (டைமர் 3)", "description": "சார்ஜ் இடைவெளி சாளரத்தின் தொடக்க நேரம் (டைமர் 3)" }, "stoptime_timer_3": { "name": "இறுதி நேரம் (டைமர் 3)", "description": "சார்ஜ் இடைவெளி சாளரத்தின் இறுதி நேரம் (டைமர் 3)" }, "status_timer_4": { "name": "நிலை (டைமர் 4)", "description": "services.charging_break_clocktimer_configure.fields.status_timer_4.description" }, "starttime_timer_4": { "name": "தொடக்க நேரம் (டைமர் 4)", "description": "சார்ஜ் இடைவெளி சாளரத்தின் தொடக்க நேரம் (டைமர் 4)" }, "stoptime_timer_4": { "name": "இறுதி நேரம் (டைமர் 4)", "description": "சார்ஜ் இடைவெளி சாளரத்தின் இறுதி நேரம் (டைமர் 4)" } } } }, "entity": { "binary_sensor": { "chargingactive": { "name": "சார்ஜிங் செயலில்" } }, "sensor": { "chargingpowerecolimit": { "name": "சார்ஜிங் சக்தி வரம்பு" }, "auxheatstatus": { "state": { "0": "செயலற்றது", "1": "இயல்பான வெப்பமாக்கல்", "2": "இயல்பான காற்றோட்டம்", "3": "கையேடு வெப்பமாக்கல்", "4": "பிந்தைய வெப்பமாக்கல்", "5": "பிந்தைய காற்றோட்டம்", "6": "தானியங்கி வெப்பமாக்கல்" } }, "chargeflapacstatus": { "state": { "0": "திறந்தது", "1": "மூடியது", "2": "மடல் அழுத்தப்பட்டது", "3": "தெரியவில்லை" } }, "chargeflapdcstatus": { "state": { "0": "திறந்தது", "1": "மூடியது", "2": "மடல் அழுத்தப்பட்டது", "3": "தெரியவில்லை" } }, "chargingstatus": { "state": { "0": "சார்ஜிங்", "1": "சார்ஜிங் முடிகிறது", "2": "சார்ஜ் இடைவெளி", "3": "துண்டிக்கப்பட்டது", "4": "தோல்வி", "5": "மெதுவான", "6": "வேகமான", "7": "டிஸ்சார்ஜிங்", "8": "சார்ஜ் ஆகவில்லை", "9": "பயண இலக்கை அடைந்த பின் மெதுவான சார்ஜிங்", "10": "பயண இலக்கை அடைந்த பின் சார்ஜிங்", "11": "பயண இலக்கை அடைந்த பின் வேகமான சார்ஜிங்", "12": "இணைக்கப்பட்டது", "13": "AC சார்ஜிங்", "14": "DC சார்ஜிங்", "15": "பேட்டரி அளவுத்திருத்தம் செயலில்", "16": "தெரியவில்லை" } }, "departuretimemode": { "state": { "0": "முடக்கப்பட்டது", "1": "நாள்தோறும்", "2": "வாராந்திர" } }, "ignitionstate": { "state": { "0": "பூட்டப்பட்டது", "1": "அணைக்கப்பட்டது", "2": "துணை", "4": "இயக்கத்தில்", "5": "தொடக்கம்" } }, "interiorprotectionsensorstatus": { "state": { "0": "செயலில் இல்லை", "1": "செயலில் இல்லை", "2": "செயலில்" } }, "lock": { "state": { "0": "திறக்கப்பட்டது", "1": "உள்பூட்டப்பட்டது", "2": "பூட்டப்பட்டது", "3": "ஓரளவு திறக்கப்பட்டது", "4": "தெரியவில்லை" }, "state_attributes": { "decklidstatus": { "name": "டெக் மூடி", "state": { "false": "மூடியது", "true": "திறந்தது" } }, "doorstatusfrontleft": { "name": "கதவு முன் இடது", "state": { "false": "மூடியது", "true": "திறந்தது" } }, "doorstatusfrontright": { "name": "கதவு முன் வலது", "state": { "false": "மூடியது", "true": "திறந்தது" } }, "doorstatusrearleft": { "name": "கதவு பின்புற இடது", "state": { "false": "மூடியது", "true": "திறந்தது" } }, "doorstatusrearright": { "name": "கதவு பின்புற வலது", "state": { "false": "மூடியது", "true": "திறந்தது" } }, "doorlockstatusfrontleft": { "name": "கதவு பூட்டு முன் இடது", "state": { "false": "பூட்டப்பட்டது", "true": "திறக்கப்பட்டது" } }, "doorlockstatusfrontright": { "name": "கதவு பூட்டு முன் வலது", "state": { "false": "பூட்டப்பட்டது", "true": "திறக்கப்பட்டது" } }, "doorlockstatusrearleft": { "name": "கதவு பூட்டு பின்புற இடது", "state": { "false": "பூட்டப்பட்டது", "true": "திறக்கப்பட்டது" } }, "doorlockstatusrearright": { "name": "கதவு பூட்டு பின்புற வலது", "state": { "false": "பூட்டப்பட்டது", "true": "திறக்கப்பட்டது" } }, "doorlockstatusgas": { "name": "எரிவாயு பூட்டு", "state": { "false": "பூட்டப்பட்டது", "true": "திறக்கப்பட்டது" } }, "enginehoodstatus": { "name": "எஞ்சின் ஹுட்", "state": { "false": "மூடியது", "true": "திறந்தது" } }, "doorstatusoverall": { "name": "ஒட்டுமொத்த கதவு நிலை", "state": { "0": "திறந்தது", "1": "மூடியது", "2": "இல்லாதது", "3": "தெரியவில்லை" } }, "sunroofstatus": { "name": "சன்ரூஃப் நிலை", "state": { "0": "மூடியது", "1": "திறந்தது", "2": "உயர்த்தி திறப்பு", "3": "இயங்குகிறது", "4": "அதிர்வு எதிர்ப்பு நிலை", "5": "நழுவும் இடைநிலை", "6": "உயர்த்தும் இடைநிலை", "7": "திறக்கிறது", "8": "மூடுகிறது", "9": "அதிர்வு எதிர்ப்பு உயர்த்துதல்", "10": "இடைநிலை நிலை", "11": "உயர்த்தி திறக்கிறது", "12": "உயர்த்தி மூடுகிறது" } } } }, "sunroofstatus": { "state": { "0": "மூடியது", "1": "திறந்தது", "2": "உயர்த்தி திறப்பு", "3": "இயங்குகிறது", "4": "அதிர்வு எதிர்ப்பு", "5": "நழுவும் இடைநிலை", "6": "உயர்த்தும் இடைநிலை", "7": "திறக்கிறது", "8": "மூடுகிறது", "9": "அதிர்வு எதிர்ப்பு உயர்த்துதல்", "10": "இடைநிலை நிலை", "11": "உயர்த்தி திறக்கிறது", "12": "உயர்த்தி மூடுகிறது" } }, "starterbatterystate": { "state": { "0": "பச்சை", "1": "மஞ்சள்", "2": "சிவப்பு" } }, "tirewarningsrdk": { "state": { "0": "எச்சரிக்கை இல்லை", "1": "மென்மையான எச்சரிக்கை", "2": "குறைந்த அழுத்தம்", "3": "காற்றிழப்பு" } }, "selectedchargeprogram": { "state": { "0": "நிலையான", "2": "வீடு", "3": "வேலை", "4": "ஆதரிக்கப்படவில்லை" } } }, "switch": { "auxheat": { "name": "துணை வெப்பமாக்கல்" }, "precond": { "name": "முன் நுழைவு காலநிலை கட்டுப்பாடு" } }, "button": { "btn_preheat_start_now": { "name": "முன்வெப்பமாக்கல் தொடக்கம்" }, "btn_preheat_stop_now": { "name": "முன்வெப்பமாக்கல் நிறுத்தம்" }, "btn_sigpos_start_now": { "name": "விளக்குகள் ஒளிர்தல்" } } }, "selector": { "charge_program": { "options": { "0": "இயல்புநிலை", "2": "வீடு", "3": "வேலை" } }, "charging_break_clocktimer_configure_action": { "options": { "notset": "அமைக்கப்படவில்லை", "active": "செயலில்", "inactive": "செயலற்றது" } }, "temperature_configure": { "options": { "0": "குறைந்த", "30": "உயர்ந்த" } } } } ================================================ FILE: custom_components/mbapi2020/webapi.py ================================================ """Define an object to interact with the REST API.""" from __future__ import annotations import json import logging import ssl import traceback import uuid from aiohttp import ClientSession from aiohttp.client_exceptions import ClientError import google.protobuf.message from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import ( REGION_CHINA, RIS_APPLICATION_VERSION, RIS_OS_VERSION, RIS_SDK_VERSION, SYSTEM_PROXY, VERIFY_SSL, WEBSOCKET_USER_AGENT, WEBSOCKET_USER_AGENT_CN, X_APPLICATIONNAME, ) from .helper import UrlHelper as helper from .oauth import Oauth from .proto import vehicle_events_pb2 LOGGER = logging.getLogger(__name__) class WebApi: """Define the API object.""" def __init__( self, hass: HomeAssistant, oauth: Oauth, session: ClientSession, region: str, ) -> None: """Initialize.""" self._session: ClientSession = session self._oauth: Oauth = oauth self._region = region self.hass = hass self.session_id = str(uuid.uuid4()).upper() async def _request( self, method: str, endpoint: str, rcp_headers: bool = False, ignore_errors: bool = False, return_as_json: bool = True, **kwargs, ): """Make a request against the API.""" url = f"{helper.Rest_url(self._region)}{endpoint}" kwargs.setdefault("headers", {}) kwargs.setdefault("proxy", SYSTEM_PROXY) token = await self._oauth.async_get_cached_token() if not rcp_headers: kwargs["headers"] = { "Authorization": f"Bearer {token['access_token']}", "X-SessionId": self.session_id, "X-TrackingId": str(uuid.uuid4()).upper(), "X-ApplicationName": X_APPLICATIONNAME, "ris-application-version": RIS_APPLICATION_VERSION, "ris-os-name": "ios", "ris-os-version": RIS_OS_VERSION, "ris-sdk-version": RIS_SDK_VERSION, "X-Locale": "de-DE", "User-Agent": WEBSOCKET_USER_AGENT, "Content-Type": "application/json; charset=UTF-8", } else: kwargs["headers"] = { "Authorization": f"Bearer {token['access_token']}", "User-Agent": WEBSOCKET_USER_AGENT, "Accept-Language": "de-DE;q=1.0, en-DE;q=0.9", } if not self._session or self._session.closed: self._session = async_get_clientsession(self.hass, VERIFY_SSL) try: if "url" in kwargs: async with self._session.request(method, **kwargs) as resp: # resp.raise_for_status() if return_as_json: return await resp.json(content_type=None) return await resp.read() else: async with self._session.request(method, url, **kwargs) as resp: if 400 <= resp.status < 500: try: error = await resp.text() error_json = json.loads(error) if error_json: error_message = f"Error requesting: {url} - {resp.status} - {error_json['code']} - {error_json['errors']}" else: error_message = f"Error requesting: {url} - {resp.status} - 0 - {error}" except (json.JSONDecodeError, KeyError): error_message = f"Error requesting: {url} - {resp.status} - 0 - {error}" LOGGER.error(error_message) if not ignore_errors else LOGGER.info(error_message) else: resp.raise_for_status() if return_as_json: return await resp.json(content_type=None) return await resp.read() except ClientError as err: LOGGER.debug(traceback.format_exc()) if not ignore_errors: raise ClientError from err return [] except Exception: LOGGER.debug(traceback.format_exc()) async def get_config(self): """Get standard user information.""" return await self._request("get", "/v1/config") async def get_user(self): """Get standard user information.""" return await self._request("get", "/v1/user") async def get_user_info(self): """Get all devices associated with an API key.""" return await self._request("get", "/v2/vehicles") async def get_car_capabilities(self, vin: str): """Get all car capabilities associated with an vin.""" return await self._request("get", f"/v1/vehicle/{vin}/capabilities") async def get_car_capabilities_commands(self, vin: str): """Get all car capabilities associated with an vin.""" return await self._request("get", f"/v1/vehicle/{vin}/capabilities/commands") async def get_car_rcp_supported_settings(self, vin: str): """Get all supported car rcp options associated.""" url = f"{helper.RCP_url(self._region)}/api/v1/vehicles/{vin}/settings" LOGGER.debug("get_car_rcp_supported_settings: %s", url) return await self._request("get", "", url=url, rcp_headers=True) async def get_car_rcp_settings(self, vin: str, setting: str): """Get all rcp setting for a car.""" url = f"{helper.RCP_url(self._region)}/api/v1/vehicles/{vin}/settings/{setting}" LOGGER.debug("get_car_rcp_settings: %s", url) return await self._request("get", "", url=url, rcp_headers=True) async def send_route_to_car( self, vin: str, title: str, latitude: float, longitude: float, city: str, postcode: str, street: str, ): """Send route to car associated by vin.""" data = { "routeTitle": title, "routeType": "singlePOI", "waypoints": [ { "city": city, "latitude": latitude, "longitude": longitude, "postalCode": postcode, "street": street, "title": title, } ], } return await self._request("post", f"/v1/vehicle/{vin}/route", data=json.dumps(data)) async def get_car_geofencing_violations(self, vin: str): """Get all geofencing violations for a car.""" url = f"/v1/geofencing/vehicles/{vin}/fences/violations" return await self._request("get", url, rcp_headers=False, ignore_errors=True) async def get_fleet_info(self, company: str, fleet: str): """Get fleet information.""" url = f"/v1/company/{company}/fleet/{fleet}?size=100&filter=" return await self._request("get", url, rcp_headers=False, ignore_errors=True) async def is_car_rcp_supported(self, vin: str, **kwargs): """Return if is car rcp supported.""" token = await self._oauth.async_get_cached_token() headers = { "Authorization": f"Bearer {token['access_token']}", "User-Agent": WEBSOCKET_USER_AGENT if self._region != REGION_CHINA else WEBSOCKET_USER_AGENT_CN, } kwargs.setdefault("headers", headers) kwargs.setdefault("proxy", SYSTEM_PROXY) url = f"{helper.PSAG_url(self._region)}/api/app/v2/vehicles/{vin}/profileInformation" if not self._session or self._session.closed: self._session = async_get_clientsession(self.hass, VERIFY_SSL) async with self._session.request("get", url, **kwargs) as resp: resp_status = resp.status await resp.text() return bool(resp_status == 200) async def download_images(self, vin: str): """Download the car images and store it to the components ressource folder.""" url = f"/v1/vehicle/{vin}/topviewimage" return await self._request("get", url, rcp_headers=False, ignore_errors=False, return_as_json=False) async def get_car_p2b_data_via_rest(self, vin: str): """Get vehicleattributes via rest.""" url = f"{helper.Widget_url(self._region)}/v1/vehicle/{vin}/vehicleattributes" try: data = await self._request("get", "", url=url, return_as_json=False) message = vehicle_events_pb2.VEPUpdate() message.ParseFromString(data) except TypeError as err: LOGGER.error("could not decode data (%s) from websocket: %s", data, err) except google.protobuf.message.DecodeError as err: LOGGER.error("could not decode data (%s) from websocket: %s", data, err) return message if message else None ================================================ FILE: custom_components/mbapi2020/websocket.py ================================================ """Define an object to interact with the Websocket API.""" from __future__ import annotations import asyncio from collections.abc import Awaitable, Callable import contextlib # NEW from datetime import datetime, timezone import logging import time import uuid from aiohttp import ClientSession, WSMsgType, WSServerHandshakeError, client_exceptions from homeassistant.const import EVENT_HOMEASSISTANT_STOP from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import ( REGION_APAC, REGION_CHINA, REGION_EUROPE, REGION_NORAM, RIS_APPLICATION_VERSION, RIS_APPLICATION_VERSION_CN, RIS_APPLICATION_VERSION_NA, RIS_APPLICATION_VERSION_PA, RIS_OS_NAME, RIS_OS_VERSION, RIS_SDK_VERSION, RIS_SDK_VERSION_CN, SYSTEM_PROXY, VERIFY_SSL, WEBSOCKET_USER_AGENT, WEBSOCKET_USER_AGENT_CN, WEBSOCKET_USER_AGENT_PA, WEBSOCKET_USER_AGENT_US, ) from .helper import LogHelper as loghelper, UrlHelper as helper, Watchdog from .oauth import Oauth from .proto import vehicle_events_pb2 DEFAULT_WATCHDOG_TIMEOUT = 30 DEFAULT_WATCHDOG_TIMEOUT_CARCOMMAND = 180 INITIAL_WATCHDOG_TIMEOUT = 30 PING_WATCHDOG_TIMEOUT = 32 RECONNECT_WATCHDOG_TIMEOUT = 60 STATE_CONNECTED = "connected" STATE_RECONNECTING = "reconnecting" INITIATE_RELOGIN_AFTER_429 = True MAX_RELOGIN_ATTEMPTS = 3 LOGGER = logging.getLogger(__name__) class _PrefixAdapter(logging.LoggerAdapter): """Logger adapter that prefixes messages with config entry and instance ID.""" def process(self, msg, kwargs): """Prepend entry_id and instance_id to log message.""" return f"[{self.extra['entry_id']}][inst#{self.extra['instance_id']}] {msg}", kwargs class Websocket: """Define the websocket.""" _instance_counter: int = 0 def __init__( self, hass, oauth, region, session_id=str(uuid.uuid4()).upper(), ignition_states: dict[str, bool] | None = None ) -> None: """Initialize.""" Websocket._instance_counter += 1 self._instance_id = Websocket._instance_counter if ignition_states is None: ignition_states = {} self.oauth: Oauth = oauth self._hass: HomeAssistant = hass self.is_stopping: bool = False self._on_data_received: Callable[..., Awaitable] = None self._connection = None self._region = region self.connection_state = "unknown" self.is_connecting = False self.ha_stop_handler = None self._watchdog: Watchdog = Watchdog( self.initiatiate_connection_disconnect_with_reconnect, topic="Connection", timeout_seconds=INITIAL_WATCHDOG_TIMEOUT, log_events=True, ) self._pingwatchdog: Watchdog = Watchdog( self.ping, topic="Ping", timeout_seconds=PING_WATCHDOG_TIMEOUT, log_events=False ) self._reconnectwatchdog: Watchdog = Watchdog( self._reconnect_attempt, topic="Reconnect", timeout_seconds=RECONNECT_WATCHDOG_TIMEOUT, log_events=True ) self.component_reload_watcher: Watchdog = Watchdog( self._blocked_account_reload_check, 30, "Blocked_account_reload", False ) if getattr(self.oauth, "_config_entry", None): self._LOGGER = _PrefixAdapter( LOGGER, {"entry_id": self.oauth._config_entry.entry_id, "instance_id": self._instance_id} ) else: self._LOGGER = _PrefixAdapter(LOGGER, {"entry_id": "unknown", "instance_id": self._instance_id}) self._LOGGER.info( "Websocket instance created (total instances created: %d, obj_id: %s)", Websocket._instance_counter, id(self), ) self._queue = asyncio.Queue() self._queue_shutdown_sentinel = object() # Sentinel für graceful shutdown self.session_id = session_id self._ignition_states: dict[str, bool] = ignition_states self.ws_connect_retry_counter_reseted: bool = False self.ws_connect_retry_counter: int = 0 self.account_blocked: bool = False self.ws_blocked_connection_error_logged = False self._connection_start_time: float | None = None self._initial_timeout_used: bool = False self._queue_task: asyncio.Task = None self._websocket_task: asyncio.Task = None self._relogin_429_attempts: int = 0 self._async_stop_call_count: int = 0 self._connect_internal_active_count: int = 0 self._blocked_since_time: float | None = None self._last_backup_reload_time: float | None = None async def _reconnect_attempt(self) -> None: """Attempt reconnection without cancelling the reconnect watchdog.""" self._LOGGER.debug("Starting reconnect attempt") try: await self._async_connect_internal() except Exception as err: self._LOGGER.error("Reconnect attempt failed: %s (%s)", err, type(err).__name__) finally: # Re-trigger reconnect watchdog if not stopping and not connected if not self.is_stopping and self.connection_state != STATE_CONNECTED: self._LOGGER.debug("Re-triggering reconnect watchdog after failed attempt") await self._reconnectwatchdog.trigger() async def async_connect(self, on_data=None) -> None: """Connect to the socket.""" # Cancel reconnect watchdog for manual connections self._reconnectwatchdog.cancel(graceful=True) await self._async_connect_internal(on_data) async def _async_connect_internal(self, on_data=None) -> None: """Internal connect method without cancelling reconnect watchdog.""" if self.is_connecting: return self._connect_internal_active_count += 1 self._LOGGER.debug( "_async_connect_internal ENTER (active_count: %d, queue_task: %s, ws_task: %s)", self._connect_internal_active_count, self._queue_task.get_name() if self._queue_task and not self._queue_task.done() else "None/done", self._websocket_task.get_name() if self._websocket_task and not self._websocket_task.done() else "None/done", ) async def _async_stop_handler(event): """Stop when Home Assistant is shutting down.""" await self.async_stop() if on_data: self._on_data_received = on_data self.is_connecting = True self.is_stopping = False if not self.ha_stop_handler: # NICHT sofort aufrufen – Rückruf behalten, nicht deregistrieren self.ha_stop_handler = self._hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _async_stop_handler) session = async_get_clientsession(self._hass, VERIFY_SSL) # Tasks erstellen und verwalten self._queue_task = asyncio.create_task(self._start_queue_handler(), name="mbapi2020.queue") self._websocket_task = asyncio.create_task(self._start_websocket_handler(session), name="mbapi2020.ws") # Warten, dass Tasks laufen - mit ordnungsgemäßer Exception-Behandlung try: await asyncio.gather(self._queue_task, self._websocket_task, return_exceptions=True) except Exception as e: self._LOGGER.debug("async_connect tasks finished with exception: %s", e) finally: self._connect_internal_active_count -= 1 self._LOGGER.debug( "_async_connect_internal EXIT (remaining active: %d)", self._connect_internal_active_count ) # Sicherstellen, dass Tasks ordnungsgemäß beendet werden await self._cleanup_tasks() async def async_stop(self, now: datetime = datetime.now()): """Close connection.""" self._async_stop_call_count += 1 self._LOGGER.debug( "async_stop called (call #%d, is_stopping_already: %s)", self._async_stop_call_count, self.is_stopping ) self.is_stopping = True # Watchdogs anhalten (graceful: laufenden expire-Task nicht killen) self._pingwatchdog.cancel(graceful=True) self._reconnectwatchdog.cancel(graceful=True) self._watchdog.cancel(graceful=True) # Dann WebSocket-Verbindung ordentlich schließen (gegen Cancel geschützt) if self._connection is not None and not self._connection.closed: try: self._LOGGER.debug("Closing WebSocket connection...") await asyncio.shield( asyncio.wait_for( self._connection.close(code=1000, message=b"Client shutdown"), timeout=1.0, ) ) self._LOGGER.debug("ws.close awaited (handshake done)") except asyncio.TimeoutError: self._LOGGER.warning("WebSocket close() timed out (no server CLOSE). Proceeding with shutdown.") except asyncio.CancelledError: # Beim Shutdown nicht re-raisen self._LOGGER.error("WebSocket close() was cancelled by outer task; ignoring during shutdown.") except Exception as e: self._LOGGER.debug("Error closing WebSocket connection: %s", e) # Zustände zurücksetzen self._watchdog.cancel(graceful=True) self.connection_state = "closed" self._connection_start_time = None self._initial_timeout_used = False # Queue-Handler zum Beenden signalisieren try: self._queue.put_nowait(self._queue_shutdown_sentinel) except asyncio.QueueFull: self._LOGGER.warning("Queue full during shutdown, forcing queue cleanup") await self._cleanup_queue("async_stop:queue_full") # Tasks ordnungsgemäß beenden (shield + kleine Timeouts) await self._await_tasks_then_cleanup() async def initiatiate_connection_disconnect_with_reconnect(self): """Initiate a connection disconnect.""" if any(self._ignition_states.values()): self._LOGGER.debug( "initiatiate_connection_disconnect_with_reconnect canceled - Reason: ignitions_state: %s", [loghelper.Mask_VIN(key) for key, value in self._ignition_states.items() if value], ) await self._watchdog.trigger() return # Verhindere Reentrancy: weitere Trigger sofort unterbinden, aber laufenden Task nicht killen self.is_stopping = True loop = asyncio.get_running_loop() self._watchdog.cancel(graceful=True) self._reconnectwatchdog.cancel(graceful=True) # Graceful shutdown in separatem Task ausführen, um Self-Cancel zu vermeiden loop.create_task(self._graceful_shutdown_and_optionally_reconnect(), name="mbapi2020.shutdown") async def _graceful_shutdown_and_optionally_reconnect(self): try: await self.async_stop() finally: # Wenn direkt ein Reconnect gewollt ist, hier starten: await self._reconnectwatchdog.trigger() async def ping(self): """Send a ping to the MB websocket servers.""" if self.is_stopping: return try: await self._connection.ping() await self._pingwatchdog.trigger() except (client_exceptions.ClientError, ConnectionResetError): await self._pingwatchdog.trigger() async def call(self, message, car_command: bool = False): """Send a message to the MB websocket servers.""" if self.is_stopping: return try: reconnect_task = None if not self._connection or self._connection.closed: reconnect_task = asyncio.create_task(self.async_connect()) if car_command: self._set_watchdog_timeout(DEFAULT_WATCHDOG_TIMEOUT_CARCOMMAND) await self._watchdog.trigger() if reconnect_task: for _ in range(50): if self._connection and not self._connection.closed: break await asyncio.sleep(0.1) await self._connection.send_bytes(message) except client_exceptions.ClientError as err: raise HomeAssistantError( "MB-Websocket connection is not active. Can't execute the call. Check the homeassistant.log for more details Error: %s", err, ) from err async def _start_queue_handler(self): """Start the queue handler - entry point for the task.""" await self._queue_handler() async def _queue_handler(self): while not self.is_stopping: try: # Timeout für graceful shutdown data = await asyncio.wait_for(self._queue.get(), timeout=1.0) # Check for shutdown sentinel if data is self._queue_shutdown_sentinel: self._LOGGER.debug("Queue handler received shutdown signal") self._queue.task_done() break try: message = vehicle_events_pb2.PushMessage() message.ParseFromString(data) except TypeError as err: self._LOGGER.error("could not decode data (%s) from websocket: %s", data, err) self._queue.task_done() continue if message is None: self._queue.task_done() continue self._LOGGER.debug("Got notification: %s", message.WhichOneof("msg")) try: ack_message = self._on_data_received(message) if ack_message: if isinstance(ack_message, str): await self.call(bytes.fromhex(ack_message)) else: await self.call(ack_message.SerializeToString()) except Exception as err: self._LOGGER.error("Error processing queue message: %s", err) self._queue.task_done() except asyncio.TimeoutError: # Timeout ist normal - weiter prüfen ob stopping continue except asyncio.CancelledError: self._LOGGER.debug("Queue handler cancelled") break except Exception as err: self._LOGGER.error("Unexpected error in queue handler: %s", err) break self._LOGGER.debug("Queue handler stopped") async def _start_websocket_handler(self, session: ClientSession): retry_in: int = 10 self._LOGGER.debug( "_start_websocket_handler (is_stopping: %s, session.closed: %s)", self.is_stopping, session.closed, ) while not self.is_stopping and not session.closed: try: await self.component_reload_watcher.trigger() await self._websocket_handler(session) except client_exceptions.ClientConnectionError as cce: # noqa: PERF203 self._LOGGER.error("Could not connect: %s, retry in %s seconds...", cce, retry_in) self._LOGGER.debug(cce) self.connection_state = STATE_RECONNECTING await asyncio.sleep(retry_in) retry_in = retry_in * 2 if retry_in < 120 else 120 self.ws_connect_retry_counter += 1 except ConnectionResetError as cce: self._LOGGER.info("Connection reseted: %s, retry in %s seconds...", cce, retry_in) self._LOGGER.debug(cce) self.connection_state = STATE_RECONNECTING await asyncio.sleep(retry_in) retry_in = retry_in * 2 if retry_in < 120 else 120 self.ws_connect_retry_counter += 1 except WSServerHandshakeError as error: if not self.ws_blocked_connection_error_logged: self._LOGGER.info( "MB-API access blocked. (First Message, expect a re-login) %s, retry in %s seconds...", error, retry_in, ) self.ws_blocked_connection_error_logged = True else: self._LOGGER.warning("WSS Connection blocked: %s, retry in %s seconds...", error, retry_in) if "429" in str(error.code): self.account_blocked = True # Setze Zeitstempel für Backup-Reload if self._blocked_since_time is None: self._blocked_since_time = time.time() if INITIATE_RELOGIN_AFTER_429 and self._relogin_429_attempts < MAX_RELOGIN_ATTEMPTS: config_entry = getattr(self.oauth, "_config_entry", None) if config_entry and "password" in config_entry.data: password = config_entry.data["password"] username = config_entry.data.get("username").strip() region = config_entry.data.get("region") if username and password and hasattr(self.oauth, "async_login_new"): self._LOGGER.info("429 detected: Trying relogin with stored password") try: token_info = await self.oauth.async_login_new(username, password) self._LOGGER.info("Relogin successful after 429") self._relogin_429_attempts = MAX_RELOGIN_ATTEMPTS except Exception as relogin_err: self._relogin_429_attempts += 1 self._LOGGER.error( "Relogin after 429 failed (attempt %d/%d): %s", self._relogin_429_attempts, MAX_RELOGIN_ATTEMPTS, relogin_err, ) self.ws_connect_retry_counter += 1 self.connection_state = STATE_RECONNECTING await asyncio.sleep(retry_in) retry_in = 10 * self.ws_connect_retry_counter * self.ws_connect_retry_counter except Exception as error: self._LOGGER.error("Other error: %s (%s)", error, type(error).__name__) self.connection_state = STATE_RECONNECTING await asyncio.sleep(retry_in) retry_in = retry_in * 2 if retry_in < 120 else 120 self.ws_connect_retry_counter += 1 async def _websocket_handler(self, session: ClientSession, **kwargs): websocket_url = helper.Websocket_url(self._region) kwargs.setdefault("proxy", SYSTEM_PROXY) kwargs.setdefault("headers", await self._websocket_connection_headers()) self.is_connecting = True self._LOGGER.debug("Connecting to %s", websocket_url) self._connection = await session.ws_connect(websocket_url, **kwargs) self._LOGGER.debug("Connected to mercedes websocket at %s", websocket_url) # Always reset to initial timeout for each new connection (including reconnects) self._connection_start_time = asyncio.get_running_loop().time() self._initial_timeout_used = True self._watchdog.timeout = INITIAL_WATCHDOG_TIMEOUT await self._watchdog.trigger() while not self._connection.closed: if self.is_stopping: break self.is_connecting = False self.connection_state = STATE_CONNECTED # Reset blocked timestamp wenn Verbindung erfolgreich ist if self._blocked_since_time is not None: self._blocked_since_time = None self._relogin_429_attempts = 0 msg = await self._connection.receive() # Wichtig: alle Close-Varianten sauber behandeln if msg.type in (WSMsgType.CLOSE, WSMsgType.CLOSING, WSMsgType.CLOSED): self._LOGGER.debug("websocket connection is closing (%s)", msg.type) break if msg.type == WSMsgType.ERROR: self._LOGGER.debug("websocket connection is closing - message type error.") break if msg.type == WSMsgType.BINARY: self._queue.put_nowait(msg.data) await self._pingwatchdog.trigger() await self._watchdog.trigger() async def _websocket_connection_headers(self): token = await self.oauth.async_get_cached_token() header = { "Authorization": token["access_token"], "APP-SESSION-ID": self.session_id, "OUTPUT-FORMAT": "PROTO", "X-SessionId": self.session_id, "X-TrackingId": str(uuid.uuid4()).upper(), "ris-os-name": RIS_OS_NAME, "ris-os-version": RIS_OS_VERSION, # "ris-websocket-type": "ios-native", "ris-sdk-version": RIS_SDK_VERSION, "X-Locale": "de-DE", "User-Agent": WEBSOCKET_USER_AGENT, # "Accept-Language": " de-DE,de;q=0.9", } return self._get_region_header(header) def _get_region_header(self, header) -> list: if self._region == REGION_EUROPE: header["X-ApplicationName"] = "mycar-store-ece" header["ris-application-version"] = RIS_APPLICATION_VERSION if self._region == REGION_NORAM: header["X-ApplicationName"] = "mycar-store-us" header["ris-application-version"] = RIS_APPLICATION_VERSION_NA header["User-Agent"] = WEBSOCKET_USER_AGENT_US header["X-Locale"] = "en-US" header["Accept-Encoding"] = "gzip" header["Sec-WebSocket-Extensions"] = "permessage-deflate" if self._region == REGION_APAC: header["X-ApplicationName"] = "mycar-store-ap" header["ris-application-version"] = RIS_APPLICATION_VERSION_PA header["User-Agent"] = WEBSOCKET_USER_AGENT_PA if self._region == REGION_CHINA: header["X-ApplicationName"] = "mycar-store-cn" header["ris-application-version"] = RIS_APPLICATION_VERSION_CN header["User-Agent"] = WEBSOCKET_USER_AGENT_CN header["ris-sdk-version"] = RIS_SDK_VERSION_CN return header async def _blocked_account_reload_check(self): if self.account_blocked and self.ws_connect_retry_counter_reseted: self.account_blocked = False self.ws_connect_retry_counter_reseted = False self._blocked_since_time = None self._last_backup_reload_time = None self._LOGGER.info("Initiating component reload after account got unblocked...") self._hass.config_entries.async_schedule_reload(self.oauth._config_entry.entry_id) elif self.account_blocked and not self.ws_connect_retry_counter_reseted: current_time = time.time() # Prüfe ob Backup-Reload notwendig und erlaubt ist if self._blocked_since_time is not None and self._should_trigger_backup_reload(current_time): self._LOGGER.info( "Initiating scheduled backup component reload during allowed time window " "(ignition mode or no message received)" ) self.account_blocked = False self._blocked_since_time = None self._last_backup_reload_time = current_time self._hass.config_entries.async_schedule_reload(self.oauth._config_entry.entry_id) else: await self.component_reload_watcher.trigger() def _should_trigger_backup_reload(self, current_time: float) -> bool: """Prüft ob Backup-Reload ausgeführt werden soll (alle 30 Min oder garantiert nach Mitternacht GMT).""" # Kein Backup-Reload für China - Reauth ist dort nicht verfügbar if self._region == REGION_CHINA: return False # Mindestens 5 Minuten blockiert sein if current_time - self._blocked_since_time < 300: return False # Aktuelle Zeit in GMT now_utc = datetime.fromtimestamp(current_time, tz=timezone.utc) # GARANTIERT nach Mitternacht GMT (00:00 - 00:30 Zeitfenster) if now_utc.hour == 0 and now_utc.minute <= 30: # Prüfe ob schon heute nach Mitternacht ein Reload gemacht wurde if self._last_backup_reload_time is not None: last_reload_utc = datetime.fromtimestamp(self._last_backup_reload_time, tz=timezone.utc) # Wenn der letzte Reload heute nach Mitternacht war, nicht nochmal if ( last_reload_utc.date() == now_utc.date() and last_reload_utc.hour == 0 and last_reload_utc.minute <= 30 ): return False return True # Alle 30 Minuten, aber nur wenn mindestens 30 Min seit letztem Reload if self._last_backup_reload_time is not None: if current_time - self._last_backup_reload_time < 1800: # 30 * 60 = 1800 Sekunden return False # 30-Minuten-Intervalle (:00, :30) mit 5-Minuten-Fenster if now_utc.minute <= 5 or (25 <= now_utc.minute <= 35): return True return False async def _await_tasks_then_cleanup(self): """Warte kurz auf natürliches Ende der Tasks und räume dann auf.""" # Warten auf _websocket_task if self._websocket_task and not self._websocket_task.done(): try: await asyncio.shield(asyncio.wait_for(self._websocket_task, timeout=2.0)) except asyncio.TimeoutError: self._LOGGER.warning("websocket task didn't finish in time, cancelling") if self._websocket_task: self._websocket_task.cancel() with contextlib.suppress(Exception): await self._websocket_task except asyncio.CancelledError: # Beim Shutdown ignorieren pass # Queue-Task analog if self._queue_task and not self._queue_task.done(): try: await asyncio.shield(asyncio.wait_for(self._queue_task, timeout=2.0)) except asyncio.TimeoutError: self._queue_task.cancel() with contextlib.suppress(Exception): await self._queue_task except asyncio.CancelledError: pass # Queue bereinigen await self._cleanup_queue("_await_tasks_then_cleanup") # Task-Referenzen zurücksetzen self._queue_task = None self._websocket_task = None async def _cleanup_tasks(self): """Cleanup running tasks properly (Fallback).""" tasks_to_cancel = [] if self._queue_task and not self._queue_task.done(): tasks_to_cancel.append(self._queue_task) self._LOGGER.debug("Cancelling _queue_task") if self._websocket_task and not self._websocket_task.done(): tasks_to_cancel.append(self._websocket_task) self._LOGGER.debug("Cancelling _websocket_task") if tasks_to_cancel: for task in tasks_to_cancel: task.cancel() # Warten auf ordnungsgemäße Beendigung mit Timeout try: await asyncio.wait_for(asyncio.gather(*tasks_to_cancel, return_exceptions=True), timeout=5.0) except asyncio.TimeoutError: self._LOGGER.warning("Some websocket tasks did not terminate within 5 seconds") # Queue bereinigen await self._cleanup_queue("_cleanup_tasks") # Task-Referenzen zurücksetzen self._queue_task = None self._websocket_task = None async def _cleanup_queue(self, caller: str = "unknown"): """Cleanup remaining queue items.""" cleanup_count = 0 try: while not self._queue.empty(): try: self._queue.get_nowait() self._queue.task_done() cleanup_count += 1 except asyncio.QueueEmpty: break except Exception as err: self._LOGGER.error("Error cleaning up queue: %s", err) if cleanup_count > 0: self._LOGGER.debug( "Cleaned up %d remaining queue items (caller: %s, qsize: %d)", cleanup_count, caller, self._queue.qsize(), ) def _set_watchdog_timeout(self, timeout: int) -> None: """Set watchdog timeout with protection period logic.""" if not self._initial_timeout_used or self._connection_start_time is None: # Not in initial timeout mode, allow any timeout change self._watchdog.timeout = timeout return # After protection period, allow timeout changes and switch to default behavior self._watchdog.timeout = timeout # Reset to normal behavior after protection period (regardless of timeout value) self._initial_timeout_used = False self._connection_start_time = None def _reset_watchdog_timeout(self) -> None: """Reset watchdog timeout to default and clear initial timeout state.""" self._watchdog.timeout = DEFAULT_WATCHDOG_TIMEOUT self._initial_timeout_used = False self._connection_start_time = None ================================================ FILE: hacs.json ================================================ { "name": "MercedesME 2020", "homeassistant": "2024.02.0", "zip_release": true, "filename": "mbapi2020.zip", "render_readme": true } ================================================ FILE: mypi.ini ================================================ # Automatically generated by hassfest. # # To update, run python3 -m script.hassfest -p mypy_config [mypy] python_version = 3.13 plugins = pydantic.mypy show_error_codes = true follow_imports = silent local_partial_types = true strict_equality = true no_implicit_optional = true warn_incomplete_stub = true warn_redundant_casts = true warn_unused_configs = true warn_unused_ignores = true enable_error_code = ignore-without-code, redundant-self, truthy-iterable disable_error_code = annotation-unchecked, import-not-found, import-untyped extra_checks = false check_untyped_defs = true disallow_incomplete_defs = true disallow_subclassing_any = true disallow_untyped_calls = true disallow_untyped_decorators = true disallow_untyped_defs = true warn_return_any = true warn_unreachable = true [pydantic-mypy] init_forbid_extra = true init_typed = true warn_required_dynamic_aliases = true warn_untyped_fields = true [mypy-custom_components.*] check_untyped_defs = false disallow_incomplete_defs = false disallow_subclassing_any = false disallow_untyped_calls = false disallow_untyped_decorators = false disallow_untyped_defs = false warn_return_any = false warn_unreachable = false no_implicit_reexport = false ignore_missing_imports = True follow_imports = silent [mypy-simulator] check_untyped_defs = false disallow_incomplete_defs = false disallow_subclassing_any = false disallow_untyped_calls = false disallow_untyped_decorators = false disallow_untyped_defs = false warn_return_any = false warn_unreachable = false no_implicit_reexport = false ignore_missing_imports = True follow_imports = silent [mypy-tests.*] check_untyped_defs = false disallow_incomplete_defs = false disallow_subclassing_any = false disallow_untyped_calls = false disallow_untyped_decorators = false disallow_untyped_defs = false warn_return_any = false warn_unreachable = false [mypy.voluptuous] ignore_missing_imports = True follow_imports = silent ================================================ FILE: pyproject.toml ================================================ [tool.pylint.MAIN] py-version = "3.14" # Use a conservative default here; 2 should speed up most setups and not hurt # any too bad. Override on command line as appropriate. jobs = 2 init-hook = """\ from pathlib import Path; \ import sys; \ from pylint.config import find_default_config_files; \ sys.path.append( \ str(Path(next(find_default_config_files())).parent.joinpath('pylint/plugins')) ) \ """ load-plugins = [ "pylint.extensions.code_style", "pylint.extensions.typing", "pylint_per_file_ignores", ] persistent = false extension-pkg-allow-list = [ "av.audio.stream", "av.logging", "av.stream", "ciso8601", "orjson", "cv2", ] [tool.pylint.BASIC] class-const-naming-style = "any" [tool.pylint."MESSAGES CONTROL"] # Reasons disabled: # format - handled by ruff # locally-disabled - it spams too much # duplicate-code - unavoidable # cyclic-import - doesn't test if both import on load # abstract-class-little-used - prevents from setting right foundation # unused-argument - generic callbacks and setup methods create a lot of warnings # too-many-* - are not enforced for the sake of readability # too-few-* - same as too-many-* # abstract-method - with intro of async there are always methods missing # inconsistent-return-statements - doesn't handle raise # too-many-ancestors - it's too strict. # wrong-import-order - isort guards this # possibly-used-before-assignment - too many errors / not necessarily issues # --- # Pylint CodeStyle plugin # consider-using-namedtuple-or-dataclass - too opinionated # consider-using-assignment-expr - decision to use := better left to devs disable = [ "format", "abstract-method", "cyclic-import", "duplicate-code", "inconsistent-return-statements", "locally-disabled", "not-context-manager", "too-few-public-methods", "too-many-ancestors", "too-many-arguments", "too-many-instance-attributes", "too-many-lines", "too-many-locals", "too-many-public-methods", "too-many-boolean-expressions", "too-many-positional-arguments", "wrong-import-order", "consider-using-namedtuple-or-dataclass", "consider-using-assignment-expr", # "possibly-used-before-assignment", # Handled by ruff # Ref: "await-outside-async", # PLE1142 "bad-str-strip-call", # PLE1310 "bad-string-format-type", # PLE1307 "bidirectional-unicode", # PLE2502 "continue-in-finally", # PLE0116 "duplicate-bases", # PLE0241 "misplaced-bare-raise", # PLE0704 "format-needs-mapping", # F502 "function-redefined", # F811 # Needed because ruff does not understand type of __all__ generated by a function # "invalid-all-format", # PLE0605 "invalid-all-object", # PLE0604 "invalid-character-backspace", # PLE2510 "invalid-character-esc", # PLE2513 "invalid-character-nul", # PLE2514 "invalid-character-sub", # PLE2512 "invalid-character-zero-width-space", # PLE2515 "logging-too-few-args", # PLE1206 "logging-too-many-args", # PLE1205 "missing-format-string-key", # F524 "mixed-format-string", # F506 "no-method-argument", # N805 "no-self-argument", # N805 "nonexistent-operator", # B002 "nonlocal-without-binding", # PLE0117 "not-in-loop", # F701, F702 "notimplemented-raised", # F901 "return-in-init", # PLE0101 "return-outside-function", # F706 "syntax-error", # E999 "too-few-format-args", # F524 "too-many-format-args", # F522 "too-many-star-expressions", # F622 "truncated-format-string", # F501 "undefined-all-variable", # F822 "undefined-variable", # F821 "used-prior-global-declaration", # PLE0118 "yield-inside-async-function", # PLE1700 "yield-outside-function", # F704 "anomalous-backslash-in-string", # W605 "assert-on-string-literal", # PLW0129 "assert-on-tuple", # F631 "bad-format-string", # W1302, F "bad-format-string-key", # W1300, F "bare-except", # E722 "binary-op-exception", # PLW0711 "cell-var-from-loop", # B023 # "dangerous-default-value", # B006, ruff catches new occurrences, needs more work "duplicate-except", # B014 "duplicate-key", # F601 "duplicate-string-formatting-argument", # F "duplicate-value", # F "eval-used", # S307 "exec-used", # S102 "expression-not-assigned", # B018 "f-string-without-interpolation", # F541 "forgotten-debug-statement", # T100 "format-string-without-interpolation", # F # "global-statement", # PLW0603, ruff catches new occurrences, needs more work "global-variable-not-assigned", # PLW0602 "implicit-str-concat", # ISC001 "import-self", # PLW0406 "inconsistent-quotes", # Q000 "invalid-envvar-default", # PLW1508 "keyword-arg-before-vararg", # B026 "logging-format-interpolation", # G "logging-fstring-interpolation", # G "logging-not-lazy", # G "misplaced-future", # F404 "named-expr-without-context", # PLW0131 "nested-min-max", # PLW3301 "pointless-statement", # B018 "raise-missing-from", # B904 "redefined-builtin", # A001 "try-except-raise", # TRY302 "unused-argument", # ARG001, we don't use it "unused-format-string-argument", #F507 "unused-format-string-key", # F504 "unused-import", # F401 "unused-variable", # F841 "useless-else-on-loop", # PLW0120 "wildcard-import", # F403 "bad-classmethod-argument", # N804 "consider-iterating-dictionary", # SIM118 "empty-docstring", # D419 "invalid-name", # N815 "line-too-long", # E501, disabled globally "missing-class-docstring", # D101 "missing-final-newline", # W292 "missing-function-docstring", # D103 "missing-module-docstring", # D100 "multiple-imports", #E401 "singleton-comparison", # E711, E712 "subprocess-run-check", # PLW1510 "superfluous-parens", # UP034 "ungrouped-imports", # I001 "unidiomatic-typecheck", # E721 "unnecessary-direct-lambda-call", # PLC3002 "unnecessary-lambda-assignment", # PLC3001 "unnecessary-pass", # PIE790 "unneeded-not", # SIM208 "useless-import-alias", # PLC0414 "wrong-import-order", # I001 "wrong-import-position", # E402 "comparison-of-constants", # PLR0133 "comparison-with-itself", # PLR0124 "consider-alternative-union-syntax", # UP007 "consider-merging-isinstance", # PLR1701 "consider-using-alias", # UP006 "consider-using-dict-comprehension", # C402 "consider-using-generator", # C417 "consider-using-get", # SIM401 "consider-using-set-comprehension", # C401 "consider-using-sys-exit", # PLR1722 "consider-using-ternary", # SIM108 "literal-comparison", # F632 "property-with-parameters", # PLR0206 "super-with-arguments", # UP008 "too-many-branches", # PLR0912 "too-many-return-statements", # PLR0911 "too-many-statements", # PLR0915 "trailing-comma-tuple", # COM818 "unnecessary-comprehension", # C416 "use-a-generator", # C417 "use-dict-literal", # C406 "use-list-literal", # C405 "useless-object-inheritance", # UP004 "useless-return", # PLR1711 "no-else-break", # RET508 "no-else-continue", # RET507 "no-else-raise", # RET506 "no-else-return", # RET505 "broad-except", # BLE001 "protected-access", # SLF001 "broad-exception-raised", # TRY002 "consider-using-f-string", # PLC0209 # "no-self-use", # PLR6301 # Optional plugin, not enabled # Handled by mypy # Ref: "abstract-class-instantiated", "arguments-differ", "assigning-non-slot", "assignment-from-no-return", "assignment-from-none", "bad-exception-cause", "bad-format-character", "bad-reversed-sequence", "bad-super-call", "bad-thread-instantiation", "catching-non-exception", "comparison-with-callable", "deprecated-class", "dict-iter-missing-items", "format-combined-specification", "global-variable-undefined", "import-error", "inconsistent-mro", "inherit-non-class", "init-is-generator", "invalid-class-object", "invalid-enum-extension", "invalid-envvar-value", "invalid-format-returned", "invalid-hash-returned", "invalid-metaclass", "invalid-overridden-method", "invalid-repr-returned", "invalid-sequence-index", "invalid-slice-index", "invalid-slots-object", "invalid-slots", "invalid-star-assignment-target", "invalid-str-returned", "invalid-unary-operand-type", "invalid-unicode-codec", "isinstance-second-argument-not-valid-type", "method-hidden", "misplaced-format-function", "missing-format-argument-key", "missing-format-attribute", "missing-kwoa", "no-member", "no-value-for-parameter", "non-iterator-returned", "non-str-assignment-to-dunder-name", "nonlocal-and-global", "not-a-mapping", "not-an-iterable", "not-async-context-manager", "not-callable", "not-context-manager", "overridden-final-method", "raising-bad-type", "raising-non-exception", "redundant-keyword-arg", "relative-beyond-top-level", "self-cls-assignment", "signature-differs", "star-needs-assignment-target", "subclassed-final-class", "super-without-brackets", "too-many-function-args", "typevar-double-variance", "typevar-name-mismatch", "unbalanced-dict-unpacking", "unbalanced-tuple-unpacking", "unexpected-keyword-arg", "unhashable-member", "unpacking-non-sequence", "unsubscriptable-object", "unsupported-assignment-operation", "unsupported-binary-operation", "unsupported-delete-operation", "unsupported-membership-test", "used-before-assignment", "using-final-decorator-in-unsupported-version", "wrong-exception-operation", ] enable = [ #"useless-suppression", # temporarily every now and then to clean them up "use-symbolic-message-instead", ] per-file-ignores = [ # redefined-outer-name: Tests reference fixtures in the test function # use-implicit-booleaness-not-comparison: Tests need to validate that a list # or a dict is returned "/tests/:redefined-outer-name,use-implicit-booleaness-not-comparison", ] [tool.pylint.REPORTS] score = false [tool.pylint.TYPECHECK] ignored-classes = [ "_CountingAttr", # for attrs ] mixin-class-rgx = ".*[Mm]ix[Ii]n" [tool.pylint.FORMAT] expected-line-ending-format = "LF" [tool.pylint.EXCEPTIONS] overgeneral-exceptions = [ "builtins.BaseException", "builtins.Exception", # "homeassistant.exceptions.HomeAssistantError", # too many issues ] [tool.pylint.TYPING] runtime-typing = false [tool.pylint.CODE_STYLE] max-line-length-suggestions = 120 [tool.pytest.ini_options] testpaths = [ "tests", ] norecursedirs = [ ".git", "testing_config", ] log_format = "%(asctime)s.%(msecs)03d %(levelname)-8s %(threadName)s %(name)s:%(filename)s:%(lineno)s %(message)s" log_date_format = "%Y-%m-%d %H:%M:%S" asyncio_mode = "auto" asyncio_default_fixture_loop_scope = "function" filterwarnings = [] [tool.ruff] line-length = 120 required-version = ">=0.6.8" [tool.ruff.lint] select = [ "A001", # Variable {name} is shadowing a Python builtin "ASYNC210", # Async functions should not call blocking HTTP methods "ASYNC220", # Async functions should not create subprocesses with blocking methods "ASYNC221", # Async functions should not run processes with blocking methods "ASYNC222", # Async functions should not wait on processes with blocking methods "ASYNC230", # Async functions should not open files with blocking methods like open "ASYNC251", # Async functions should not call time.sleep "B002", # Python does not support the unary prefix increment "B005", # Using .strip() with multi-character strings is misleading "B007", # Loop control variable {name} not used within loop body "B014", # Exception handler with duplicate exception "B015", # Pointless comparison. Did you mean to assign a value? Otherwise, prepend assert or remove it. "B017", # pytest.raises(BaseException) should be considered evil "B018", # Found useless attribute access. Either assign it to a variable or remove it. "B023", # Function definition does not bind loop variable {name} "B026", # Star-arg unpacking after a keyword argument is strongly discouraged "B032", # Possible unintentional type annotation (using :). Did you mean to assign (using =)? "B904", # Use raise from to specify exception cause "B905", # zip() without an explicit strict= parameter "BLE", "C", # complexity "COM818", # Trailing comma on bare tuple prohibited "D", # docstrings "DTZ003", # Use datetime.now(tz=) instead of datetime.utcnow() "DTZ004", # Use datetime.fromtimestamp(ts, tz=) instead of datetime.utcfromtimestamp(ts) "E", # pycodestyle "F", # pyflakes/autoflake "F541", # f-string without any placeholders "FLY", # flynt "FURB", # refurb "G", # flake8-logging-format "I", # isort "INP", # flake8-no-pep420 "ISC", # flake8-implicit-str-concat "ICN001", # import concentions; {name} should be imported as {asname} "LOG", # flake8-logging "N804", # First argument of a class method should be named cls "N805", # First argument of a method should be named self "N815", # Variable {name} in class scope should not be mixedCase "PERF", # Perflint "PGH", # pygrep-hooks "PIE", # flake8-pie "PL", # pylint "PT", # flake8-pytest-style "PTH", # flake8-pathlib "PYI", # flake8-pyi "RET", # flake8-return "RSE", # flake8-raise "RUF005", # Consider iterable unpacking instead of concatenation "RUF006", # Store a reference to the return value of asyncio.create_task "RUF010", # Use explicit conversion flag "RUF013", # PEP 484 prohibits implicit Optional "RUF017", # Avoid quadratic list summation "RUF018", # Avoid assignment expressions in assert statements "RUF019", # Unnecessary key check before dictionary access # "RUF100", # Unused `noqa` directive; temporarily every now and then to clean them up "S102", # Use of exec detected "S103", # bad-file-permissions "S108", # hardcoded-temp-file "S306", # suspicious-mktemp-usage "S307", # suspicious-eval-usage "S313", # suspicious-xmlc-element-tree-usage "S314", # suspicious-xml-element-tree-usage "S315", # suspicious-xml-expat-reader-usage "S316", # suspicious-xml-expat-builder-usage "S317", # suspicious-xml-sax-usage "S318", # suspicious-xml-mini-dom-usage "S319", # suspicious-xml-pull-dom-usage "S601", # paramiko-call "S602", # subprocess-popen-with-shell-equals-true "S604", # call-with-shell-equals-true "S608", # hardcoded-sql-expression "S609", # unix-command-wildcard-injection "SIM", # flake8-simplify "SLF", # flake8-self "SLOT", # flake8-slots "T100", # Trace found: {name} used "T20", # flake8-print "TCH", # flake8-type-checking "TID", # Tidy imports "TRY", # tryceratops "UP", # pyupgrade "UP031", # Use format specifiers instead of percent format "UP032", # Use f-string instead of `format` call "W", # pycodestyle ] ignore = [ "D202", # No blank lines allowed after function docstring "D203", # 1 blank line required before class docstring "D213", # Multi-line docstring summary should start at the second line "D406", # Section name should end with a newline "D407", # Section name underlining "E501", # line too long "PLC1901", # {existing} can be simplified to {replacement} as an empty string is falsey; too many false positives "PLR0911", # Too many return statements ({returns} > {max_returns}) "PLR0912", # Too many branches ({branches} > {max_branches}) "PLR0913", # Too many arguments to function call ({c_args} > {max_args}) "PLR0915", # Too many statements ({statements} > {max_statements}) "PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable "PLW2901", # Outer {outer_kind} variable {name} overwritten by inner {inner_kind} target "PT011", # pytest.raises({exception}) is too broad, set the `match` parameter or use a more specific exception "PT018", # Assertion should be broken down into multiple parts "RUF001", # String contains ambiguous unicode character. "RUF002", # Docstring contains ambiguous unicode character. "RUF003", # Comment contains ambiguous unicode character. "RUF015", # Prefer next(...) over single element slice "SIM102", # Use a single if statement instead of nested if statements "SIM103", # Return the condition {condition} directly "SIM108", # Use ternary operator {contents} instead of if-else-block "SIM115", # Use context handler for opening files # Moving imports into type-checking blocks can mess with pytest.patch() "TC001", # Move application import {} into a type-checking block "TC002", # Move third-party import {} into a type-checking block "TC003", # Move standard library import {} into a type-checking block "TRY003", # Avoid specifying long messages outside the exception class "TRY400", # Use `logging.exception` instead of `logging.error` # May conflict with the formatter, https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "W191", "E111", "E114", "E117", "D206", "D300", "Q", "COM812", "COM819", "ISC001", # Disabled because ruff does not understand type of __all__ generated by a function "PLE0605", "SLF001" ] [tool.ruff.lint.flake8-import-conventions.extend-aliases] voluptuous = "vol" "homeassistant.components.air_quality.PLATFORM_SCHEMA" = "AIR_QUALITY_PLATFORM_SCHEMA" "homeassistant.components.alarm_control_panel.PLATFORM_SCHEMA" = "ALARM_CONTROL_PANEL_PLATFORM_SCHEMA" "homeassistant.components.binary_sensor.PLATFORM_SCHEMA" = "BINARY_SENSOR_PLATFORM_SCHEMA" "homeassistant.components.button.PLATFORM_SCHEMA" = "BUTTON_PLATFORM_SCHEMA" "homeassistant.components.calendar.PLATFORM_SCHEMA" = "CALENDAR_PLATFORM_SCHEMA" "homeassistant.components.camera.PLATFORM_SCHEMA" = "CAMERA_PLATFORM_SCHEMA" "homeassistant.components.climate.PLATFORM_SCHEMA" = "CLIMATE_PLATFORM_SCHEMA" "homeassistant.components.conversation.PLATFORM_SCHEMA" = "CONVERSATION_PLATFORM_SCHEMA" "homeassistant.components.cover.PLATFORM_SCHEMA" = "COVER_PLATFORM_SCHEMA" "homeassistant.components.date.PLATFORM_SCHEMA" = "DATE_PLATFORM_SCHEMA" "homeassistant.components.datetime.PLATFORM_SCHEMA" = "DATETIME_PLATFORM_SCHEMA" "homeassistant.components.device_tracker.PLATFORM_SCHEMA" = "DEVICE_TRACKER_PLATFORM_SCHEMA" "homeassistant.components.event.PLATFORM_SCHEMA" = "EVENT_PLATFORM_SCHEMA" "homeassistant.components.fan.PLATFORM_SCHEMA" = "FAN_PLATFORM_SCHEMA" "homeassistant.components.geo_location.PLATFORM_SCHEMA" = "GEO_LOCATION_PLATFORM_SCHEMA" "homeassistant.components.humidifier.PLATFORM_SCHEMA" = "HUMIDIFIER_PLATFORM_SCHEMA" "homeassistant.components.image.PLATFORM_SCHEMA" = "IMAGE_PLATFORM_SCHEMA" "homeassistant.components.image_processing.PLATFORM_SCHEMA" = "IMAGE_PROCESSING_PLATFORM_SCHEMA" "homeassistant.components.lawn_mower.PLATFORM_SCHEMA" = "LAWN_MOWER_PLATFORM_SCHEMA" "homeassistant.components.light.PLATFORM_SCHEMA" = "LIGHT_PLATFORM_SCHEMA" "homeassistant.components.lock.PLATFORM_SCHEMA" = "LOCK_PLATFORM_SCHEMA" "homeassistant.components.media_player.PLATFORM_SCHEMA" = "MEDIA_PLAYER_PLATFORM_SCHEMA" "homeassistant.components.notify.PLATFORM_SCHEMA" = "NOTIFY_PLATFORM_SCHEMA" "homeassistant.components.number.PLATFORM_SCHEMA" = "NUMBER_PLATFORM_SCHEMA" "homeassistant.components.remote.PLATFORM_SCHEMA" = "REMOTE_PLATFORM_SCHEMA" "homeassistant.components.scene.PLATFORM_SCHEMA" = "SCENE_PLATFORM_SCHEMA" "homeassistant.components.select.PLATFORM_SCHEMA" = "SELECT_PLATFORM_SCHEMA" "homeassistant.components.sensor.PLATFORM_SCHEMA" = "SENSOR_PLATFORM_SCHEMA" "homeassistant.components.siren.PLATFORM_SCHEMA" = "SIREN_PLATFORM_SCHEMA" "homeassistant.components.stt.PLATFORM_SCHEMA" = "STT_PLATFORM_SCHEMA" "homeassistant.components.switch.PLATFORM_SCHEMA" = "SWITCH_PLATFORM_SCHEMA" "homeassistant.components.text.PLATFORM_SCHEMA" = "TEXT_PLATFORM_SCHEMA" "homeassistant.components.time.PLATFORM_SCHEMA" = "TIME_PLATFORM_SCHEMA" "homeassistant.components.todo.PLATFORM_SCHEMA" = "TODO_PLATFORM_SCHEMA" "homeassistant.components.tts.PLATFORM_SCHEMA" = "TTS_PLATFORM_SCHEMA" "homeassistant.components.vacuum.PLATFORM_SCHEMA" = "VACUUM_PLATFORM_SCHEMA" "homeassistant.components.valve.PLATFORM_SCHEMA" = "VALVE_PLATFORM_SCHEMA" "homeassistant.components.update.PLATFORM_SCHEMA" = "UPDATE_PLATFORM_SCHEMA" "homeassistant.components.wake_word.PLATFORM_SCHEMA" = "WAKE_WORD_PLATFORM_SCHEMA" "homeassistant.components.water_heater.PLATFORM_SCHEMA" = "WATER_HEATER_PLATFORM_SCHEMA" "homeassistant.components.weather.PLATFORM_SCHEMA" = "WEATHER_PLATFORM_SCHEMA" "homeassistant.core.DOMAIN" = "HOMEASSISTANT_DOMAIN" "homeassistant.helpers.area_registry" = "ar" "homeassistant.helpers.category_registry" = "cr" "homeassistant.helpers.config_validation" = "cv" "homeassistant.helpers.device_registry" = "dr" "homeassistant.helpers.entity_registry" = "er" "homeassistant.helpers.floor_registry" = "fr" "homeassistant.helpers.issue_registry" = "ir" "homeassistant.helpers.label_registry" = "lr" "homeassistant.util.dt" = "dt_util" [tool.ruff.lint.flake8-pytest-style] fixture-parentheses = false mark-parentheses = false [tool.ruff.lint.flake8-tidy-imports.banned-api] "async_timeout".msg = "use asyncio.timeout instead" "pytz".msg = "use zoneinfo instead" [tool.ruff.lint.isort] force-sort-within-sections = true known-first-party = [ "homeassistant", ] combine-as-imports = true split-on-trailing-comma = false [tool.ruff.lint.per-file-ignores] # Allow for main entry & scripts to write to stdout "script/*" = ["T20"] #"script/burp-*" = ["W410"] # Allow relative imports within auth and within components "custom_components/*/*/*" = ["TID252"] # Temporary "tests/**" = ["PTH"] "custom_components/mbapi2020/proto/*.py" = ["F401"] # Alle .py-Dateien im src-Verzeichnis [tool.ruff.lint.mccabe] max-complexity = 25 [tool.ruff.lint.pydocstyle] property-decorators = ["propcache.cached_property"] ================================================ FILE: requirements.txt ================================================ protobuf>=3.19.1 pre-commit ================================================ FILE: scripts/burp-redirector.py ================================================ from burp import IBurpExtender, IHttpListener HOST_TO = "localhost" SERVER_PORT_MAP = { "bff.emea-prod.mobilesdk.mercedes-benz.com": 8002, "websocket.emea-prod.mobilesdk.mercedes-benz.com": 8001, } class BurpExtender(IBurpExtender, IHttpListener): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("MB Traffic redirector") # register ourselves as an HTTP listener callbacks.registerHttpListener(self) # # implement IHttpListener # def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo): # only process requests if not messageIsRequest: return # get the HTTP service for the request httpService = messageInfo.getHttpService() host = httpService.getHost() if host in SERVER_PORT_MAP: messageInfo.setHttpService( self._helpers.buildHttpService(HOST_TO, SERVER_PORT_MAP.get(host), httpService.getProtocol()) ) ================================================ FILE: scripts/https-bff.py ================================================ from http.server import HTTPServer, SimpleHTTPRequestHandler import logging import os from pathlib import Path import ssl import sys LOGGER = logging.getLogger(__package__) class SecureHTTPRequestHandler(SimpleHTTPRequestHandler): """Überschreibt die Methode, um das Basisverzeichnis anzupassen.""" def translate_path(self, path): """Basisverzeichnis für Dateien.""" base_directory = "../local" # Anhängen von ".json", wenn der Path keine Dateiendung enthält if not Path(path).suffix: # Kein "." in der Datei path += ".json" # Normalisierung des Pfads path = super().translate_path(path) # Ersetzen des Basisverzeichnisses durch das angegebene relative_path = os.path.relpath(path, Path.cwd()) LOGGER.debug("request %s", Path(base_directory) / relative_path) return Path(base_directory) / relative_path def set_logger(): """Set Logger properties.""" fmt = "%(asctime)s.%(msecs)03d %(levelname)s (%(threadName)s) [%(name)s] %(message)s" LOGGER.setLevel(logging.DEBUG) handler = logging.StreamHandler(sys.stdout) handler.setLevel(logging.DEBUG) formatter = logging.Formatter(fmt) handler.setFormatter(formatter) LOGGER.addHandler(handler) def start_server(host="127.0.0.1", port=8002, certfile="../local/selfsigned.crt", keyfile="../local/selfsigned.key"): """HTTPS-Server mit dem spezifizierten Handler.""" httpd = HTTPServer((host, port), SecureHTTPRequestHandler) # SSL-Kontext erstellen ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) # Socket mit SSL-Kontext umschließen httpd.socket = ssl_context.wrap_socket(httpd.socket, server_side=True) LOGGER.debug("HTTPS-Server gestartet auf https://%s:%s", host, port) LOGGER.debug("Daten werden aus dem Verzeichnis ../local geladen.") httpd.serve_forever() if __name__ == "__main__": start_server() ================================================ FILE: scripts/https-ws-case-429.py ================================================ """Simple HTTP Server to simulate http429.""" from __future__ import annotations from http.server import BaseHTTPRequestHandler, HTTPServer import logging import ssl import sys from urllib.parse import urlparse HTTP_SERVER_IP = "0.0.0.0" HTTP_SERVER_PORT = 8001 LOGGER = logging.getLogger(__package__) class MBAPI2020SimulatorServer(BaseHTTPRequestHandler): """Simple HTTP Server to simulate the MBAPI2020 API.""" def do_GET(self): """Answer get requests.""" parsed = urlparse(self.path) if parsed.path == "/v2/ws": self.send_response(429) self.send_header("Content-type", "") self.end_headers() self.wfile.write("".encode("utf-8")) return def do_POST(self): """Answer post requests.""" self.do_GET() def set_logger(): """Set Logger properties.""" fmt = "%(asctime)s.%(msecs)03d %(levelname)s (%(threadName)s) [%(name)s] %(message)s" LOGGER.setLevel(logging.DEBUG) handler = logging.StreamHandler(sys.stdout) handler.setLevel(logging.DEBUG) formatter = logging.Formatter(fmt) handler.setFormatter(formatter) LOGGER.addHandler(handler) if __name__ == "__main__": context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.load_cert_chain(certfile="../local/selfsigned.crt", keyfile="../local/selfsigned.key") context.check_hostname = False webServer = HTTPServer((HTTP_SERVER_IP, HTTP_SERVER_PORT), MBAPI2020SimulatorServer) webServer.socket = context.wrap_socket(webServer.socket, server_side=True) set_logger() LOGGER.debug("Server started https://%s:%s", HTTP_SERVER_IP, HTTP_SERVER_PORT) webServer.serve_forever() webServer.server_close() LOGGER.debug("Server stopped.") ================================================ FILE: scripts/setup ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/.." sudo apt-get update sudo apt-get install -y --no-install-recommends \ libpcap-dev \ libturbojpeg0 python3 -m pip install --requirement requirements.txt pre-commit install ================================================ FILE: token-requester/macOS/.gitignore ================================================ # Xcode # # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore ## User settings xcuserdata/ ## Obj-C/Swift specific *.hmap ## App packaging *.ipa *.dSYM.zip *.dSYM ## Playgrounds timeline.xctimeline playground.xcworkspace # Swift Package Manager # # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. # Packages/ # Package.pins # Package.resolved # *.xcodeproj # # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata # hence it is not needed unless you have added a package configuration file to your project # .swiftpm .build/ # CocoaPods # # We recommend against adding the Pods directory to your .gitignore. However # you should judge for yourself, the pros and cons are mentioned at: # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control # # Pods/ # # Add this line if you want to avoid checking in source code from the Xcode workspace # *.xcworkspace # Carthage # # Add this line if you want to avoid checking in source code from Carthage dependencies. # Carthage/Checkouts Carthage/Build/ # fastlane # # It is recommended to not store the screenshots in the git repo. # Instead, use fastlane to re-generate the screenshots whenever they are needed. # For more information about the recommended setup visit: # https://docs.fastlane.tools/best-practices/source-control/#source-control fastlane/report.xml fastlane/Preview.html fastlane/screenshots/**/*.png fastlane/test_output # General .DS_Store .AppleDouble .LSOverride # Icon must end with two \r Icon # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper/AppDelegate.swift ================================================ // // AppDelegate.swift // MBAPI2020 Token Helper // // Created by Rene Nulsch on 27.12.24. // import Cocoa @main class AppDelegate: NSObject, NSApplicationDelegate { func applicationDidFinishLaunching(_ aNotification: Notification) { // Insert code here to initialize your application } func applicationWillTerminate(_ aNotification: Notification) { // Insert code here to tear down your application } func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { return true } } ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper/Assets.xcassets/AccentColor.colorset/Contents.json ================================================ { "colors" : [ { "idiom" : "universal" } ], "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ {"info":{"version":1,"author":"xcode"},"images":[{"scale":"1x","size":"16x16","filename":"mac16pt1x.png","idiom":"mac"},{"idiom":"mac","scale":"2x","filename":"mac16pt2x.png","size":"16x16"},{"size":"32x32","idiom":"mac","scale":"1x","filename":"mac32pt1x.png"},{"size":"32x32","idiom":"mac","filename":"mac32pt2x.png","scale":"2x"},{"size":"128x128","scale":"1x","filename":"mac128pt1x.png","idiom":"mac"},{"idiom":"mac","filename":"mac128pt2x.png","scale":"2x","size":"128x128"},{"scale":"1x","size":"256x256","idiom":"mac","filename":"mac256pt1x.png"},{"idiom":"mac","filename":"mac256pt2x.png","size":"256x256","scale":"2x"},{"scale":"1x","filename":"mac512pt1x.png","idiom":"mac","size":"512x512"},{"size":"512x512","filename":"mac512pt2x.png","scale":"2x","idiom":"mac"}]} ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper/Assets.xcassets/Contents.json ================================================ { "info" : { "author" : "xcode", "version" : 1 } } ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper/Base.lproj/Main.storyboard ================================================ Default Left to Right Right to Left Default Left to Right Right to Left ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper/MBAPI2020_Token_Helper.entitlements ================================================ com.apple.security.app-sandbox com.apple.security.files.user-selected.read-only com.apple.security.network.client ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper/ViewController.swift ================================================ import Cocoa import AuthenticationServices import CryptoKit class ViewController: NSViewController, ASWebAuthenticationPresentationContextProviding { @IBOutlet weak var label_rt: NSTextField! @IBOutlet weak var label_at: NSTextField! @IBOutlet weak var copyRefreshToken: NSButton! @IBOutlet weak var copyAccessToken: NSButton! @IBOutlet weak var refreshToken_textview: NSTextField! @IBOutlet weak var accessToken_textview: NSTextField! var codeVerifier: String = "" var authSession: ASWebAuthenticationSession? // Authentifizierungssession als Instanzvariable speichern override func viewDidLoad() { super.viewDidLoad() copyAccessToken.isHidden = true copyRefreshToken.isHidden = true refreshToken_textview.isHidden = true accessToken_textview.isHidden = true label_at.isHidden = true label_rt.isHidden = true } @IBAction func IBActionfunccloseApp_senderAnyNSApplicationsharedterminatenilcloseApp(_ sender: Any) { NSApplication.shared.terminate(nil) } @IBAction func StartButton_click(_ sender: Any) { startOAuthLogin() } func showMessageBox(title: String) { let alert = NSAlert() alert.messageText = title alert.alertStyle = .warning alert.addButton(withTitle: "OK") alert.runModal() } func startOAuthLogin() { codeVerifier = generateCodeVerifier() guard let codeChallenge = generateCodeChallenge(from: codeVerifier) else { showMessageBox(title: "Fehler beim Generieren der Code Challenge") return } let authorizationEndpoint = "https://id.mercedes-benz.com/as/authorization.oauth2" let clientID = "62778dc4-1de3-44f4-af95-115f06a3a008" let redirectURI = "rismycar://login-callback" let scope = "email openid profile offline_access phone ciam-uid" let responseType = "code" let codeChallengeMethod = "S256" var components = URLComponents(string: authorizationEndpoint) components?.queryItems = [ URLQueryItem(name: "response_type", value: responseType), URLQueryItem(name: "client_id", value: clientID), URLQueryItem(name: "redirect_uri", value: redirectURI), URLQueryItem(name: "scope", value: scope), URLQueryItem(name: "code_challenge", value: codeChallenge), URLQueryItem(name: "code_challenge_method", value: codeChallengeMethod) ] guard let authURL = components?.url else { showMessageBox(title: "Ungültige URL für OAuth-Login") return } authSession = ASWebAuthenticationSession(url: authURL, callbackURLScheme: "rismycar") { [weak self] callbackURL, error in guard let self = self else { return } if let error = error { self.showMessageBox(title: "Fehler bei der Authentifizierung: \(error.localizedDescription)") return } guard let callbackURL = callbackURL, let components = URLComponents(url: callbackURL, resolvingAgainstBaseURL: false), let queryItems = components.queryItems, let code = queryItems.first(where: { $0.name == "code" })?.value else { self.showMessageBox(title: "Fehler beim Abrufen des Authorization Codes.") return } self.exchangeCodeForToken(code: code, redirectURI: redirectURI) } authSession?.presentationContextProvider = self authSession?.start() } func exchangeCodeForToken(code: String, redirectURI: String) { let tokenEndpoint = "https://id.mercedes-benz.com/as/token.oauth2" let clientID = "62778dc4-1de3-44f4-af95-115f06a3a008" guard let url = URL(string: tokenEndpoint) else { showMessageBox(title: "Ungültige Token-URL") return } var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") let bodyParameters = [ "grant_type": "authorization_code", "code": code, "redirect_uri": redirectURI, "client_id": clientID, "code_verifier": codeVerifier ] request.httpBody = bodyParameters.map { "\($0.key)=\($0.value)" }.joined(separator: "&").data(using: .utf8) URLSession.shared.dataTask(with: request) { [weak self] data, response, error in guard let self = self else { return } if let error = error { self.showMessageBox(title: "Fehler beim Abrufen des Tokens: \(error.localizedDescription)") return } guard let data = data else { self.showMessageBox(title: "Keine Daten vom Server erhalten.") return } do { if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any], let refreshToken = json["refresh_token"] as? String, let accessToken = json["access_token"] as? String { DispatchQueue.main.async { [weak self] in guard let self = self else { return } self.accessToken_textview.stringValue = accessToken self.refreshToken_textview.stringValue = refreshToken self.refreshToken_textview.isHidden = false self.accessToken_textview.isHidden = false self.copyAccessToken.isHidden = false self.copyRefreshToken.isHidden = false self.label_at.isHidden = false self.label_rt.isHidden = false } } else { self.showMessageBox(title: "Fehlende Token-Werte.") } } catch { self.showMessageBox(title: "Fehler beim Verarbeiten der JSON-Daten: \(error.localizedDescription)") } }.resume() } func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor { guard let window = self.view.window else { fatalError("Window not available") } return window } func generateCodeVerifier() -> String { let characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~" return String((0..<128).map { _ in characters.randomElement()! }) } func generateCodeChallenge(from verifier: String) -> String? { guard let data = verifier.data(using: .utf8) else { return nil } let hashed = SHA256.hash(data: data) return Data(hashed).base64EncodedString() .replacingOccurrences(of: "+", with: "-") .replacingOccurrences(of: "/", with: "_") .replacingOccurrences(of: "=", with: "") } @IBAction func copyAccessTokenToClipboard(_ sender: Any) { // Hole den Text aus der NSTextView let textToCopy = accessToken_textview.stringValue // Kopiere den Text in die Zwischenablage let pasteboard = NSPasteboard.general pasteboard.clearContents() pasteboard.setString(textToCopy, forType: .string) } @IBAction func copyRefreshTokenToClipboard(_ sender: Any) { // Hole den Text aus der NSTextView let textToCopy = refreshToken_textview.stringValue // Kopiere den Text in die Zwischenablage let pasteboard = NSPasteboard.general pasteboard.clearContents() pasteboard.setString(textToCopy, forType: .string) } } ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 77; objects = { /* Begin PBXFileReference section */ A77B1D8E2D1F13C50021D982 /* MBAPI2020 Token Helper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "MBAPI2020 Token Helper.app"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ A77B1D902D1F13C50021D982 /* MBAPI2020 Token Helper */ = { isa = PBXFileSystemSynchronizedRootGroup; path = "MBAPI2020 Token Helper"; sourceTree = ""; }; /* End PBXFileSystemSynchronizedRootGroup section */ /* Begin PBXFrameworksBuildPhase section */ A77B1D8B2D1F13C50021D982 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ A77B1D852D1F13C50021D982 = { isa = PBXGroup; children = ( A77B1D902D1F13C50021D982 /* MBAPI2020 Token Helper */, A77B1D8F2D1F13C50021D982 /* Products */, ); sourceTree = ""; }; A77B1D8F2D1F13C50021D982 /* Products */ = { isa = PBXGroup; children = ( A77B1D8E2D1F13C50021D982 /* MBAPI2020 Token Helper.app */, ); name = Products; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ A77B1D8D2D1F13C50021D982 /* MBAPI2020 Token Helper */ = { isa = PBXNativeTarget; buildConfigurationList = A77B1D9D2D1F13C50021D982 /* Build configuration list for PBXNativeTarget "MBAPI2020 Token Helper" */; buildPhases = ( A77B1D8A2D1F13C50021D982 /* Sources */, A77B1D8B2D1F13C50021D982 /* Frameworks */, A77B1D8C2D1F13C50021D982 /* Resources */, ); buildRules = ( ); dependencies = ( ); fileSystemSynchronizedGroups = ( A77B1D902D1F13C50021D982 /* MBAPI2020 Token Helper */, ); name = "MBAPI2020 Token Helper"; packageProductDependencies = ( ); productName = "MBAPI2020 Token Helper"; productReference = A77B1D8E2D1F13C50021D982 /* MBAPI2020 Token Helper.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ A77B1D862D1F13C50021D982 /* Project object */ = { isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; LastSwiftUpdateCheck = 1620; LastUpgradeCheck = 1620; TargetAttributes = { A77B1D8D2D1F13C50021D982 = { CreatedOnToolsVersion = 16.2; }; }; }; buildConfigurationList = A77B1D892D1F13C50021D982 /* Build configuration list for PBXProject "MBAPI2020 Token Helper" */; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, ); mainGroup = A77B1D852D1F13C50021D982; minimizedProjectReferenceProxies = 1; preferredProjectObjectVersion = 77; productRefGroup = A77B1D8F2D1F13C50021D982 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( A77B1D8D2D1F13C50021D982 /* MBAPI2020 Token Helper */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ A77B1D8C2D1F13C50021D982 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ A77B1D8A2D1F13C50021D982 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin XCBuildConfiguration section */ A77B1D9B2D1F13C50021D982 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MACOSX_DEPLOYMENT_TARGET = 15.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; A77B1D9C2D1F13C50021D982 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; LOCALIZATION_PREFERS_STRING_CATALOGS = YES; MACOSX_DEPLOYMENT_TARGET = 15.2; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; }; name = Release; }; A77B1D9E2D1F13C50021D982 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = "MBAPI2020 Token Helper/MBAPI2020_Token_Helper.entitlements"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = 675LSN3VC2; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "MBAPI2020-Token-Helper-Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = "MBAPI2020 Token Helper"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSMainStoryboardFile = Main; INFOPLIST_KEY_NSPrincipalClass = NSApplication; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.5; MARKETING_VERSION = 1.5; PRODUCT_BUNDLE_IDENTIFIER = "de.nulsch.MBAPI2020-Token-Helper"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; }; name = Debug; }; A77B1D9F2D1F13C50021D982 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CODE_SIGN_ENTITLEMENTS = "MBAPI2020 Token Helper/MBAPI2020_Token_Helper.entitlements"; "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 4; DEVELOPMENT_TEAM = 675LSN3VC2; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = "MBAPI2020-Token-Helper-Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = "MBAPI2020 Token Helper"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSMainStoryboardFile = Main; INFOPLIST_KEY_NSPrincipalClass = NSApplication; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.5; MARKETING_VERSION = 1.5; PRODUCT_BUNDLE_IDENTIFIER = "de.nulsch.MBAPI2020-Token-Helper"; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ A77B1D892D1F13C50021D982 /* Build configuration list for PBXProject "MBAPI2020 Token Helper" */ = { isa = XCConfigurationList; buildConfigurations = ( A77B1D9B2D1F13C50021D982 /* Debug */, A77B1D9C2D1F13C50021D982 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; A77B1D9D2D1F13C50021D982 /* Build configuration list for PBXNativeTarget "MBAPI2020 Token Helper" */ = { isa = XCConfigurationList; buildConfigurations = ( A77B1D9E2D1F13C50021D982 /* Debug */, A77B1D9F2D1F13C50021D982 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = A77B1D862D1F13C50021D982 /* Project object */; } ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020 Token Helper.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: token-requester/macOS/MBAPI2020 Token Helper/MBAPI2020-Token-Helper-Info.plist ================================================ CFBundleURLTypes CFBundleTypeRole Editor CFBundleURLName rismycar CFBundleURLSchemes rismycar ================================================ FILE: token-requester/net-core/mb-token-requester/CallbackManager.cs ================================================ using System.IO.Pipes; namespace mbtokenrequester { class CallbackManager { private readonly string _name; public CallbackManager(string name) { _name = name ?? throw new ArgumentNullException(nameof(name)); } public int ClientConnectTimeoutSeconds { get; set; } = 1; public async Task RunClient(string args) { using (var client = new NamedPipeClientStream(".", _name, PipeDirection.Out)) { await client.ConnectAsync(ClientConnectTimeoutSeconds * 1000); using (var sw = new StreamWriter(client) { AutoFlush = true }) { await sw.WriteAsync(args); } } } public async Task RunServer(CancellationToken? token = null) { token = CancellationToken.None; using (var server = new NamedPipeServerStream(_name, PipeDirection.In)) { await server.WaitForConnectionAsync(token.Value); using (var sr = new StreamReader(server)) { var msg = await sr.ReadToEndAsync(); return msg; } } } } } ================================================ FILE: token-requester/net-core/mb-token-requester/DesktopEntryHandler.cs ================================================ using System; using System.IO; using System.Reflection; using System.Runtime; namespace mbtokenrequester { [System.Runtime.Versioning.SupportedOSPlatform("linux")] class DesktopEntryHandler { public DesktopEntryHandler(string uriScheme) { } } } ================================================ FILE: token-requester/net-core/mb-token-requester/Program.cs ================================================ using IdentityModel.Client; using IdentityModel.OidcClient; using System.Diagnostics; using System.Runtime.InteropServices; using Serilog; using Microsoft.Extensions.Configuration; namespace mbtokenrequester { class Program { private static IConfiguration Configuration; static async Task Main(string[] args) { try { Configuration = new ConfigurationBuilder() .AddJsonFile("appsettings.json") .Build(); Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .ReadFrom.Configuration(Configuration) .CreateLogger(); if (args.Any()) { Log.Information($"Args {args[0]}"); await ProcessCallback(args[0]); } else { await Run(); } } catch (Exception ex) { Console.WriteLine(ex.Message); Console.ReadLine(); //Log.Fatal(ex, "Host terminated unexpectedly"); } finally { await Log.CloseAndFlushAsync(); } //Console.ReadLine(); } private static async Task ProcessCallback(string args) { Log.Information($"Args: {args}"); var response = new AuthorizeResponse(args); if (!String.IsNullOrWhiteSpace(response.State)) { Console.WriteLine($"Found state: {response.State}"); var callbackManager = new CallbackManager(response.State); await callbackManager.RunClient(args); } else { Console.WriteLine("Error: no state on response"); } } static async Task Run() { var CustomUriScheme = Configuration["AppSettings:CustomUriScheme"]; if (OperatingSystem.IsWindows()) { new RegistryConfig(CustomUriScheme).Configure(); } Log.Information("+-----------------------+"); Log.Information("| Sign in with OIDC |"); Log.Information("+-----------------------+"); Log.Information(""); if (!OperatingSystem.IsMacOS()) { Log.Information("Press any key to sign in..."); Console.ReadKey(); } Program p = new Program(); await p.SignIn(); if (OperatingSystem.IsWindows()) { new RegistryConfig(CustomUriScheme).DeleteRegKeys(); } } private async Task SignIn() { // create a redirect URI using the custom redirect uri rismycar://login-callback var CustomUriScheme = Configuration["AppSettings:CustomUriScheme"]; string redirectUri = string.Format(CustomUriScheme + Configuration["AppSettings:uri-callback"]); Log.Information("redirect URI: " + redirectUri); // HttpClientHandler handler = new HttpClientHandler(); // handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator; var options = new OidcClientOptions { Authority = Configuration["AppSettings:Authority"], ClientId = Configuration["AppSettings:ClientId"], Scope = Configuration["AppSettings:Scope"], RedirectUri = redirectUri, DisablePushedAuthorization = true, // BackchannelHandler = handler, }; Log.Information(options.ToString()); var client = new OidcClient(options); var state = await client.PrepareLoginAsync(); Log.Information($"Start URL: {state.StartUrl}"); var callbackManager = new CallbackManager(state.State); // open system browser to start authentication Process.Start(new ProcessStartInfo { FileName = state.StartUrl, UseShellExecute = true }); Log.Information("Running callback manager"); var response = await callbackManager.RunServer(); Log.Information($"Response from authorize endpoint: {response}"); // Brings the Console to Focus. if (OperatingSystem.IsWindows()) { BringConsoleToFront(); } var result = await client.ProcessResponseAsync(response, state); if (OperatingSystem.IsWindows()) { BringConsoleToFront(); } if (result.IsError) { Log.Error("\n\nError:\n{0}", result.Error); } else { Log.Information("\n\nClaims:"); foreach (var claim in result.User.Claims) { Log.Information("{0}: {1}", claim.Type, claim.Value); } Console.WriteLine(); Log.Information("Access token:\n{0}", result.AccessToken); Console.WriteLine(); if (!string.IsNullOrWhiteSpace(result.RefreshToken)) { Log.Information("Refresh token:\n{0}", result.RefreshToken); } Console.WriteLine(); Console.WriteLine("Press any key to close the app..."); Console.ReadLine(); } } // Hack to bring the Console window to front. // ref: http://stackoverflow.com/a/12066376 [DllImport("kernel32.dll", ExactSpelling = true)] [System.Runtime.Versioning.SupportedOSPlatform("windows")] public static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] [System.Runtime.Versioning.SupportedOSPlatform("windows")] public static extern bool SetForegroundWindow(IntPtr hWnd); [System.Runtime.Versioning.SupportedOSPlatform("windows")] public void BringConsoleToFront() { SetForegroundWindow(GetConsoleWindow()); } } } ================================================ FILE: token-requester/net-core/mb-token-requester/RegistryConfig.cs ================================================ using System.Reflection; using Microsoft.Win32; using System.Runtime; namespace mbtokenrequester { [System.Runtime.Versioning.SupportedOSPlatform("windows")] class RegistryConfig { public RegistryConfig(string uriScheme) { CustomUriScheme = uriScheme; } public void Configure() { if (NeedToAddKeys()) AddRegKeys(); } public void DeleteRegKeys() { using (var classesKey = Registry.CurrentUser.OpenSubKey(RootKeyPath, true)) { if (classesKey?.OpenSubKey(CustomUriScheme) != null) { classesKey.DeleteSubKeyTree(CustomUriScheme, false); } } } private string CustomUriScheme { get; } string CustomUriSchemeKeyPath => RootKeyPath + @"\" + CustomUriScheme; string CustomUriSchemeKeyValueValue => "URL:" + CustomUriScheme; string CommandKeyPath => CustomUriSchemeKeyPath + @"\shell\open\command"; const string RootKeyPath = @"Software\Classes"; const string CustomUriSchemeKeyValueName = ""; const string ShellKeyName = "shell"; const string OpenKeyName = "open"; const string CommandKeyName = "command"; const string CommandKeyValueName = ""; const string CommandKeyValueFormat = "\"{0}\\callback.bat\" \"%1\""; static string CommandKeyValueValue => string.Format(CommandKeyValueFormat, Path.GetDirectoryName(System.AppContext.BaseDirectory)); const string UrlProtocolValueName = "URL Protocol"; const string UrlProtocolValueValue = ""; bool NeedToAddKeys() { var addKeys = false; using (var commandKey = Registry.CurrentUser.OpenSubKey(CommandKeyPath)) { var commandValue = commandKey?.GetValue(CommandKeyValueName); addKeys |= !CommandKeyValueValue.Equals(commandValue); } using (var customUriSchemeKey = Registry.CurrentUser.OpenSubKey(CustomUriSchemeKeyPath)) { var uriValue = customUriSchemeKey?.GetValue(CustomUriSchemeKeyValueName); var protocolValue = customUriSchemeKey?.GetValue(UrlProtocolValueName); addKeys |= !CustomUriSchemeKeyValueValue.Equals(uriValue); addKeys |= !UrlProtocolValueValue.Equals(protocolValue); } return addKeys; } void AddRegKeys() { using (var classesKey = Registry.CurrentUser.OpenSubKey(RootKeyPath, true)) { using (var root = classesKey!.OpenSubKey(CustomUriScheme, true) ?? classesKey.CreateSubKey(CustomUriScheme, true)) { root.SetValue(CustomUriSchemeKeyValueName, CustomUriSchemeKeyValueValue); root.SetValue(UrlProtocolValueName, UrlProtocolValueValue); using (var shell = root.OpenSubKey(ShellKeyName, true) ?? root.CreateSubKey(ShellKeyName, true)) { using (var open = shell.OpenSubKey(OpenKeyName, true) ?? shell.CreateSubKey(OpenKeyName, true)) { using (var command = open.OpenSubKey(CommandKeyName, true) ?? open.CreateSubKey(CommandKeyName, true)) { command.SetValue(CommandKeyValueName, CommandKeyValueValue); } } } } } } } } ================================================ FILE: token-requester/net-core/mb-token-requester/appsettings.json ================================================ { "AppSettings": { "Authority": "https://id.mercedes-benz.com/", "ClientId": "62778dc4-1de3-44f4-af95-115f06a3a008", "CustomUriScheme": "rismycar", "Scope": "openid email phone profile offline_access ciam-uid", "uri-callback": "://login-callback" }, "Logging": { "LogLevel": { "Default": "Debug" } }, "Serilog": { "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ], "WriteTo": [ //{ // "Name": "File", // "Args": { // "path": "log.txt", // "rollingInterval": "Day", // "shared": true // } //}, {"Name": "Console"} ] } } ================================================ FILE: token-requester/net-core/mb-token-requester/callback.bat ================================================ @echo off "%~dp0mb-token-requester.exe" %* ================================================ FILE: token-requester/net-core/mb-token-requester/mb-shortcut-handler.desktop ================================================ [Desktop Entry] Version=1.0 Type=Application Name=MBTockenCreator Exec=~/temp/linux-x64/mb-token-requester %u Icon= MimeType=x-scheme-handler/rismycar; Terminal=True ================================================ FILE: token-requester/net-core/mb-token-requester/mb-token-requester.csproj ================================================  Exe net8.0 enable enable True AnyCPU;x64 win-x64;win-arm64;linux-x64 $([System.IO.Path]::Combine($(OutputPath),'package'))/ $([System.IO.Path]::Combine($(PackageDir),'publish.zip')) Always Never Always Always Always ================================================ FILE: token-requester/net-core/mb-token-requester/mb-token-requester.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.12.35527.113 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "mb-token-requester", "mb-token-requester.csproj", "{2A5E7CF4-5871-4827-AFEA-106A83367680}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2A5E7CF4-5871-4827-AFEA-106A83367680}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2A5E7CF4-5871-4827-AFEA-106A83367680}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A5E7CF4-5871-4827-AFEA-106A83367680}.Debug|x64.ActiveCfg = Debug|x64 {2A5E7CF4-5871-4827-AFEA-106A83367680}.Debug|x64.Build.0 = Debug|x64 {2A5E7CF4-5871-4827-AFEA-106A83367680}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A5E7CF4-5871-4827-AFEA-106A83367680}.Release|Any CPU.Build.0 = Release|Any CPU {2A5E7CF4-5871-4827-AFEA-106A83367680}.Release|x64.ActiveCfg = Release|x64 {2A5E7CF4-5871-4827-AFEA-106A83367680}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal