mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[tesla] Adapt binding to changed API from Tesla backend (#14924)
* Adapt binding to changed API from Tesla backend * Add new translations and vehicle thing type Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
parent
91450d0708
commit
bf2ce7b418
@ -22,10 +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.
|
||||
|
||||
Note: Vehicles that are asleep might not be discovered, so you might want to wake it up through the Tesla app first.
|
||||
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 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
|
||||
|
||||
@ -40,7 +41,6 @@ Please note that we in general consider it dangerous to enter your credentials i
|
||||
|
||||
When using one of such apps, simply copy and paste the received refresh token into the account configuration.
|
||||
|
||||
|
||||
## Thing Configuration Parameters
|
||||
|
||||
The vehicle Thing requires the vehicle's VIN as a configuration parameter `vin`.
|
||||
@ -52,8 +52,7 @@ Additionally, the follow optional parameters may be defined.
|
||||
| valetpin | Valet PIN | false | PIN to use when enabling Valet Mode |
|
||||
| allowWakeupForCommands | Allow Wake-Up For Commands | false | Wake up the vehicle to send commands. May cause vehicle to stay awake |
|
||||
|
||||
|
||||
For further flexibility and experimentation, the following advanced parameters may also be set.
|
||||
For further flexibility and experimentation, the following advanced parameters may also be set.
|
||||
|
||||
| Parameter Name | Label | Default Value | Description |
|
||||
|-----------------------------|------------------------------------------------|---------------|----------------------------------------------------------------------------------------------------|
|
||||
@ -64,13 +63,12 @@ For further flexibility and experimentation, the following advanced parameters m
|
||||
| useAdvancedStatesForPolling | Use Console Modes and Occupancy for Inactivity | false | Use these states to help continue the fast polling of the API |
|
||||
|
||||
`allowWakeup` should be used with caution as this determines whether openHAB is allowed to wake up the vehicle in order to retrieve data from it.
|
||||
This setting is not recommended as it will result in a significant vampire drain (i.e. energy consumption although the vehicle is parking).
|
||||
This setting is not recommended as it will result in a significant vampire drain (i.e. energy consumption although the vehicle is parking).
|
||||
|
||||
`enableEvents` captures and processes data in near real-time for key variables by enabling events streamed by the Tesla back-end system.
|
||||
|
||||
`inactivity` setting is ignored and will always be five minutes if homelink is available (car is at home)
|
||||
|
||||
|
||||
## Channels
|
||||
|
||||
All vehicles support a huge number of channels - the following list shows the standard ones:
|
||||
@ -88,7 +86,6 @@ All vehicles support a huge number of channels - the following list shows the st
|
||||
| odometer | Number:Length | Odometer | Odometer of the vehicle |
|
||||
| speed | Number:Speed | Speed | Vehicle speed |
|
||||
|
||||
|
||||
Additionally, these advanced channels are available (not all are available on all vehicle types, e.g., the sunroof):
|
||||
|
||||
| Channel ID | Item Type | Label | Description |
|
||||
@ -100,7 +97,7 @@ Additionally, these advanced channels are available (not all are available on al
|
||||
| batteryheaternopower | Switch | Battery Heater Power | Indicates if there is enough power to use the battery heater |
|
||||
| batteryrange | Number:Length | Battery Range | Range of the battery |
|
||||
| calendarenabled | Switch | Calendar Enabled | Indicates if access to a remote calendar is enabled |
|
||||
| centerdisplay | Number | Central Display State | Indicates the state of the central display in the vehicle, see [here](https://tesla-api.timdorr.com/vehicle/state/vehiclestate) for valid values |
|
||||
| centerdisplay | Number | Central Display State | Indicates the state of the central display in the vehicle, see [here](https://tesla-api.timdorr.com/vehicle/state/vehiclestate) for valid values |
|
||||
| centerrearseatheater | Switch | Center Rear Seat Heater | Indicates if the center rear seat heater is switched on |
|
||||
| charge | Switch | Charge | Start (ON) or stop (OFF) charging |
|
||||
| chargecable | String | Charge Cable | Undocumented / To be defined |
|
||||
@ -195,13 +192,11 @@ Additionally, these advanced channels are available (not all are available on al
|
||||
| wakeup | Switch | Wake Up | Wake up the vehicle from a (deep) sleep |
|
||||
| wiperbladeheater | Switch | Wiperblade Heater | Indicates if the wiperblade heater is switched on |
|
||||
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
demo.Things:
|
||||
|
||||
```
|
||||
```java
|
||||
Bridge tesla:account:myaccount "My Tesla Account" [ refreshToken="xxxx" ] {
|
||||
model3 mycar "My favorite car" [ vin="5YJSA7H25FFP53736"]
|
||||
}
|
||||
@ -209,70 +204,70 @@ Bridge tesla:account:myaccount "My Tesla Account" [ refreshToken="xxxx" ] {
|
||||
|
||||
demo.items:
|
||||
|
||||
```
|
||||
DateTime TeslaEventstamp {channel="model3:myaccount:mycar:eventstamp"}
|
||||
String TeslaState {channel="model3:myaccount:mycar:state"}
|
||||
Number TeslaSpeed {channel="model3:myaccount:mycar:speed"}
|
||||
String TeslaShiftState {channel="model3:myaccount:mycar:shiftstate"}
|
||||
Number TeslaOdometer {channel="model3:myaccount:mycar:odometer"}
|
||||
Number TeslaRange {channel="model3:myaccount:mycar:range"}
|
||||
```java
|
||||
DateTime TeslaEventstamp {channel="account:model3:myaccount:mycar:eventstamp"}
|
||||
String TeslaState {channel="account:model3:myaccount:mycar:state"}
|
||||
Number TeslaSpeed {channel="account:model3:myaccount:mycar:speed"}
|
||||
String TeslaShiftState {channel="account:model3:myaccount:mycar:shiftstate"}
|
||||
Number TeslaOdometer {channel="account:model3:myaccount:mycar:odometer"}
|
||||
Number TeslaRange {channel="account:model3:myaccount:mycar:range"}
|
||||
|
||||
Number TeslaBatteryLevel {channel="model3:myaccount:mycar:batterylevel"}
|
||||
Number TeslaPower {channel="model3:myaccount:mycar:power"}
|
||||
Number TeslaBatteryCurrent {channel="model3:myaccount:mycar:batterycurrent"}
|
||||
Number TeslaBatteryRange {channel="model3:myaccount:mycar:batteryrange"}
|
||||
Number TeslaEstBatteryRange {channel="model3:myaccount:mycar:estimatedbatteryrange"}
|
||||
Number TeslaIdealBatteryRange {channel="model3:myaccount:mycar:idealbatteryrange"}
|
||||
Number TeslaUsableBatteryLevel {channel="model3:myaccount:mycar:usablebatterylevel"}
|
||||
Switch TeslaPreconditioning {channel="model3:myaccount:mycar:preconditioning"}
|
||||
Number TeslaBatteryLevel {channel="account:model3:myaccount:mycar:batterylevel"}
|
||||
Number TeslaPower {channel="account:model3:myaccount:mycar:power"}
|
||||
Number TeslaBatteryCurrent {channel="account:model3:myaccount:mycar:batterycurrent"}
|
||||
Number TeslaBatteryRange {channel="account:model3:myaccount:mycar:batteryrange"}
|
||||
Number TeslaEstBatteryRange {channel="account:model3:myaccount:mycar:estimatedbatteryrange"}
|
||||
Number TeslaIdealBatteryRange {channel="account:model3:myaccount:mycar:idealbatteryrange"}
|
||||
Number TeslaUsableBatteryLevel {channel="account:model3:myaccount:mycar:usablebatterylevel"}
|
||||
Switch TeslaPreconditioning {channel="account:model3:myaccount:mycar:preconditioning"}
|
||||
|
||||
Switch TeslaCharge {channel="model3:myaccount:mycar:charge"}
|
||||
Switch TeslaChargeToMax {channel="model3:myaccount:mycar:chargetomax"}
|
||||
Switch TeslaCharge {channel="account:model3:myaccount:mycar:charge"}
|
||||
Switch TeslaChargeToMax {channel="account:model3:myaccount:mycar:chargetomax"}
|
||||
|
||||
Dimmer TeslaChargeLimit {channel="model3:myaccount:mycar:chargelimit"}
|
||||
Number TeslaChargeRate {channel="model3:myaccount:mycar:chargerate"}
|
||||
String TeslaChargingState {channel="model3:myaccount:mycar:chargingstate"}
|
||||
Number TeslaChargerPower {channel="model3:myaccount:mycar:chargerpower"}
|
||||
Number TeslaTimeToFullCharge {channel="model3:myaccount:mycar:timetofullcharge"}
|
||||
Number TeslaMaxCharges {channel="model3:myaccount:mycar:maxcharges"}
|
||||
Dimmer TeslaChargeLimit {channel="account:model3:myaccount:mycar:chargelimit"}
|
||||
Number TeslaChargeRate {channel="account:model3:myaccount:mycar:chargerate"}
|
||||
String TeslaChargingState {channel="account:model3:myaccount:mycar:chargingstate"}
|
||||
Number TeslaChargerPower {channel="account:model3:myaccount:mycar:chargerpower"}
|
||||
Number TeslaTimeToFullCharge {channel="account:model3:myaccount:mycar:timetofullcharge"}
|
||||
Number TeslaMaxCharges {channel="account:model3:myaccount:mycar:maxcharges"}
|
||||
|
||||
Number TeslaChargerVoltage {channel="model3:myaccount:mycar:chargervoltage"}
|
||||
Number TeslaChargerPower {channel="model3:myaccount:mycar:chargerpower"}
|
||||
Number TeslaChargerCurrent {channel="model3:myaccount:mycar:chargercurrent"}
|
||||
Number TeslaChargerVoltage {channel="account:model3:myaccount:mycar:chargervoltage"}
|
||||
Number TeslaChargerPower {channel="account:model3:myaccount:mycar:chargerpower"}
|
||||
Number TeslaChargerCurrent {channel="account:model3:myaccount:mycar:chargercurrent"}
|
||||
|
||||
DateTime TeslaScheduledChargingStart {channel="model3:myaccount:mycar:scheduledchargingstart"}
|
||||
Dimmer TeslaSoC {channel="model3:myaccount:mycar:soc"}
|
||||
DateTime TeslaScheduledChargingStart {channel="account:model3:myaccount:mycar:scheduledchargingstart"}
|
||||
Dimmer TeslaSoC {channel="account:model3:myaccount:mycar:soc"}
|
||||
|
||||
Switch TeslaDoorLock {channel="model3:myaccount:mycar:doorlock"}
|
||||
Switch TeslaHorn {channel="model3:myaccount:mycar:honkhorn"}
|
||||
Switch TeslaStart {channel="model3:myaccount:mycar:remotestart"}
|
||||
Switch TeslaSentry {channel="model3:myaccount:mycar:sentrymode"}
|
||||
Switch TeslaLights {channel="model3:myaccount:mycar:flashlights"}
|
||||
Switch TeslaValet {channel="model3:myaccount:mycar:valetmode"}
|
||||
Switch TeslaDoorLock {channel="account:model3:myaccount:mycar:doorlock"}
|
||||
Switch TeslaHorn {channel="account:model3:myaccount:mycar:honkhorn"}
|
||||
Switch TeslaStart {channel="account:model3:myaccount:mycar:remotestart"}
|
||||
Switch TeslaSentry {channel="account:model3:myaccount:mycar:sentrymode"}
|
||||
Switch TeslaLights {channel="account:model3:myaccount:mycar:flashlights"}
|
||||
Switch TeslaValet {channel="account:model3:myaccount:mycar:valetmode"}
|
||||
|
||||
Switch TeslaWakeup {channel="model3:myaccount:mycar:wakeup"}
|
||||
Switch TeslaWakeup {channel="account:model3:myaccount:mycar:wakeup"}
|
||||
|
||||
Switch TeslaBatteryHeater {channel="model3:myaccount:mycar:batteryheater"}
|
||||
Switch TeslaFrontDefrost {channel="model3:myaccount:mycar:frontdefroster"}
|
||||
Switch TeslaRearDefrost {channel="model3:myaccount:mycar:reardefroster"}
|
||||
Switch TeslaLeftSeatHeater {channel="model3:myaccount:mycar:leftseatheater"}
|
||||
Switch TeslaRightSeatHeater {channel="model3:myaccount:mycar:rightseatheater"}
|
||||
Switch TeslaBatteryHeater {channel="account:model3:myaccount:mycar:batteryheater"}
|
||||
Switch TeslaFrontDefrost {channel="account:model3:myaccount:mycar:frontdefroster"}
|
||||
Switch TeslaRearDefrost {channel="account:model3:myaccount:mycar:reardefroster"}
|
||||
Switch TeslaLeftSeatHeater {channel="account:model3:myaccount:mycar:leftseatheater"}
|
||||
Switch TeslaRightSeatHeater {channel="account:model3:myaccount:mycar:rightseatheater"}
|
||||
|
||||
Switch TeslaHomelink {channel="model3:myaccount:mycar:homelink"}
|
||||
Location TeslaLocation {channel="model3:myaccount:mycar:location"}
|
||||
Number TeslaHeading {channel="model3:myaccount:mycar:heading"}
|
||||
DateTime TeslaLocationTime {channel="model3:myaccount:mycar:gpstimestamp"}
|
||||
Switch TeslaHomelink {channel="account:model3:myaccount:mycar:homelink"}
|
||||
Location TeslaLocation {channel="account:model3:myaccount:mycar:location"}
|
||||
Number TeslaHeading {channel="account:model3:myaccount:mycar:heading"}
|
||||
DateTime TeslaLocationTime {channel="account:model3:myaccount:mycar:gpstimestamp"}
|
||||
|
||||
Switch TeslaAutoconditioning {channel="model3:myaccount:mycar:autoconditioning"}
|
||||
Number:Temperature TeslaTemperature {channel="model3:myaccount:mycar:temperature"}
|
||||
Number:Temperature TeslaTemperatureCombined {channel="model3:myaccount:mycar:combinedtemp"}
|
||||
Number:Temperature TeslaInsideTemperature {channel="model3:myaccount:mycar:insidetemp"}
|
||||
Number:Temperature TeslaOutsideTemperature {channel="model3:myaccount:mycar:outsidetemp"}
|
||||
Switch TeslaAutoconditioning {channel="account:model3:myaccount:mycar:autoconditioning"}
|
||||
Number:Temperature TeslaTemperature {channel="account:model3:myaccount:mycar:temperature"}
|
||||
Number:Temperature TeslaTemperatureCombined {channel="account:model3:myaccount:mycar:combinedtemp"}
|
||||
Number:Temperature TeslaInsideTemperature {channel="account:model3:myaccount:mycar:insidetemp"}
|
||||
Number:Temperature TeslaOutsideTemperature {channel="account:model3:myaccount:mycar:outsidetemp"}
|
||||
```
|
||||
|
||||
demo.sitemap:
|
||||
|
||||
```
|
||||
```perl
|
||||
sitemap main label="Main"
|
||||
{
|
||||
Text item=TeslaUsableBatteryLevel label="Car" icon="tesla" valuecolor=[<=20="red",>60="green"]
|
||||
@ -342,23 +337,7 @@ sitemap main label="Main"
|
||||
}
|
||||
Frame
|
||||
{
|
||||
Switch label="State" item=nTeslaState_chart icon=line mappings=[0="Hide", 1="Hour", 2="Day", 3="Week", 4="Month"]
|
||||
Chart item=nTeslaState period=h refresh=30000 visibility=[nTeslaState_chart==1]
|
||||
Chart item=nTeslaState period=D refresh=30000 visibility=[nTeslaState_chart==2]
|
||||
Chart item=nTeslaState period=W refresh=30000 visibility=[nTeslaState_chart==3]
|
||||
Chart item=nTeslaState period=M refresh=30000 visibility=[nTeslaState_chart==4]
|
||||
}
|
||||
Frame
|
||||
{
|
||||
Switch label="Battery" item=TeslaBatteryLevel_chart icon=line mappings=[0="Hide", 1="Hour", 2="Day", 3="Week", 4="Month"]
|
||||
Chart item=TeslaUsableBatteryLevel period=h refresh=30000 visibility=[TeslaBatteryLevel_chart==1]
|
||||
Chart item=TeslaUsableBatteryLevel period=D refresh=30000 visibility=[TeslaBatteryLevel_chart==2]
|
||||
Chart item=TeslaUsableBatteryLevel period=W refresh=30000 visibility=[TeslaBatteryLevel_chart==3]
|
||||
Chart item=TeslaUsableBatteryLevel period=M refresh=30000 visibility=[TeslaBatteryLevel_chart==4]
|
||||
}
|
||||
Frame
|
||||
{
|
||||
Mapview item=TeslaLocation height=10 icon=location
|
||||
Mapview item=TeslaLocation height=10
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -366,7 +345,7 @@ sitemap main label="Main"
|
||||
|
||||
demo.rule (for graphing online status in sitemap above)
|
||||
|
||||
```
|
||||
```java
|
||||
rule "Tesla State Changed"
|
||||
when
|
||||
Item TeslaState changed
|
||||
|
@ -28,7 +28,7 @@ public class TeslaBindingConstants {
|
||||
public static final String API_NAME = "Tesla Client API";
|
||||
public static final String API_VERSION = "api/1/";
|
||||
public static final String PATH_COMMAND = "command/{cmd}";
|
||||
public static final String PATH_DATA_REQUEST = "data_request/{cmd}";
|
||||
public static final String PATH_DATA_REQUEST = "vehicle_data";
|
||||
public static final String PATH_VEHICLE_ID = "/{vid}/";
|
||||
public static final String PATH_WAKE_UP = "wake_up";
|
||||
public static final String PATH_ACCESS_TOKEN = "oauth/token";
|
||||
@ -71,19 +71,11 @@ public class TeslaBindingConstants {
|
||||
public static final String COMMAND_WAKE_UP = "wake_up";
|
||||
public static final String DATA_THROTTLE = "datathrottle";
|
||||
|
||||
// Tesla REST API vehicle states
|
||||
public static final String CHARGE_STATE = "charge_state";
|
||||
public static final String CLIMATE_STATE = "climate_state";
|
||||
public static final String DRIVE_STATE = "drive_state";
|
||||
public static final String GUI_STATE = "gui_settings";
|
||||
public static final String MOBILE_ENABLED_STATE = "mobile_enabled";
|
||||
public static final String VEHICLE_STATE = "vehicle_state";
|
||||
public static final String VEHICLE_CONFIG = "vehicle_config";
|
||||
|
||||
public static final String BINDING_ID = "tesla";
|
||||
|
||||
// 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");
|
||||
|
@ -48,10 +48,10 @@ public class TeslaChannelSelectorProxy {
|
||||
AUTO_COND("is_auto_conditioning_on", "autoconditioning", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -64,10 +64,10 @@ public class TeslaChannelSelectorProxy {
|
||||
BATTERY_HEATER("battery_heater_on", "batteryheater", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -76,10 +76,10 @@ public class TeslaChannelSelectorProxy {
|
||||
BATTERY_HEATER_NO_POWER("battery_heater_no_power", "batteryheaternopower", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -97,10 +97,10 @@ public class TeslaChannelSelectorProxy {
|
||||
CALENDAR_SUPPORTED("calendar_supported", "calendarsupported", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -109,10 +109,10 @@ public class TeslaChannelSelectorProxy {
|
||||
CALENDAR_ENABLED("calendar_enabled", "calendarenabled", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -123,10 +123,10 @@ public class TeslaChannelSelectorProxy {
|
||||
CHARGE(null, "charge", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -138,10 +138,10 @@ public class TeslaChannelSelectorProxy {
|
||||
CHARGE_ENABLE_REQUEST("charge_enable_request", "chargeenablerequest", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -184,10 +184,10 @@ public class TeslaChannelSelectorProxy {
|
||||
CHARGE_TO_MAX("charge_to_max_range", "chargetomax", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -197,10 +197,10 @@ public class TeslaChannelSelectorProxy {
|
||||
CHARGEPORT("charge_port_door_open", "chargeport", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -214,10 +214,10 @@ public class TeslaChannelSelectorProxy {
|
||||
CLIMATE_ON("is_climate_on", "climate", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -229,10 +229,10 @@ public class TeslaChannelSelectorProxy {
|
||||
DARK_RIMS("dark_rims", "darkrims", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -242,10 +242,10 @@ public class TeslaChannelSelectorProxy {
|
||||
DF("df", "driverfrontdoor", OpenClosedType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("OPEN");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("CLOSED");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -254,10 +254,10 @@ public class TeslaChannelSelectorProxy {
|
||||
DOOR_LOCK("locked", "doorlock", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -266,10 +266,10 @@ public class TeslaChannelSelectorProxy {
|
||||
DR("dr", "driverreardoor", OpenClosedType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("OPEN");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("CLOSED");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -319,10 +319,10 @@ public class TeslaChannelSelectorProxy {
|
||||
EU_VEHICLE("eu_vehicle", "european", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -332,10 +332,10 @@ public class TeslaChannelSelectorProxy {
|
||||
FAST_CHARGER("fast_charger_present", "fastcharger", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -346,10 +346,10 @@ public class TeslaChannelSelectorProxy {
|
||||
FLASH(null, "flashlights", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -358,10 +358,10 @@ public class TeslaChannelSelectorProxy {
|
||||
FRONT_DEFROSTER("is_front_defroster_on", "frontdefroster", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -370,10 +370,10 @@ public class TeslaChannelSelectorProxy {
|
||||
FT("ft", "fronttrunk", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -397,10 +397,10 @@ public class TeslaChannelSelectorProxy {
|
||||
HAS_SPOILER("has_spoiler", "spoiler", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -417,10 +417,10 @@ public class TeslaChannelSelectorProxy {
|
||||
HONK_HORN(null, "honkhorn", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -429,10 +429,10 @@ public class TeslaChannelSelectorProxy {
|
||||
HOMELINK_NEARBY("homelink_nearby", "homelink", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -491,10 +491,10 @@ public class TeslaChannelSelectorProxy {
|
||||
MANAGED_CHARGING("managed_charging_active", "managedcharging", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true")) {
|
||||
if ("true".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false")) {
|
||||
if ("false".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -504,23 +504,23 @@ public class TeslaChannelSelectorProxy {
|
||||
false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true")) {
|
||||
if ("true".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false")) {
|
||||
if ("false".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
}
|
||||
},
|
||||
MANAGED_CHARGING_START("managed_charging_start_time", "managedchargingstart", StringType.class, false),
|
||||
MOBILE_ENABLED(TeslaBindingConstants.MOBILE_ENABLED_STATE, "mobileenabled", OnOffType.class, false) {
|
||||
MOBILE_ENABLED("mobile_enabled", "mobileenabled", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true")) {
|
||||
if ("true".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false")) {
|
||||
if ("false".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -529,10 +529,10 @@ public class TeslaChannelSelectorProxy {
|
||||
MOTORIZED_CHARGE_PORT("motorized_charge_port", "motorizedchargeport", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -555,10 +555,10 @@ public class TeslaChannelSelectorProxy {
|
||||
NATIVE_LOCATION_SUPPORTED("native_location_supported", "nativelocationsupported", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -568,10 +568,10 @@ public class TeslaChannelSelectorProxy {
|
||||
NOT_ENOUGH_POWER_TO_HEAT("not_enough_power_to_heat", "notenoughpower", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -580,10 +580,10 @@ public class TeslaChannelSelectorProxy {
|
||||
NOTIFICATIONS_ENABLED("notifications_enabled", "notificationsenabled", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -592,10 +592,10 @@ public class TeslaChannelSelectorProxy {
|
||||
NOTIFICATIONS_SUPPORTED("notifications_supported", "notificationssupported", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -612,10 +612,10 @@ public class TeslaChannelSelectorProxy {
|
||||
OPEN_FRUNK(null, "openfrunk", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -624,10 +624,10 @@ public class TeslaChannelSelectorProxy {
|
||||
OPEN_TRUNK(null, "opentrunk", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -645,10 +645,10 @@ public class TeslaChannelSelectorProxy {
|
||||
PARSED_CALENDAR("parsed_calendar_supported", "parsedcalendar", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -666,10 +666,10 @@ public class TeslaChannelSelectorProxy {
|
||||
PF("pf", "passengerfrontdoor", OpenClosedType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("OPEN");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("CLOSED");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -679,10 +679,10 @@ public class TeslaChannelSelectorProxy {
|
||||
PR("pr", "passengerreardoor", OpenClosedType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("OPEN");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("CLOSED");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -691,10 +691,10 @@ public class TeslaChannelSelectorProxy {
|
||||
PRECONDITIONING("is_preconditioning", "preconditioning", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -705,7 +705,7 @@ public class TeslaChannelSelectorProxy {
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
State someState = super.getState(s);
|
||||
BigDecimal value = ((DecimalType) someState).toBigDecimal();
|
||||
if (properties.containsKey("distanceunits") && properties.get("distanceunits").equals("km/hr")) {
|
||||
if (properties.containsKey("distanceunits") && "km/hr".equals(properties.get("distanceunits"))) {
|
||||
return new QuantityType<>(value, MetricPrefix.KILO(SIUnits.METRE));
|
||||
} else {
|
||||
return new QuantityType<>(value, ImperialUnits.MILE);
|
||||
@ -715,10 +715,10 @@ public class TeslaChannelSelectorProxy {
|
||||
REAR_DEFROSTER("is_rear_defroster_on", "reardefroster", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -727,10 +727,10 @@ public class TeslaChannelSelectorProxy {
|
||||
REAR_SEAT_HEATERS("rear_seat_heaters", "rearseatheaters", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -739,10 +739,10 @@ public class TeslaChannelSelectorProxy {
|
||||
REMOTE_START("remote_start", "remotestart", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -751,10 +751,10 @@ public class TeslaChannelSelectorProxy {
|
||||
REMOTE_START_ENABLED("remote_start_enabled", "remotestartenabled", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -763,10 +763,10 @@ public class TeslaChannelSelectorProxy {
|
||||
REMOTE_START_SUPPORTED("remote_start_supported", "remotestartsupported", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -775,10 +775,10 @@ public class TeslaChannelSelectorProxy {
|
||||
RESET_VALET_PIN(null, "resetvaletpin", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -787,10 +787,10 @@ public class TeslaChannelSelectorProxy {
|
||||
RHD("rhd", "rhd", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -801,10 +801,10 @@ public class TeslaChannelSelectorProxy {
|
||||
RT("rt", "reartrunk", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -821,10 +821,10 @@ public class TeslaChannelSelectorProxy {
|
||||
SCHEDULED_CHARGING_PENDING("scheduled_charging_pending", "scheduledchargingpending", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -844,10 +844,10 @@ public class TeslaChannelSelectorProxy {
|
||||
SENTRY_MODE("sentry_mode", "sentrymode", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -856,10 +856,10 @@ public class TeslaChannelSelectorProxy {
|
||||
SENTRY_MODE_AVAILABLE("sentry_mode_available", "sentrymodeavailable", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -869,10 +869,10 @@ public class TeslaChannelSelectorProxy {
|
||||
SIDEMIRROR_HEATING("side_mirror_heaters", "sidemirrorheaters", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -881,10 +881,10 @@ public class TeslaChannelSelectorProxy {
|
||||
SMART_PRECONDITIONING("smart_preconditioning", "smartpreconditioning", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -907,10 +907,10 @@ public class TeslaChannelSelectorProxy {
|
||||
STEERINGWHEEL_HEATER("steering_wheel_heater", "steeringwheelheater", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -919,10 +919,10 @@ public class TeslaChannelSelectorProxy {
|
||||
SUN_ROOF_PRESENT("sun_roof_installed", "sunroofinstalled", OnOffType.class, true) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -942,7 +942,7 @@ public class TeslaChannelSelectorProxy {
|
||||
TIMESTAMP("timestamp", "eventstamp", DateTimeType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
Date date = new Date(Long.valueOf(s));
|
||||
Date date = new Date(Long.parseLong(s));
|
||||
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
return super.getState(dateFormatter.format(date));
|
||||
}
|
||||
@ -950,10 +950,10 @@ public class TeslaChannelSelectorProxy {
|
||||
TRIP_CARGING("trip_charging", "tripcharging", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -970,10 +970,10 @@ public class TeslaChannelSelectorProxy {
|
||||
VALET_MODE("valet_mode", "valetmode", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -982,10 +982,10 @@ public class TeslaChannelSelectorProxy {
|
||||
VALET_PIN("valet_pin_needed", "valetpin", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -995,10 +995,10 @@ public class TeslaChannelSelectorProxy {
|
||||
WAKEUP(null, "wakeup", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -1007,10 +1007,10 @@ public class TeslaChannelSelectorProxy {
|
||||
WIPERBLADE_HEATER("wiper_blade_heater", "wiperbladeheater", OnOffType.class, false) {
|
||||
@Override
|
||||
public State getState(String s, TeslaChannelSelectorProxy proxy, Map<String, String> properties) {
|
||||
if (s.equals("true") || s.equals("1")) {
|
||||
if ("true".equals(s) || "1".equals(s)) {
|
||||
return super.getState("ON");
|
||||
}
|
||||
if (s.equals("false") || s.equals("0")) {
|
||||
if ("false".equals(s) || "0".equals(s)) {
|
||||
return super.getState("OFF");
|
||||
}
|
||||
return super.getState(s);
|
||||
@ -1059,10 +1059,8 @@ public class TeslaChannelSelectorProxy {
|
||||
if (state != null) {
|
||||
return state;
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
} catch (IllegalArgumentException e) {
|
||||
} catch (IllegalAccessException e) {
|
||||
} catch (InvocationTargetException e) {
|
||||
} catch (NoSuchMethodException | IllegalArgumentException | IllegalAccessException
|
||||
| InvocationTargetException e) {
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,11 @@ 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;
|
||||
import org.openhab.binding.tesla.internal.protocol.VehicleData;
|
||||
import org.openhab.binding.tesla.internal.protocol.sso.TokenResponse;
|
||||
import org.openhab.core.io.net.http.HttpClientFactory;
|
||||
import org.openhab.core.thing.Bridge;
|
||||
@ -43,6 +45,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;
|
||||
@ -66,7 +69,7 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
|
||||
public static final int API_MAXIMUM_ERRORS_IN_INTERVAL = 3;
|
||||
public static final int API_ERROR_INTERVAL_SECONDS = 15;
|
||||
private static final int CONNECT_RETRY_INTERVAL = 15000;
|
||||
private static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
||||
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
||||
.withZone(ZoneId.systemDefault());
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(TeslaAccountHandler.class);
|
||||
@ -80,6 +83,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 +100,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);
|
||||
@ -143,7 +149,7 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
|
||||
}
|
||||
|
||||
public void scanForVehicles() {
|
||||
scheduler.execute(() -> queryVehicles());
|
||||
scheduler.execute(this::queryVehicles);
|
||||
}
|
||||
|
||||
public void addVehicleListener(VehicleListener listener) {
|
||||
@ -179,7 +185,6 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
|
||||
ThingStatusInfo authenticationResult = authenticate();
|
||||
updateStatus(authenticationResult.getStatus(), authenticationResult.getStatusDetail(),
|
||||
authenticationResult.getDescription());
|
||||
return false;
|
||||
} else {
|
||||
apiIntervalErrors++;
|
||||
if (immediatelyFail || apiIntervalErrors >= API_MAXIMUM_ERRORS_IN_INTERVAL) {
|
||||
@ -221,11 +226,11 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
|
||||
Vehicle[] vehicleArray = gson.fromJson(jsonObject.getAsJsonArray("response"), Vehicle[].class);
|
||||
|
||||
for (Vehicle vehicle : vehicleArray) {
|
||||
String responseString = invokeAndParse(vehicle.id, VEHICLE_CONFIG, null, dataRequestTarget, 0);
|
||||
if (responseString == null || responseString.isBlank()) {
|
||||
continue;
|
||||
String responseString = invokeAndParse(vehicle.id, null, null, dataRequestTarget, 0);
|
||||
VehicleConfig vehicleConfig = null;
|
||||
if (responseString != null && !responseString.isBlank()) {
|
||||
vehicleConfig = gson.fromJson(responseString, VehicleData.class).vehicle_config;
|
||||
}
|
||||
VehicleConfig vehicleConfig = gson.fromJson(responseString, VehicleConfig.class);
|
||||
for (VehicleListener listener : vehicleListeners) {
|
||||
listener.vehicleFound(vehicle, vehicleConfig);
|
||||
}
|
||||
@ -233,6 +238,14 @@ 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);
|
||||
@ -256,13 +269,13 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
|
||||
TokenResponse token = logonToken;
|
||||
|
||||
boolean hasExpired = true;
|
||||
logger.debug("Current authentication time {}", dateFormatter.format(Instant.now()));
|
||||
logger.debug("Current authentication time {}", DATE_FORMATTER.format(Instant.now()));
|
||||
|
||||
if (token != null) {
|
||||
Instant tokenCreationInstant = Instant.ofEpochMilli(token.created_at * 1000);
|
||||
Instant tokenExpiresInstant = Instant.ofEpochMilli((token.created_at + token.expires_in) * 1000);
|
||||
logger.debug("Found a request token from {}", dateFormatter.format(tokenCreationInstant));
|
||||
logger.debug("Access token expiration time {}", dateFormatter.format(tokenExpiresInstant));
|
||||
logger.debug("Found a request token from {}", DATE_FORMATTER.format(tokenCreationInstant));
|
||||
logger.debug("Access token expiration time {}", DATE_FORMATTER.format(tokenExpiresInstant));
|
||||
|
||||
if (tokenExpiresInstant.isBefore(Instant.now())) {
|
||||
logger.debug("The access token has expired");
|
||||
@ -308,15 +321,13 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
|
||||
.header("Authorization", "Bearer " + logonToken.access_token)
|
||||
.post(Entity.entity(payLoad, MediaType.APPLICATION_JSON_TYPE));
|
||||
}
|
||||
} else if (command != null) {
|
||||
response = target.resolveTemplate("cmd", command).resolveTemplate("vid", vehicleId)
|
||||
.request(MediaType.APPLICATION_JSON_TYPE)
|
||||
.header("Authorization", "Bearer " + logonToken.access_token).get();
|
||||
} else {
|
||||
if (command != null) {
|
||||
response = target.resolveTemplate("cmd", command).resolveTemplate("vid", vehicleId)
|
||||
.request(MediaType.APPLICATION_JSON_TYPE)
|
||||
.header("Authorization", "Bearer " + logonToken.access_token).get();
|
||||
} else {
|
||||
response = target.resolveTemplate("vid", vehicleId).request(MediaType.APPLICATION_JSON_TYPE)
|
||||
.header("Authorization", "Bearer " + logonToken.access_token).get();
|
||||
}
|
||||
response = target.resolveTemplate("vid", vehicleId).request(MediaType.APPLICATION_JSON_TYPE)
|
||||
.header("Authorization", "Bearer " + logonToken.access_token).get();
|
||||
}
|
||||
|
||||
if (!checkResponse(response, false)) {
|
||||
@ -330,7 +341,6 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
|
||||
logger.debug("Retrying to send the command {}.", command);
|
||||
return invokeAndParse(vehicleId, command, payLoad, target, noOfretries - 1);
|
||||
} catch (InterruptedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -353,8 +363,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();
|
||||
@ -394,19 +405,16 @@ public class TeslaAccountHandler extends BaseBridgeHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (response != null) {
|
||||
logger.error("Error fetching the list of vehicles : {}:{}", response.getStatus(),
|
||||
response.getStatusInfo());
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
} else if (response != null) {
|
||||
logger.error("Error fetching the list of vehicles : {}:{}", response.getStatus(),
|
||||
response.getStatusInfo());
|
||||
updateStatus(ThingStatus.OFFLINE);
|
||||
}
|
||||
} else if (authenticationResult.getStatusDetail() == ThingStatusDetail.CONFIGURATION_ERROR) {
|
||||
// make sure to set thing to CONFIGURATION_ERROR in case of failed authentication in order not to
|
||||
// hit request limit on retries on the Tesla SSO endpoints.
|
||||
updateStatus(ThingStatus.OFFLINE, authenticationResult.getStatusDetail());
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("An exception occurred while connecting to the Tesla back-end: '{}'", e.getMessage(), e);
|
||||
@ -415,6 +423,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;
|
||||
|
@ -22,7 +22,6 @@ import java.nio.charset.CodingErrorAction;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
@ -32,6 +31,7 @@ import org.eclipse.jetty.websocket.api.WebSocketPingPongListener;
|
||||
import org.eclipse.jetty.websocket.client.WebSocketClient;
|
||||
import org.openhab.binding.tesla.internal.protocol.Event;
|
||||
import org.openhab.core.io.net.http.WebSocketFactory;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -54,7 +54,6 @@ public class TeslaEventEndpoint implements WebSocketListener, WebSocketPingPongL
|
||||
|
||||
private String endpointId;
|
||||
protected WebSocketFactory webSocketFactory;
|
||||
private static final AtomicInteger INSTANCE_COUNTER = new AtomicInteger();
|
||||
|
||||
private WebSocketClient client;
|
||||
private ConnectionState connectionState = ConnectionState.CLOSED;
|
||||
@ -62,11 +61,12 @@ public class TeslaEventEndpoint implements WebSocketListener, WebSocketPingPongL
|
||||
private EventHandler eventHandler;
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
public TeslaEventEndpoint(WebSocketFactory webSocketFactory) {
|
||||
public TeslaEventEndpoint(ThingUID uid, WebSocketFactory webSocketFactory) {
|
||||
try {
|
||||
this.endpointId = "TeslaEventEndpoint-" + INSTANCE_COUNTER.incrementAndGet();
|
||||
this.endpointId = "TeslaEventEndpoint-" + uid.getAsString();
|
||||
|
||||
client = webSocketFactory.createWebSocketClient(endpointId);
|
||||
String name = ThingWebClientUtil.buildWebClientConsumerName(uid, null);
|
||||
client = webSocketFactory.createWebSocketClient(name);
|
||||
this.client.setConnectTimeout(TIMEOUT_MILLISECONDS);
|
||||
this.client.setMaxIdleTimeout(IDLE_TIMEOUT_MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
@ -74,6 +74,16 @@ public class TeslaEventEndpoint implements WebSocketListener, WebSocketPingPongL
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
if (client.isRunning()) {
|
||||
client.stop();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("An exception occurred while stopping the WebSocket client : {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void connect(URI endpointURI) {
|
||||
if (connectionState == ConnectionState.CONNECTED) {
|
||||
return;
|
||||
@ -113,7 +123,7 @@ public class TeslaEventEndpoint implements WebSocketListener, WebSocketPingPongL
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
public void closeConnection() {
|
||||
try {
|
||||
connectionState = ConnectionState.CLOSING;
|
||||
if (session != null && session.isOpen()) {
|
||||
|
@ -46,7 +46,7 @@ public class TeslaSSOHandler {
|
||||
private final HttpClient httpClient;
|
||||
private final Gson gson = new Gson();
|
||||
private final Logger logger = LoggerFactory.getLogger(TeslaSSOHandler.class);
|
||||
private static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
||||
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
||||
.withZone(ZoneId.systemDefault());
|
||||
|
||||
public TeslaSSOHandler(HttpClient httpClient) {
|
||||
@ -74,7 +74,7 @@ public class TeslaSSOHandler {
|
||||
|
||||
if (tokenResponse != null && tokenResponse.access_token != null && !tokenResponse.access_token.isEmpty()) {
|
||||
tokenResponse.created_at = Instant.now().getEpochSecond();
|
||||
logger.debug("Access token expires in {} seconds at {}", tokenResponse.expires_in, dateFormatter
|
||||
logger.debug("Access token expires in {} seconds at {}", tokenResponse.expires_in, DATE_FORMATTER
|
||||
.format(Instant.ofEpochMilli((tokenResponse.created_at + tokenResponse.expires_in) * 1000)));
|
||||
return tokenResponse;
|
||||
} else {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tesla.internal.handler;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
|
||||
/**
|
||||
* {@link ThingWebClientUtil} provides an utility method to create a valid consumer name for web clients.
|
||||
*
|
||||
* @author Laurent Garnier - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ThingWebClientUtil {
|
||||
|
||||
private static final int MAX_CONSUMER_NAME_LENGTH = 20;
|
||||
|
||||
/**
|
||||
* Build a valid consumer name for HTTP or WebSocket client.
|
||||
*
|
||||
* @param uid thing UID for which to associate HTTP or WebSocket client
|
||||
* @param prefix a prefix to consider for the name; can be null
|
||||
* @return a valid consumer name
|
||||
*/
|
||||
public static String buildWebClientConsumerName(ThingUID uid, @Nullable String prefix) {
|
||||
String pref = prefix == null ? "" : prefix;
|
||||
String name = pref + uid.getAsString().replace(':', '-');
|
||||
if (name.length() > MAX_CONSUMER_NAME_LENGTH) {
|
||||
// Try to use only prefix + binding ID + thing ID
|
||||
name = pref + uid.getBindingId();
|
||||
if (name.length() > (MAX_CONSUMER_NAME_LENGTH / 2)) {
|
||||
// Truncate the binding ID to keep enough place for thing ID
|
||||
name = name.substring(0, MAX_CONSUMER_NAME_LENGTH / 2);
|
||||
}
|
||||
// Add the thing ID
|
||||
String id = uid.getId();
|
||||
int maxIdLength = MAX_CONSUMER_NAME_LENGTH - 1 - name.length();
|
||||
if (id.length() > maxIdLength) {
|
||||
// If thing ID is too big, use a hash code of the thing UID instead of thing id
|
||||
// and truncate it if necessary
|
||||
id = buildHashCode(uid, maxIdLength);
|
||||
}
|
||||
name += "-" + id;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// Make the method public just to be able to call it inside the tests
|
||||
static String buildHashCode(ThingUID uid, int maxLength) {
|
||||
String result = Integer.toHexString(uid.hashCode());
|
||||
if (result.length() > maxLength) {
|
||||
result = result.substring(result.length() - maxLength);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2022 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.tesla.internal.protocol;
|
||||
|
||||
/**
|
||||
* The {@link VehicleData} is a data structure to capture
|
||||
* variables sent by the Tesla API about a vehicle.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution
|
||||
*/
|
||||
public class VehicleData {
|
||||
|
||||
public String color;
|
||||
public String display_name;
|
||||
public String id;
|
||||
public String option_codes;
|
||||
public String vehicle_id;
|
||||
public String vin;
|
||||
public String tokens[];
|
||||
public String state;
|
||||
public boolean remote_start_enabled;
|
||||
public boolean calendar_enabled;
|
||||
public boolean notifications_enabled;
|
||||
public String backseat_token;
|
||||
public String backseat_token_updated_at;
|
||||
|
||||
public ChargeState charge_state;
|
||||
public ClimateState climate_state;
|
||||
public DriveState drive_state;
|
||||
public GUIState gui_settings;
|
||||
public VehicleConfig vehicle_config;
|
||||
public VehicleState vehicle_state;
|
||||
|
||||
VehicleData() {
|
||||
}
|
||||
}
|
@ -18,12 +18,12 @@ package org.openhab.binding.tesla.internal.throttler;
|
||||
* @author Karel Goderis - Initial contribution
|
||||
*/
|
||||
public interface TimeProvider {
|
||||
public static final TimeProvider SYSTEM_PROVIDER = new TimeProvider() {
|
||||
static final TimeProvider SYSTEM_PROVIDER = new TimeProvider() {
|
||||
@Override
|
||||
public long getCurrentTimeInMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
};
|
||||
|
||||
public long getCurrentTimeInMillis();
|
||||
long getCurrentTimeInMillis();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -421,7 +421,7 @@
|
||||
</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>
|
||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user