|
|
@ -1,10 +1,12 @@ |
|
|
|
package main |
|
|
|
package main |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
|
|
|
|
"flag" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
"os" |
|
|
|
"os" |
|
|
|
"strconv" |
|
|
|
"strconv" |
|
|
|
"strings" |
|
|
|
"strings" |
|
|
|
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/bogosj/tesla" |
|
|
|
"github.com/bogosj/tesla" |
|
|
|
"github.com/therecipe/qt/widgets" |
|
|
|
"github.com/therecipe/qt/widgets" |
|
|
@ -43,14 +45,36 @@ var ( |
|
|
|
|
|
|
|
|
|
|
|
window *widgets.QMainWindow |
|
|
|
window *widgets.QMainWindow |
|
|
|
mainApp *widgets.QApplication |
|
|
|
mainApp *widgets.QApplication |
|
|
|
|
|
|
|
vehicleSearch string |
|
|
|
|
|
|
|
refresh bool |
|
|
|
popup = false |
|
|
|
popup = false |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func init() { |
|
|
|
|
|
|
|
flag.StringVar(&vehicleSearch, "v", "", "Vehicle Identifier") |
|
|
|
|
|
|
|
flag.BoolVar(&refresh, "r", false, "Auto-refresh (every minute)") |
|
|
|
|
|
|
|
flag.Parse() |
|
|
|
|
|
|
|
} |
|
|
|
func main() { |
|
|
|
func main() { |
|
|
|
mainApp = widgets.NewQApplication(len(os.Args), os.Args) |
|
|
|
mainApp = widgets.NewQApplication(len(os.Args), os.Args) |
|
|
|
window = widgets.NewQMainWindow(nil, 0) |
|
|
|
window = widgets.NewQMainWindow(nil, 0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c := getTeslaClient() |
|
|
|
|
|
|
|
vehicles, err := c.Vehicles() |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
showDialogue(false, "Unable to get vehicles.\n%+v", err) |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(vehicles) == 0 { |
|
|
|
|
|
|
|
showDialogue(false, "No vehicles to show.") |
|
|
|
|
|
|
|
return |
|
|
|
|
|
|
|
} else if len(vehicles) > 1 && vehicleSearch == "" { |
|
|
|
|
|
|
|
showDialogue(false, "Unable to determine vehicle.") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Setup all UI Elements
|
|
|
|
// Setup all UI Elements
|
|
|
|
|
|
|
|
window.SetWindowTitle("Loading, please wait!") |
|
|
|
|
|
|
|
|
|
|
|
batteryLevel = widgets.NewQLabel(nil, 0) |
|
|
|
batteryLevel = widgets.NewQLabel(nil, 0) |
|
|
|
batteryRange = widgets.NewQLabel(nil, 0) |
|
|
|
batteryRange = widgets.NewQLabel(nil, 0) |
|
|
|
chargingState = widgets.NewQLabel(nil, 0) |
|
|
|
chargingState = widgets.NewQLabel(nil, 0) |
|
|
@ -93,25 +117,34 @@ func main() { |
|
|
|
centralWidget := widgets.NewQWidget(window, 0) |
|
|
|
centralWidget := widgets.NewQWidget(window, 0) |
|
|
|
|
|
|
|
|
|
|
|
// Set Values for everything
|
|
|
|
// Set Values for everything
|
|
|
|
|
|
|
|
go setValues() |
|
|
|
|
|
|
|
if refresh { |
|
|
|
|
|
|
|
go func() { |
|
|
|
|
|
|
|
time.Sleep(1 * time.Minute) |
|
|
|
setValues() |
|
|
|
setValues() |
|
|
|
|
|
|
|
}() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Some adjustments
|
|
|
|
// Some adjustments
|
|
|
|
window.SetWindowTitle(fmt.Sprintf("%+v: %+v", vehicle.DisplayName, vehicle.Vin)) |
|
|
|
|
|
|
|
|
|
|
|
lockedDoors.SetCheckable(false) |
|
|
|
|
|
|
|
climateOn.SetCheckable(false) |
|
|
|
|
|
|
|
tempSetting.SetReadOnly(true) |
|
|
|
|
|
|
|
|
|
|
|
batteryLevel.SetFixedWidth(30) |
|
|
|
batteryLevel.SetFixedWidth(30) |
|
|
|
insideTemp.SetFixedWidth(25) |
|
|
|
insideTemp.SetFixedWidth(25) |
|
|
|
outsideTemp.SetFixedWidth(25) |
|
|
|
outsideTemp.SetFixedWidth(25) |
|
|
|
tempSetting.SetFixedWidth(25) |
|
|
|
tempSetting.SetFixedWidth(25) |
|
|
|
|
|
|
|
|
|
|
|
currentChargeLabel.SetText("Current Charge: ") |
|
|
|
currentChargeLabel.SetText("Current Charge:") |
|
|
|
currentRangeLabel.SetText("Current Range: ") |
|
|
|
currentRangeLabel.SetText("Current Range:") |
|
|
|
insideTempLabel.SetText("Inside Temp: ") |
|
|
|
insideTempLabel.SetText("Inside Temp:") |
|
|
|
outsideTempLabel.SetText("Outside Temp: ") |
|
|
|
outsideTempLabel.SetText("Outside Temp:") |
|
|
|
climateEnabledLabel.SetText("Climate On: ") |
|
|
|
climateEnabledLabel.SetText("Climate On:") |
|
|
|
climateSettingLabel.SetText("Climate Setting: ") |
|
|
|
climateSettingLabel.SetText("Climate Setting:") |
|
|
|
doorLockLabel.SetText("Lock Doors: ") |
|
|
|
doorLockLabel.SetText("Lock Doors:") |
|
|
|
sentryModeLabel.SetText("Sentry Mode: ") |
|
|
|
sentryModeLabel.SetText("Sentry Mode:") |
|
|
|
chargingStateLabel.SetText("Charging: ") |
|
|
|
chargingStateLabel.SetText("Charging:") |
|
|
|
honk.SetText("Honk") |
|
|
|
honk.SetText("Honk") |
|
|
|
flashLights.SetText("Flash") |
|
|
|
flashLights.SetText("Flash") |
|
|
|
trunk.SetText("Trunk") |
|
|
|
trunk.SetText("Trunk") |
|
|
@ -134,13 +167,13 @@ func main() { |
|
|
|
chargeHbox.AddWidget(batteryRange, 0, 0) |
|
|
|
chargeHbox.AddWidget(batteryRange, 0, 0) |
|
|
|
|
|
|
|
|
|
|
|
// Charging State has its own section and is handled differently based on if it is present or not
|
|
|
|
// Charging State has its own section and is handled differently based on if it is present or not
|
|
|
|
if chargeStats.ChargingState != "Disconnected" { |
|
|
|
if chargeStats != nil && chargeStats.ChargingState != "Disconnected" { |
|
|
|
statusLayout.AddRow3("Minutes to Full: ", minutesToFull) |
|
|
|
statusLayout.AddRow3("Minutes to Full:", minutesToFull) |
|
|
|
if chargeStats.FastChargerPresent { |
|
|
|
if chargeStats.FastChargerPresent { |
|
|
|
statusLayout.AddRow3("Fast Charger: ", fastChargerInd) |
|
|
|
statusLayout.AddRow3("Fast Charger:", fastChargerInd) |
|
|
|
} |
|
|
|
} |
|
|
|
if chargeStats.BatteryHeaterOn { |
|
|
|
if chargeStats.BatteryHeaterOn { |
|
|
|
statusLayout.AddRow3("Battey Heater: ", batteryHeaterInd) |
|
|
|
statusLayout.AddRow3("Battey Heater:", batteryHeaterInd) |
|
|
|
} |
|
|
|
} |
|
|
|
statusLayout.AddRow3(" ", nil) |
|
|
|
statusLayout.AddRow3(" ", nil) |
|
|
|
} |
|
|
|
} |
|
|
@ -163,7 +196,7 @@ func main() { |
|
|
|
securityHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
securityHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
securityHbox.AddWidget(sentryModeLabel, 0, 0) |
|
|
|
securityHbox.AddWidget(sentryModeLabel, 0, 0) |
|
|
|
securityHbox.AddWidget(sentryMode, 0, 0) |
|
|
|
securityHbox.AddWidget(sentryMode, 0, 0) |
|
|
|
if chargeStats.ChargingState != "Disconnected" { |
|
|
|
if chargeStats != nil && chargeStats.ChargingState != "Disconnected" { |
|
|
|
securityHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
securityHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed)) |
|
|
|
securityHbox.AddWidget(chargingStateLabel, 0, 0) |
|
|
|
securityHbox.AddWidget(chargingStateLabel, 0, 0) |
|
|
|
securityHbox.AddWidget(startStopCharge, 0, 0) |
|
|
|
securityHbox.AddWidget(startStopCharge, 0, 0) |
|
|
@ -181,8 +214,8 @@ func main() { |
|
|
|
|
|
|
|
|
|
|
|
// Put all Sections Together, note ChargingState (top) is already handled
|
|
|
|
// Put all Sections Together, note ChargingState (top) is already handled
|
|
|
|
statusLayout.AddRow2(currentChargeLabel, chargeHbox) |
|
|
|
statusLayout.AddRow2(currentChargeLabel, chargeHbox) |
|
|
|
statusLayout.AddRow3("Charging State: ", chargingState) |
|
|
|
statusLayout.AddRow3("Charging State:", chargingState) |
|
|
|
statusLayout.AddRow3("Charge Port: ", chargeDoorOpenInd) |
|
|
|
statusLayout.AddRow3("Charge Port:", chargeDoorOpenInd) |
|
|
|
statusLayout.AddRow3(" ", nil) |
|
|
|
statusLayout.AddRow3(" ", nil) |
|
|
|
statusLayout.AddRow2(insideTempLabel, tempHbox) |
|
|
|
statusLayout.AddRow2(insideTempLabel, tempHbox) |
|
|
|
statusLayout.AddRow2(climateEnabledLabel, climateHbox) |
|
|
|
statusLayout.AddRow2(climateEnabledLabel, climateHbox) |
|
|
@ -200,7 +233,7 @@ func main() { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func setValues() { |
|
|
|
func setValues() { |
|
|
|
vehicle = getVehicle("") |
|
|
|
vehicle = getVehicle(vehicleSearch) |
|
|
|
var err error |
|
|
|
var err error |
|
|
|
if vehicle == nil { |
|
|
|
if vehicle == nil { |
|
|
|
showDialogue(false, "Unable to get vehicle") |
|
|
|
showDialogue(false, "Unable to get vehicle") |
|
|
@ -221,9 +254,9 @@ func setValues() { |
|
|
|
} |
|
|
|
} |
|
|
|
guiSettings, err = vehicle.GuiSettings() |
|
|
|
guiSettings, err = vehicle.GuiSettings() |
|
|
|
if err != nil { |
|
|
|
if err != nil { |
|
|
|
|
|
|
|
|
|
|
|
showDialogue(false, "Unable to get Gui Settings") |
|
|
|
showDialogue(false, "Unable to get Gui Settings") |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
window.SetWindowTitle(fmt.Sprintf("%+v: %+v", vehicle.DisplayName, vehicle.Vin)) |
|
|
|
tempSettingVal := climateState.DriverTempSetting |
|
|
|
tempSettingVal := climateState.DriverTempSetting |
|
|
|
insideTempVal := climateState.InsideTemp |
|
|
|
insideTempVal := climateState.InsideTemp |
|
|
|
outsideTempVal := climateState.OutsideTemp |
|
|
|
outsideTempVal := climateState.OutsideTemp |
|
|
@ -260,6 +293,9 @@ func setValues() { |
|
|
|
lockedDoors.SetChecked(vehicleState.Locked) |
|
|
|
lockedDoors.SetChecked(vehicleState.Locked) |
|
|
|
sentryMode.SetChecked(vehicleState.SentryMode) |
|
|
|
sentryMode.SetChecked(vehicleState.SentryMode) |
|
|
|
sentryMode.SetCheckable(!vehicleState.SentryMode) |
|
|
|
sentryMode.SetCheckable(!vehicleState.SentryMode) |
|
|
|
|
|
|
|
lockedDoors.SetCheckable(true) |
|
|
|
|
|
|
|
climateOn.SetCheckable(true) |
|
|
|
|
|
|
|
tempSetting.SetReadOnly(false) |
|
|
|
|
|
|
|
|
|
|
|
startStopCharge.SetChecked(chargeStats.ChargingState == "Charging") |
|
|
|
startStopCharge.SetChecked(chargeStats.ChargingState == "Charging") |
|
|
|
if chargeStats.ChargingState == "Disconnected" { |
|
|
|
if chargeStats.ChargingState == "Disconnected" { |
|
|
@ -344,7 +380,7 @@ func openFrunk(c bool) { |
|
|
|
|
|
|
|
|
|
|
|
func showDialogue(recover bool, msg string, a ...interface{}) { |
|
|
|
func showDialogue(recover bool, msg string, a ...interface{}) { |
|
|
|
popup = true |
|
|
|
popup = true |
|
|
|
if (!recover) { |
|
|
|
if !recover { |
|
|
|
window.Close() |
|
|
|
window.Close() |
|
|
|
} |
|
|
|
} |
|
|
|
dialogue := widgets.NewQDialog(nil, 0) |
|
|
|
dialogue := widgets.NewQDialog(nil, 0) |
|
|
|