]> git.basschouten.com Git - openhab-addons.git/commitdiff
[tesla] Fix discovery of Tesla vehicles from account (#14070)
authorKai Kreuzer <kai@openhab.org>
Sat, 31 Dec 2022 09:22:39 +0000 (10:22 +0100)
committerGitHub <noreply@github.com>
Sat, 31 Dec 2022 09:22:39 +0000 (10:22 +0100)
* Fix discovery of Tesla vehicles from account

Signed-off-by: Kai Kreuzer <kai@openhab.org>
bundles/org.openhab.binding.tesla/README.md
bundles/org.openhab.binding.tesla/src/main/java/org/openhab/binding/tesla/internal/TeslaBindingConstants.java
bundles/org.openhab.binding.tesla/src/main/java/org/openhab/binding/tesla/internal/TeslaHandlerFactory.java
bundles/org.openhab.binding.tesla/src/main/java/org/openhab/binding/tesla/internal/discovery/TeslaVehicleDiscoveryService.java
bundles/org.openhab.binding.tesla/src/main/java/org/openhab/binding/tesla/internal/handler/TeslaAccountHandler.java
bundles/org.openhab.binding.tesla/src/main/java/org/openhab/binding/tesla/internal/handler/VehicleListener.java
bundles/org.openhab.binding.tesla/src/main/java/org/openhab/binding/tesla/internal/protocol/VehicleConfig.java
bundles/org.openhab.binding.tesla/src/main/resources/OH-INF/i18n/tesla.properties
bundles/org.openhab.binding.tesla/src/main/resources/OH-INF/thing/channels.xml
bundles/org.openhab.binding.tesla/src/main/resources/OH-INF/thing/vehicle.xml [new file with mode: 0644]

index 85ba33109652c33fc3cb0d70e2ad3dc5e9643634..ae4b6ec836bc8f856932b1ad1bfebd81203883b3 100644 (file)
@@ -22,9 +22,11 @@ Access is established through a Tesla account as a bridge.
 
 The account cannot be automatically discovered, but has to be created manually.
 
-Once an account is configured, it is automatically queried for associated vehicles and an Inbox entry is created for each of them.
+Once an account is configured, it is queried for associated vehicles and an Inbox entry is created for each of them.
 
-Note: Vehicles that are asleep might not be discovered, so you might want to wake it up through the Tesla app first.
+Note: Vehicles that are asleep are discovered and put into the Inbox, but their model cannot be determined.
+As an effect, their channels are missing until the vehicle wakes up and can be fully queried.
+A vehicle can be manually woken up by opening the Tesla app and checking the vehicle status in there.
 
 
 ## Bridge Configuration
index f75638e0cc866224971a2dc00b54f287eb34bc52..20ef0da8bcd143a0f5aaaef1154609dd3e55235f 100644 (file)
@@ -84,6 +84,7 @@ public class TeslaBindingConstants {
 
     // List of all Thing Type UIDs
     public static final ThingTypeUID THING_TYPE_ACCOUNT = new ThingTypeUID(BINDING_ID, "account");
+    public static final ThingTypeUID THING_TYPE_VEHICLE = new ThingTypeUID(BINDING_ID, "vehicle");
     public static final ThingTypeUID THING_TYPE_MODELS = new ThingTypeUID(BINDING_ID, "models");
     public static final ThingTypeUID THING_TYPE_MODEL3 = new ThingTypeUID(BINDING_ID, "model3");
     public static final ThingTypeUID THING_TYPE_MODELX = new ThingTypeUID(BINDING_ID, "modelx");
index d89fea388cd259ef958018c4d5d607682faf6c6e..613cad0d00740ca70a902492b14edb30292e9160 100644 (file)
@@ -27,6 +27,7 @@ import org.openhab.core.io.net.http.HttpClientFactory;
 import org.openhab.core.io.net.http.WebSocketFactory;
 import org.openhab.core.thing.Bridge;
 import org.openhab.core.thing.Thing;
+import org.openhab.core.thing.ThingTypeMigrationService;
 import org.openhab.core.thing.ThingTypeUID;
 import org.openhab.core.thing.binding.BaseThingHandlerFactory;
 import org.openhab.core.thing.binding.ThingHandler;
@@ -50,21 +51,24 @@ public class TeslaHandlerFactory extends BaseThingHandlerFactory {
     private static final int EVENT_STREAM_CONNECT_TIMEOUT = 3;
     private static final int EVENT_STREAM_READ_TIMEOUT = 200;
 
-    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT, THING_TYPE_MODELS,
-            THING_TYPE_MODEL3, THING_TYPE_MODELX, THING_TYPE_MODELY);
+    public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_ACCOUNT, THING_TYPE_VEHICLE,
+            THING_TYPE_MODELS, THING_TYPE_MODEL3, THING_TYPE_MODELX, THING_TYPE_MODELY);
 
     private final ClientBuilder clientBuilder;
     private final HttpClientFactory httpClientFactory;
     private final WebSocketFactory webSocketFactory;
+    private final ThingTypeMigrationService thingTypeMigrationService;
 
     @Activate
     public TeslaHandlerFactory(@Reference ClientBuilder clientBuilder, @Reference HttpClientFactory httpClientFactory,
-            final @Reference WebSocketFactory webSocketFactory) {
+            final @Reference WebSocketFactory webSocketFactory,
+            final @Reference ThingTypeMigrationService thingTypeMigrationService) {
         this.clientBuilder = clientBuilder //
                 .connectTimeout(EVENT_STREAM_CONNECT_TIMEOUT, TimeUnit.SECONDS)
                 .readTimeout(EVENT_STREAM_READ_TIMEOUT, TimeUnit.SECONDS);
         this.httpClientFactory = httpClientFactory;
         this.webSocketFactory = webSocketFactory;
+        this.thingTypeMigrationService = thingTypeMigrationService;
     }
 
     @Override
@@ -77,7 +81,8 @@ public class TeslaHandlerFactory extends BaseThingHandlerFactory {
         ThingTypeUID thingTypeUID = thing.getThingTypeUID();
 
         if (thingTypeUID.equals(THING_TYPE_ACCOUNT)) {
-            return new TeslaAccountHandler((Bridge) thing, clientBuilder.build(), httpClientFactory);
+            return new TeslaAccountHandler((Bridge) thing, clientBuilder.build(), httpClientFactory,
+                    thingTypeMigrationService);
         } else {
             return new TeslaVehicleHandler(thing, webSocketFactory);
         }
index 1154c6d62084b7738afae97b07d025fc1969e577..728c4114ce0be7d2475a2c6d4b4c7dde5906cd01 100644 (file)
@@ -81,8 +81,10 @@ public class TeslaVehicleDiscoveryService extends AbstractDiscoveryService
 
     @Override
     public void vehicleFound(Vehicle vehicle, VehicleConfig vehicleConfig) {
-        ThingTypeUID type = identifyModel(vehicleConfig);
+        ThingTypeUID type = vehicleConfig == null ? TeslaBindingConstants.THING_TYPE_VEHICLE
+                : vehicleConfig.identifyModel();
         if (type != null) {
+            logger.debug("Found a {} vehicle", type.getId());
             ThingUID thingUID = new ThingUID(type, handler.getThing().getUID(), vehicle.vin);
             DiscoveryResult discoveryResult = DiscoveryResultBuilder.create(thingUID).withLabel(vehicle.display_name)
                     .withBridge(handler.getThing().getUID()).withProperty(TeslaBindingConstants.VIN, vehicle.vin)
@@ -90,22 +92,4 @@ public class TeslaVehicleDiscoveryService extends AbstractDiscoveryService
             thingDiscovered(discoveryResult);
         }
     }
-
-    private ThingTypeUID identifyModel(VehicleConfig vehicleConfig) {
-        logger.debug("Found a {} vehicle", vehicleConfig.car_type);
-        switch (vehicleConfig.car_type) {
-            case "models":
-            case "models2":
-                return TeslaBindingConstants.THING_TYPE_MODELS;
-            case "modelx":
-                return TeslaBindingConstants.THING_TYPE_MODELX;
-            case "model3":
-                return TeslaBindingConstants.THING_TYPE_MODEL3;
-            case "modely":
-                return TeslaBindingConstants.THING_TYPE_MODELY;
-            default:
-                logger.debug("Found unknown vehicle type '{}' - ignoring it.", vehicleConfig.car_type);
-                return null;
-        }
-    }
 }
index d803d03a08615fd6688f5d49b9155ad8de7e9579..5d51530a9427e91ba03d10b5026c4de106dbba27 100644 (file)
@@ -32,6 +32,7 @@ import javax.ws.rs.client.WebTarget;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
+import org.openhab.binding.tesla.internal.TeslaBindingConstants;
 import org.openhab.binding.tesla.internal.discovery.TeslaVehicleDiscoveryService;
 import org.openhab.binding.tesla.internal.protocol.Vehicle;
 import org.openhab.binding.tesla.internal.protocol.VehicleConfig;
@@ -43,6 +44,7 @@ import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
 import org.openhab.core.thing.ThingStatusDetail;
 import org.openhab.core.thing.ThingStatusInfo;
+import org.openhab.core.thing.ThingTypeMigrationService;
 import org.openhab.core.thing.binding.BaseBridgeHandler;
 import org.openhab.core.thing.binding.ThingHandlerService;
 import org.openhab.core.types.Command;
@@ -80,6 +82,7 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
     final WebTarget wakeUpTarget;
 
     private final TeslaSSOHandler ssoHandler;
+    private final ThingTypeMigrationService thingTypeMigrationService;
 
     // Threading and Job related variables
     protected ScheduledFuture<?> connectJob;
@@ -96,10 +99,12 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
     private TokenResponse logonToken;
     private final Set<VehicleListener> vehicleListeners = new HashSet<>();
 
-    public TeslaAccountHandler(Bridge bridge, Client teslaClient, HttpClientFactory httpClientFactory) {
+    public TeslaAccountHandler(Bridge bridge, Client teslaClient, HttpClientFactory httpClientFactory,
+            ThingTypeMigrationService thingTypeMigrationService) {
         super(bridge);
         this.teslaTarget = teslaClient.target(URI_OWNERS);
         this.ssoHandler = new TeslaSSOHandler(httpClientFactory.getCommonHttpClient());
+        this.thingTypeMigrationService = thingTypeMigrationService;
 
         this.vehiclesTarget = teslaTarget.path(API_VERSION).path(VEHICLES);
         this.vehicleTarget = vehiclesTarget.path(PATH_VEHICLE_ID);
@@ -222,10 +227,10 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
 
             for (Vehicle vehicle : vehicleArray) {
                 String responseString = invokeAndParse(vehicle.id, VEHICLE_CONFIG, null, dataRequestTarget, 0);
-                if (responseString == null || responseString.isBlank()) {
-                    continue;
+                VehicleConfig vehicleConfig = null;
+                if (responseString != null && !responseString.isBlank()) {
+                    vehicleConfig = gson.fromJson(responseString, VehicleConfig.class);
                 }
-                VehicleConfig vehicleConfig = gson.fromJson(responseString, VehicleConfig.class);
                 for (VehicleListener listener : vehicleListeners) {
                     listener.vehicleFound(vehicle, vehicleConfig);
                 }
@@ -233,6 +238,15 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
                     if (vehicle.vin.equals(vehicleThing.getConfiguration().get(VIN))) {
                         TeslaVehicleHandler vehicleHandler = (TeslaVehicleHandler) vehicleThing.getHandler();
                         if (vehicleHandler != null) {
+                            if (TeslaBindingConstants.THING_TYPE_VEHICLE.equals(vehicleThing.getThingTypeUID())
+                                    && vehicleConfig != null) {
+                                // Seems the type of this vehicle has not been identified before, so let's switch the
+                                // thing type of it
+                                thingTypeMigrationService.migrateThingType(vehicleThing, vehicleConfig.identifyModel(),
+                                        vehicleThing.getConfiguration());
+                                break;
+
+                            }
                             logger.debug("Querying the vehicle: VIN {}", vehicle.vin);
                             String vehicleJSON = gson.toJson(vehicle);
                             vehicleHandler.parseAndUpdate("queryVehicle", null, vehicleJSON);
@@ -353,8 +367,9 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
             lock.lock();
 
             ThingStatusInfo status = getThing().getStatusInfo();
-            if (status.getStatus() != ThingStatus.ONLINE
-                    && status.getStatusDetail() != ThingStatusDetail.CONFIGURATION_ERROR) {
+            if ((status.getStatus() != ThingStatus.ONLINE
+                    && status.getStatusDetail() != ThingStatusDetail.CONFIGURATION_ERROR)
+                    || hasUnidentifiedVehicles()) {
                 logger.debug("Setting up an authenticated connection to the Tesla back-end");
 
                 ThingStatusInfo authenticationResult = authenticate();
@@ -415,6 +430,11 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
         }
     };
 
+    private boolean hasUnidentifiedVehicles() {
+        return getThing().getThings().stream()
+                .anyMatch(vehicle -> TeslaBindingConstants.THING_TYPE_VEHICLE.equals(vehicle.getThingTypeUID()));
+    }
+
     protected class Request implements Runnable {
 
         private static final int NO_OF_RETRIES = 3;
index a72360c077aeef6bcfd5f231f70a924b0fe5453f..265ff39a7b9a11f2d99fd55d2124c2ec736fa372 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.tesla.internal.handler;
 
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.binding.tesla.internal.protocol.Vehicle;
 import org.openhab.binding.tesla.internal.protocol.VehicleConfig;
 
@@ -21,12 +23,14 @@ import org.openhab.binding.tesla.internal.protocol.VehicleConfig;
  *
  * @author Kai Kreuzer - Initial contribution
  */
+@NonNullByDefault
 public interface VehicleListener {
 
     /**
      * This method is called by the {@link TeslaAccountHandler}, if a vehicle is identified.
      *
      * @param vehicle a vehicle that was found within an account.
+     * @param vehicleConfig vehicle configuration that was read from the vehicle or null, if not available.
      */
-    void vehicleFound(Vehicle vehicle, VehicleConfig vehicleConfig);
+    void vehicleFound(Vehicle vehicle, @Nullable VehicleConfig vehicleConfig);
 }
index f2b04d296e8df1b9649fbcda863e5a05efabf45a..674e7bf953884a198b4d9b2baff005284bb7487a 100644 (file)
@@ -12,6 +12,9 @@
  */
 package org.openhab.binding.tesla.internal.protocol;
 
+import org.openhab.binding.tesla.internal.TeslaBindingConstants;
+import org.openhab.core.thing.ThingTypeUID;
+
 /**
  * The {@link VehicleConfig} is a data structure to capture
  * vehicle configuration variables sent by the Tesla Vehicle
@@ -41,4 +44,20 @@ public class VehicleConfig {
     public String third_row_seats;
     public String trim_badging;
     public String wheel_type;
+
+    public ThingTypeUID identifyModel() {
+        switch (car_type) {
+            case "models":
+            case "models2":
+                return TeslaBindingConstants.THING_TYPE_MODELS;
+            case "modelx":
+                return TeslaBindingConstants.THING_TYPE_MODELX;
+            case "model3":
+                return TeslaBindingConstants.THING_TYPE_MODEL3;
+            case "modely":
+                return TeslaBindingConstants.THING_TYPE_MODELY;
+            default:
+                return TeslaBindingConstants.THING_TYPE_VEHICLE;
+        }
+    }
 }
index 3dd21b338581e8c80e1825e62bc96a70b923377c..f42d75bd73a4cabd45802d9d051fec20b54cdc11 100644 (file)
@@ -15,6 +15,8 @@ thing-type.tesla.modelx.label = Tesla Model X
 thing-type.tesla.modelx.description = A Tesla Model X Vehicle
 thing-type.tesla.modely.label = Tesla Model Y
 thing-type.tesla.modely.description = A Tesla Model Y Vehicle
+thing-type.tesla.vehicle.label = Tesla
+thing-type.tesla.vehicle.description = A Tesla Vehicle
 
 # thing types config
 
@@ -24,6 +26,14 @@ thing-type.config.tesla.model3.allowWakeup.label = Allow Wake-Up
 thing-type.config.tesla.model3.allowWakeup.description = Allows waking up the vehicle. Caution: This can result in huge vampire drain!
 thing-type.config.tesla.model3.allowWakeupForCommands.label = Allow Wake-Up For Commands
 thing-type.config.tesla.model3.allowWakeupForCommands.description = Allows waking up the vehicle, when commands are sent to it. Execution of commands will be delayed in this case and you could cause the vehicle to stay awake very long.
+thing-type.config.tesla.model3.enableEvents.label = Enable Events
+thing-type.config.tesla.model3.enableEvents.description = Enable the event stream for the vehicle
+thing-type.config.tesla.model3.inactivity.label = Inactivity Interval
+thing-type.config.tesla.model3.inactivity.description = The inactivity period in minutes, after which the binding stops for 20 minutes to let the car sleep.
+thing-type.config.tesla.model3.useAdvancedStatesForPolling.label = Use Console Modes and Occupancy for Inactivity
+thing-type.config.tesla.model3.useAdvancedStatesForPolling.description = Use these states to help continue the fast polling of the API. Do not back off polling if in these states.
+thing-type.config.tesla.model3.useDriveState.label = Use Drive State for Inactivity
+thing-type.config.tesla.model3.useDriveState.description = Use the drive state instead of location to determine vehicle inactivity.
 thing-type.config.tesla.model3.valetpin.label = Valet PIN
 thing-type.config.tesla.model3.valetpin.description = PIN to use when enabling Valet Mode
 thing-type.config.tesla.model3.vin.label = Vehicle Identification Number
@@ -32,6 +42,14 @@ thing-type.config.tesla.models.allowWakeup.label = Allow Wake-Up
 thing-type.config.tesla.models.allowWakeup.description = Allows waking up the vehicle. Caution: This can result in huge vampire drain!
 thing-type.config.tesla.models.allowWakeupForCommands.label = Allow Wake-Up For Commands
 thing-type.config.tesla.models.allowWakeupForCommands.description = Allows waking up the vehicle, when commands are sent to it. Execution of commands will be delayed in this case and you could cause the vehicle to stay awake very long.
+thing-type.config.tesla.models.enableEvents.label = Enable Events
+thing-type.config.tesla.models.enableEvents.description = Enable the event stream for the vehicle
+thing-type.config.tesla.models.inactivity.label = Inactivity Interval
+thing-type.config.tesla.models.inactivity.description = The inactivity period in minutes, after which the binding stops for 20 minutes to let the car sleep.
+thing-type.config.tesla.models.useAdvancedStatesForPolling.label = Use Console Modes and Occupancy for Inactivity
+thing-type.config.tesla.models.useAdvancedStatesForPolling.description = Use these states to help continue the fast polling of the API. Do not back off polling if in these states.
+thing-type.config.tesla.models.useDriveState.label = Use Drive State for Inactivity
+thing-type.config.tesla.models.useDriveState.description = Use the drive state instead of location to determine vehicle inactivity.
 thing-type.config.tesla.models.valetpin.label = Valet PIN
 thing-type.config.tesla.models.valetpin.description = PIN to use when enabling Valet Mode
 thing-type.config.tesla.models.vin.label = Vehicle Identification Number
@@ -40,6 +58,14 @@ thing-type.config.tesla.modelx.allowWakeup.label = Allow Wake-Up
 thing-type.config.tesla.modelx.allowWakeup.description = Allows waking up the vehicle. Caution: This can result in huge vampire drain!
 thing-type.config.tesla.modelx.allowWakeupForCommands.label = Allow Wake-Up For Commands
 thing-type.config.tesla.modelx.allowWakeupForCommands.description = Allows waking up the vehicle, when commands are sent to it. Execution of commands will be delayed in this case and you could cause the vehicle to stay awake very long.
+thing-type.config.tesla.modelx.enableEvents.label = Enable Events
+thing-type.config.tesla.modelx.enableEvents.description = Enable the event stream for the vehicle
+thing-type.config.tesla.modelx.inactivity.label = Inactivity Interval
+thing-type.config.tesla.modelx.inactivity.description = The inactivity period in minutes, after which the binding stops for 20 minutes to let the car sleep.
+thing-type.config.tesla.modelx.useAdvancedStatesForPolling.label = Use Console Modes and Occupancy for Inactivity
+thing-type.config.tesla.modelx.useAdvancedStatesForPolling.description = Use these states to help continue the fast polling of the API. Do not back off polling if in these states.
+thing-type.config.tesla.modelx.useDriveState.label = Use Drive State for Inactivity
+thing-type.config.tesla.modelx.useDriveState.description = Use the drive state instead of location to determine vehicle inactivity.
 thing-type.config.tesla.modelx.valetpin.label = Valet PIN
 thing-type.config.tesla.modelx.valetpin.description = PIN to use when enabling Valet Mode
 thing-type.config.tesla.modelx.vin.label = Vehicle Identification Number
@@ -48,10 +74,34 @@ thing-type.config.tesla.modely.allowWakeup.label = Allow Wake-Up
 thing-type.config.tesla.modely.allowWakeup.description = Allows waking up the vehicle. Caution: This can result in huge vampire drain!
 thing-type.config.tesla.modely.allowWakeupForCommands.label = Allow Wake-Up For Commands
 thing-type.config.tesla.modely.allowWakeupForCommands.description = Allows waking up the vehicle, when commands are sent to it. Execution of commands will be delayed in this case and you could cause the vehicle to stay awake very long.
+thing-type.config.tesla.modely.enableEvents.label = Enable Events
+thing-type.config.tesla.modely.enableEvents.description = Enable the event stream for the vehicle
+thing-type.config.tesla.modely.inactivity.label = Inactivity Interval
+thing-type.config.tesla.modely.inactivity.description = The inactivity period in minutes, after which the binding stops for 20 minutes to let the car sleep.
+thing-type.config.tesla.modely.useAdvancedStatesForPolling.label = Use Console Modes and Occupancy for Inactivity
+thing-type.config.tesla.modely.useAdvancedStatesForPolling.description = Use these states to help continue the fast polling of the API. Do not back off polling if in these states.
+thing-type.config.tesla.modely.useDriveState.label = Use Drive State for Inactivity
+thing-type.config.tesla.modely.useDriveState.description = Use the drive state instead of location to determine vehicle inactivity.
 thing-type.config.tesla.modely.valetpin.label = Valet PIN
 thing-type.config.tesla.modely.valetpin.description = PIN to use when enabling Valet Mode
 thing-type.config.tesla.modely.vin.label = Vehicle Identification Number
 thing-type.config.tesla.modely.vin.description = VIN of the vehicle
+thing-type.config.tesla.vehicle.allowWakeup.label = Allow Wake-Up
+thing-type.config.tesla.vehicle.allowWakeup.description = Allows waking up the vehicle. Caution: This can result in huge vampire drain!
+thing-type.config.tesla.vehicle.allowWakeupForCommands.label = Allow Wake-Up For Commands
+thing-type.config.tesla.vehicle.allowWakeupForCommands.description = Allows waking up the vehicle, when commands are sent to it. Execution of commands will be delayed in this case and you could cause the vehicle to stay awake very long.
+thing-type.config.tesla.vehicle.enableEvents.label = Enable Events
+thing-type.config.tesla.vehicle.enableEvents.description = Enable the event stream for the vehicle
+thing-type.config.tesla.vehicle.inactivity.label = Inactivity Interval
+thing-type.config.tesla.vehicle.inactivity.description = The inactivity period in minutes, after which the binding stops for 20 minutes to let the car sleep.
+thing-type.config.tesla.vehicle.useAdvancedStatesForPolling.label = Use Console Modes and Occupancy for Inactivity
+thing-type.config.tesla.vehicle.useAdvancedStatesForPolling.description = Use these states to help continue the fast polling of the API. Do not back off polling if in these states.
+thing-type.config.tesla.vehicle.useDriveState.label = Use Drive State for Inactivity
+thing-type.config.tesla.vehicle.useDriveState.description = Use the drive state instead of location to determine vehicle inactivity.
+thing-type.config.tesla.vehicle.valetpin.label = Valet PIN
+thing-type.config.tesla.vehicle.valetpin.description = PIN to use when enabling Valet Mode
+thing-type.config.tesla.vehicle.vin.label = Vehicle Identification Number
+thing-type.config.tesla.vehicle.vin.description = VIN of the vehicle
 
 # channel types
 
@@ -206,7 +256,7 @@ channel-type.tesla.minavailabletemp.label = Minimum Temperature
 channel-type.tesla.minavailabletemp.description = Indicates the minimal inside temperature of the vehicle
 channel-type.tesla.mobileenabled.label = Mobile Enabled
 channel-type.tesla.mobileenabled.description = Indicates whether the vehicle can be remotely controlled
-channel-type.tesla.notenoughpower.label = Not Enought Power
+channel-type.tesla.notenoughpower.label = Not Enough Power
 channel-type.tesla.notenoughpower.description = Indicates if not enough power (ON) is available to heat the vehicle
 channel-type.tesla.notificationsenabled.label = Notifications Enabled
 channel-type.tesla.notificationsenabled.description = Not documented / To be defined
index 1d092f763f13e1140062f07eb87577387e9a220d..7355d5f368e507406dbd4ff8f787c66314e8eb3c 100644 (file)
        </channel-type>
        <channel-type id="notenoughpower" advanced="true">
                <item-type>Switch</item-type>
-               <label>Not Enought Power</label>
+               <label>Not Enough Power</label>
                <description>Indicates if not enough power (ON) is available to heat the vehicle</description>
                <state readOnly="true"></state>
        </channel-type>
diff --git a/bundles/org.openhab.binding.tesla/src/main/resources/OH-INF/thing/vehicle.xml b/bundles/org.openhab.binding.tesla/src/main/resources/OH-INF/thing/vehicle.xml
new file mode 100644 (file)
index 0000000..e59b591
--- /dev/null
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<thing:thing-descriptions bindingId="tesla"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
+       xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
+
+       <thing-type id="vehicle">
+
+               <supported-bridge-type-refs>
+                       <bridge-type-ref id="account"/>
+               </supported-bridge-type-refs>
+
+               <label>Tesla</label>
+               <description>A Tesla Vehicle</description>
+
+               <config-description>
+                       <parameter name="vin" type="text" required="true">
+                               <label>Vehicle Identification Number</label>
+                               <description>VIN of the vehicle</description>
+                       </parameter>
+                       <parameter name="valetpin" type="integer" min="0" max="9999" required="false">
+                               <context>password</context>
+                               <label>Valet PIN</label>
+                               <description>PIN to use when enabling Valet Mode</description>
+                       </parameter>
+                       <parameter name="allowWakeup" type="boolean" required="false">
+                               <default>false</default>
+                               <label>Allow Wake-Up</label>
+                               <advanced>true</advanced>
+                               <description>Allows waking up the vehicle. Caution: This can result in huge vampire drain!</description>
+                       </parameter>
+                       <parameter name="allowWakeupForCommands" type="boolean" required="false">
+                               <default>false</default>
+                               <label>Allow Wake-Up For Commands</label>
+                               <description>Allows waking up the vehicle, when commands are sent to it. Execution of commands will be delayed in
+                                       this case and you could cause the vehicle to stay awake very long.</description>
+                       </parameter>
+                       <parameter name="enableEvents" type="boolean" required="false">
+                               <default>false</default>
+                               <label>Enable Events</label>
+                               <advanced>true</advanced>
+                               <description>Enable the event stream for the vehicle</description>
+                       </parameter>
+                       <parameter name="inactivity" type="integer" min="5" required="false">
+                               <label>Inactivity Interval</label>
+                               <advanced>true</advanced>
+                               <description>The inactivity period in minutes, after which the binding stops for 20 minutes to let the car sleep.</description>
+                               <default>5</default>
+                       </parameter>
+                       <parameter name="useDriveState" type="boolean" required="false">
+                               <default>false</default>
+                               <label>Use Drive State for Inactivity</label>
+                               <advanced>true</advanced>
+                               <description>Use the drive state instead of location to determine vehicle inactivity.</description>
+                       </parameter>
+                       <parameter name="useAdvancedStatesForPolling" type="boolean" required="false">
+                               <default>false</default>
+                               <label>Use Console Modes and Occupancy for Inactivity</label>
+                               <advanced>true</advanced>
+                               <description>Use these states to help continue the fast polling of the API. Do not back off polling if in these
+                                       states.</description>
+                       </parameter>
+               </config-description>
+
+       </thing-type>
+
+</thing:thing-descriptions>