public void parseAndUpdate(String request, String payLoad, String result) { JsonParser parser = new JsonParser(); JsonObject jsonObject = null; try { if (request != null && result != null && result != "null") { // first, update state objects switch (request) { case TESLA_DRIVE_STATE: { driveState = gson.fromJson(result, DriveState.class); break; } case TESLA_GUI_STATE: { guiState = gson.fromJson(result, GUIState.class); break; } case TESLA_VEHICLE_STATE: { vehicleState = gson.fromJson(result, VehicleState.class); break; } case TESLA_CHARGE_STATE: { chargeState = gson.fromJson(result, ChargeState.class); if (chargeState.charging_state != null && chargeState.charging_state.equals("Charging")) { updateState(CHANNEL_CHARGE, OnOffType.ON); } else { updateState(CHANNEL_CHARGE, OnOffType.OFF); } break; } case TESLA_CLIMATE_STATE: { climateState = gson.fromJson(result, ClimateState.class); break; } } // secondly, reformat the response string to a JSON compliant // object for some specific non-JSON compatible requests switch (request) { case TESLA_MOBILE_ENABLED_STATE: { jsonObject = new JsonObject(); jsonObject.addProperty(TESLA_MOBILE_ENABLED_STATE, result); break; } default: { jsonObject = parser.parse(result).getAsJsonObject(); break; } } } // process the result if (jsonObject != null && result != null && !result.equals("null")) { // deal with responses for "set" commands, which get confirmed // positively, or negatively, in which case a reason for failure // is provided if (jsonObject.get("reason") != null && jsonObject.get("reason").getAsString() != null) { boolean requestResult = jsonObject.get("result").getAsBoolean(); logger.debug( "The request ({}) execution was {}, and reported '{}'", new Object[] { request, requestResult ? "successful" : "not successful", jsonObject.get("reason").getAsString() }); } else { Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet(); for (Map.Entry<String, JsonElement> entry : entrySet) { try { TeslaChannelSelector selector = TeslaChannelSelector.getValueSelectorFromRESTID(entry.getKey()); if (!selector.isProperty()) { if (!entry.getValue().isJsonNull()) { updateState( selector.getChannelID(), teslaChannelSelectorProxy.getState( entry.getValue().getAsString(), selector, editProperties())); } else { updateState(selector.getChannelID(), UnDefType.UNDEF); } } else { if (!entry.getValue().isJsonNull()) { Map<String, String> properties = editProperties(); properties.put(selector.getChannelID(), entry.getValue().getAsString()); updateProperties(properties); } } } catch (Exception e) { logger.debug( "Unable to handle the variable/value pair '{}':'{}'", entry.getKey(), entry.getValue()); } } } } } catch (Exception p) { logger.error( "An exception occurred while parsing data received from the vehicle: '{}'", p.getMessage()); } }
@Override public void run() { try { if (isAwake()) { if (!isEstablished || (!isInMotion() && (System.currentTimeMillis() - lastEventSystemTime > EVENT_RETRY_INTERVAL))) { if (!establishEventStream()) { if ((System.currentTimeMillis() - lastEventSystemTime > EVENT_RECOVERY_INTERVAL)) { logger.warn("Event Stream : Resetting the vehicle connection"); connect(); } } } try { if (isEstablished) { String line = null; try { line = eventBufferedReader.readLine(); } catch (Exception e) { // we just move on. If we are here, then is most // probably due to Premature EOF exceptions } if (line != null) { lastEventSystemTime = System.currentTimeMillis(); logger.debug("Received an event: '{}'", line); String vals[] = line.split(","); if (!vals[0].equals(lastEventTimeStamp)) { lastEventTimeStamp = vals[0]; for (int i = 0; i < EventKeys.values().length; i++) { try { TeslaChannelSelector selector = TeslaChannelSelector.getValueSelectorFromRESTID( (EventKeys.values()[i]).toString()); if (!selector.isProperty()) { State newState = teslaChannelSelectorProxy.getState( vals[i], selector, editProperties()); if (newState != null && !vals[i].equals("")) { updateState(selector.getChannelID(), newState); } else { updateState(selector.getChannelID(), UnDefType.UNDEF); } } else { Map<String, String> properties = editProperties(); properties.put( selector.getChannelID(), (selector.getState(vals[i])).toString()); updateProperties(properties); } } catch (Exception e) { logger.warn( "An exception occurred while processing an event received from the vehicle; '{}'", e.getMessage()); } } } } } } catch (Exception e) { logger.error( "An exception occurred while reading event inputs from vehicle '{}' : {}", vehicle.vin, e.getMessage()); isEstablished = false; } } else { logger.debug("Event stream : The vehicle is not awake"); if (vehicle != null) { // wake up the vehicle until streaming token <> 0 logger.debug("Event stream : Wake up vehicle"); sendCommand(TESLA_COMMAND_WAKE_UP); } else { logger.debug("Event stream : Querying the vehicle"); vehicle = queryVehicle(); } } } catch (Exception t) { logger.error("An exception ocurred in the event stream thread: '{}'", t.getMessage()); } }
@Override public void handleCommand(ChannelUID channelUID, Command command) { String channelID = channelUID.getId(); TeslaChannelSelector selector = TeslaChannelSelector.getValueSelectorFromChannelID(channelID); if (selector != null) { try { switch (selector) { case CHARGE_LIMIT_SOC: { if (command instanceof PercentType) { setChargeLimit(((PercentType) command).intValue()); } else if (command instanceof OnOffType && command == OnOffType.ON) { setChargeLimit(100); } else if (command instanceof OnOffType && command == OnOffType.OFF) { setChargeLimit(0); } else if (command instanceof IncreaseDecreaseType && command == IncreaseDecreaseType.INCREASE) { setChargeLimit(Math.min(chargeState.charge_limit_soc + 1, 100)); } else if (command instanceof IncreaseDecreaseType && command == IncreaseDecreaseType.DECREASE) { setChargeLimit(Math.max(chargeState.charge_limit_soc - 1, 0)); } break; } case TEMPERATURE: { if (command instanceof DecimalType) { setTemperature(((DecimalType) command).floatValue()); } break; } case SUN_ROOF_STATE: { if (command instanceof StringType) { setSunroof(command.toString()); } break; } case SUN_ROOF: { if (command instanceof PercentType) { moveSunroof(((PercentType) command).intValue()); } else if (command instanceof OnOffType && command == OnOffType.ON) { moveSunroof(100); } else if (command instanceof OnOffType && command == OnOffType.OFF) { moveSunroof(0); } else if (command instanceof IncreaseDecreaseType && command == IncreaseDecreaseType.INCREASE) { moveSunroof(Math.min(chargeState.charge_limit_soc + 1, 100)); } else if (command instanceof IncreaseDecreaseType && command == IncreaseDecreaseType.DECREASE) { moveSunroof(Math.max(chargeState.charge_limit_soc - 1, 0)); } break; } case CHARGE_TO_MAX: { if (command instanceof OnOffType) { if (((OnOffType) command) == OnOffType.ON) { setMaxRangeCharging(true); } else { setMaxRangeCharging(false); } } break; } case CHARGE: { if (command instanceof OnOffType) { if (((OnOffType) command) == OnOffType.ON) { charge(true); } else { charge(false); } } break; } case FLASH: { if (command instanceof OnOffType) { if (((OnOffType) command) == OnOffType.ON) { flashLights(); } } break; } case HONK_HORN: { if (command instanceof OnOffType) { if (((OnOffType) command) == OnOffType.ON) { honkHorn(); } } break; } case CHARGEPORT: { if (command instanceof OnOffType) { if (((OnOffType) command) == OnOffType.ON) { openChargePort(); } } break; } case DOOR_LOCK: { if (command instanceof OnOffType) { if (((OnOffType) command) == OnOffType.ON) { lockDoors(true); } else { lockDoors(false); } } break; } case AUTO_COND: { if (command instanceof OnOffType) { if (((OnOffType) command) == OnOffType.ON) { autoConditioning(true); } else { autoConditioning(false); } } break; } default: break; } return; } catch (IllegalArgumentException e) { logger.warn( "An error occurred while trying to set the read-only variable associated with channel '{}' to '{}'", channelID, command.toString()); } } }