|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/bogosj/tesla"
|
|
|
|
"github.com/therecipe/qt/widgets"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// Info/Statuses
|
|
|
|
batteryLevel *widgets.QLineEdit
|
|
|
|
batteryRange *widgets.QLineEdit
|
|
|
|
chargingState *widgets.QLineEdit
|
|
|
|
minutesToFull *widgets.QLineEdit
|
|
|
|
fastChargerInd *widgets.QLineEdit
|
|
|
|
batteryHeaterInd *widgets.QLineEdit
|
|
|
|
chargeDoorOpenInd *widgets.QLineEdit
|
|
|
|
insideTemp *widgets.QLineEdit
|
|
|
|
outsideTemp *widgets.QLineEdit
|
|
|
|
|
|
|
|
// Controls
|
|
|
|
tempSetting *widgets.QLineEdit
|
|
|
|
climateOn *widgets.QCheckBox
|
|
|
|
lockedDoors *widgets.QCheckBox
|
|
|
|
sentryMode *widgets.QCheckBox
|
|
|
|
startStopCharge *widgets.QCheckBox
|
|
|
|
|
|
|
|
honk *widgets.QPushButton
|
|
|
|
flashLights *widgets.QPushButton
|
|
|
|
trunk *widgets.QPushButton
|
|
|
|
frunk *widgets.QPushButton
|
|
|
|
|
|
|
|
vehicle *tesla.Vehicle
|
|
|
|
vehicleState *tesla.VehicleState
|
|
|
|
chargeStats *tesla.ChargeState
|
|
|
|
climateState *tesla.ClimateState
|
|
|
|
guiSettings *tesla.GuiSettings
|
|
|
|
|
|
|
|
window *widgets.QMainWindow
|
|
|
|
mainApp *widgets.QApplication
|
|
|
|
popup = false
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
mainApp = widgets.NewQApplication(len(os.Args), os.Args)
|
|
|
|
|
|
|
|
vboxLayout := widgets.NewQVBoxLayout()
|
|
|
|
statusLayout := widgets.NewQFormLayout(nil)
|
|
|
|
|
|
|
|
batteryLevel = widgets.NewQLineEdit(nil)
|
|
|
|
batteryLevel.SetReadOnly(true)
|
|
|
|
batteryLevel.SetFixedWidth(30)
|
|
|
|
batteryRange = widgets.NewQLineEdit(nil)
|
|
|
|
batteryRange.SetReadOnly(true)
|
|
|
|
chargingState = widgets.NewQLineEdit(nil)
|
|
|
|
chargingState.SetReadOnly(true)
|
|
|
|
minutesToFull = widgets.NewQLineEdit(nil)
|
|
|
|
minutesToFull.SetReadOnly(true)
|
|
|
|
fastChargerInd = widgets.NewQLineEdit(nil)
|
|
|
|
fastChargerInd.SetReadOnly(true)
|
|
|
|
batteryHeaterInd = widgets.NewQLineEdit(nil)
|
|
|
|
|
|
|
|
batteryHeaterInd.SetReadOnly(true)
|
|
|
|
chargeDoorOpenInd = widgets.NewQLineEdit(nil)
|
|
|
|
chargeDoorOpenInd.SetReadOnly(true)
|
|
|
|
insideTemp = widgets.NewQLineEdit(nil)
|
|
|
|
insideTemp.SetReadOnly(true)
|
|
|
|
insideTemp.SetFixedWidth(25)
|
|
|
|
outsideTemp = widgets.NewQLineEdit(nil)
|
|
|
|
outsideTemp.SetReadOnly(true)
|
|
|
|
outsideTemp.SetFixedWidth(25)
|
|
|
|
tempSetting = widgets.NewQLineEdit(nil)
|
|
|
|
tempSetting.SetFixedWidth(25)
|
|
|
|
|
|
|
|
climateOn = widgets.NewQCheckBox(nil)
|
|
|
|
lockedDoors = widgets.NewQCheckBox(nil)
|
|
|
|
sentryMode = widgets.NewQCheckBox(nil)
|
|
|
|
|
|
|
|
startStopCharge = widgets.NewQCheckBox(nil)
|
|
|
|
|
|
|
|
honk = widgets.NewQPushButton(nil)
|
|
|
|
flashLights = widgets.NewQPushButton(nil)
|
|
|
|
trunk = widgets.NewQPushButton(nil)
|
|
|
|
frunk = widgets.NewQPushButton(nil)
|
|
|
|
|
|
|
|
currentChargeLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
currentChargeLabel.SetText("Current Charge: ")
|
|
|
|
currentRangeLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
currentRangeLabel.SetText("Current Range: ")
|
|
|
|
chargeHbox := widgets.NewQHBoxLayout()
|
|
|
|
chargeHbox.AddWidget(batteryLevel, 0, 0)
|
|
|
|
chargeHbox.AddItem(widgets.NewQSpacerItem(5, 2, widgets.QSizePolicy__Expanding, widgets.QSizePolicy__Expanding))
|
|
|
|
chargeHbox.AddWidget(currentRangeLabel, 0, 0)
|
|
|
|
chargeHbox.AddWidget(batteryRange, 0, 0)
|
|
|
|
statusLayout.AddRow2(currentChargeLabel, chargeHbox)
|
|
|
|
|
|
|
|
setValues()
|
|
|
|
statusLayout.AddRow3("Charging State: ", chargingState)
|
|
|
|
if chargeStats.ChargingState != "Disconnected" {
|
|
|
|
statusLayout.AddRow3("Minutes to Full: ", minutesToFull)
|
|
|
|
if chargeStats.FastChargerPresent {
|
|
|
|
statusLayout.AddRow3("Fast Charger: ", fastChargerInd)
|
|
|
|
}
|
|
|
|
if chargeStats.BatteryHeaterOn {
|
|
|
|
statusLayout.AddRow3("Battey Heater: ", batteryHeaterInd)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
statusLayout.AddRow3("Charge Port: ", chargeDoorOpenInd)
|
|
|
|
|
|
|
|
insideTempLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
outsideTempLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
|
|
|
|
insideTempLabel.SetText("Inside Temp: ")
|
|
|
|
outsideTempLabel.SetText("Outside Temp: ")
|
|
|
|
tempHbox := widgets.NewQHBoxLayout()
|
|
|
|
tempHbox.AddWidget(insideTemp, 0, 0)
|
|
|
|
tempHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed))
|
|
|
|
tempHbox.AddWidget(outsideTempLabel, 0, 0)
|
|
|
|
tempHbox.AddWidget(outsideTemp, 0, 0)
|
|
|
|
statusLayout.AddRow2(insideTempLabel, tempHbox)
|
|
|
|
|
|
|
|
climateEnabledLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
climateEnabledLabel.SetText("Climate On: ")
|
|
|
|
climateSettingLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
climateSettingLabel.SetText("Climate Setting: ")
|
|
|
|
|
|
|
|
climateHbox := widgets.NewQHBoxLayout()
|
|
|
|
climateHbox.AddWidget(climateOn, 0, 0)
|
|
|
|
climateHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed))
|
|
|
|
climateHbox.AddWidget(climateSettingLabel, 0, 0)
|
|
|
|
climateHbox.AddWidget(tempSetting, 0, 0)
|
|
|
|
statusLayout.AddRow2(climateEnabledLabel, climateHbox)
|
|
|
|
|
|
|
|
doorLockLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
sentryModeLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
chargingStateLabel := widgets.NewQLabel(nil, 0)
|
|
|
|
|
|
|
|
doorLockLabel.SetText("Lock Doors: ")
|
|
|
|
sentryModeLabel.SetText("Sentry Mode: ")
|
|
|
|
chargingStateLabel.SetText("Charging: ")
|
|
|
|
securityHbox := widgets.NewQHBoxLayout()
|
|
|
|
securityHbox.AddWidget(lockedDoors, 0, 0)
|
|
|
|
securityHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed))
|
|
|
|
securityHbox.AddWidget(sentryModeLabel, 0, 0)
|
|
|
|
securityHbox.AddWidget(sentryMode, 0, 0)
|
|
|
|
if chargeStats.ChargingState != "Disconnected" {
|
|
|
|
securityHbox.AddItem(widgets.NewQSpacerItem(10, 10, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed))
|
|
|
|
securityHbox.AddWidget(chargingStateLabel, 0, 0)
|
|
|
|
securityHbox.AddWidget(startStopCharge, 0, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
lockedDoors.ConnectStateChanged(lockDoors)
|
|
|
|
sentryMode.ConnectStateChanged(sentryModeEnable)
|
|
|
|
startStopCharge.ConnectStateChanged(enableCharging)
|
|
|
|
climateOn.ConnectStateChanged(enableClimate)
|
|
|
|
statusLayout.AddRow2(doorLockLabel, securityHbox)
|
|
|
|
|
|
|
|
honk = widgets.NewQPushButton(nil)
|
|
|
|
flashLights = widgets.NewQPushButton(nil)
|
|
|
|
trunk = widgets.NewQPushButton(nil)
|
|
|
|
frunk = widgets.NewQPushButton(nil)
|
|
|
|
|
|
|
|
honk.ConnectClicked(honkHorn)
|
|
|
|
honk.SetText("Honk")
|
|
|
|
flashLights.ConnectClicked(flash)
|
|
|
|
flashLights.SetText("Flash")
|
|
|
|
trunk.ConnectClicked(openTrunk)
|
|
|
|
trunk.SetText("Trunk")
|
|
|
|
frunk.ConnectClicked(openFrunk)
|
|
|
|
frunk.SetText("Frunk")
|
|
|
|
|
|
|
|
actionHbox := widgets.NewQHBoxLayout()
|
|
|
|
actionHbox.AddWidget(honk, 0, 0)
|
|
|
|
actionHbox.AddItem(widgets.NewQSpacerItem(2, 2, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed))
|
|
|
|
|
|
|
|
actionHbox.AddWidget(flashLights, 0, 0)
|
|
|
|
actionHbox.AddItem(widgets.NewQSpacerItem(2, 2, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed))
|
|
|
|
|
|
|
|
actionHbox.AddWidget(trunk, 0, 0)
|
|
|
|
actionHbox.AddItem(widgets.NewQSpacerItem(2, 2, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed))
|
|
|
|
|
|
|
|
actionHbox.AddWidget(frunk, 0, 0)
|
|
|
|
actionHbox.AddItem(widgets.NewQSpacerItem(2, 2, widgets.QSizePolicy__Fixed, widgets.QSizePolicy__Fixed))
|
|
|
|
|
|
|
|
statusLayout.AddRow6(actionHbox)
|
|
|
|
|
|
|
|
vboxLayout.AddItem(statusLayout)
|
|
|
|
|
|
|
|
window = widgets.NewQMainWindow(nil, 0)
|
|
|
|
window.SetWindowTitle(fmt.Sprintf("%+v: %+v", vehicle.DisplayName, vehicle.Vin))
|
|
|
|
centralWidget := widgets.NewQWidget(window, 0)
|
|
|
|
centralWidget.SetLayout(vboxLayout)
|
|
|
|
window.SetCentralWidget(centralWidget)
|
|
|
|
if !popup {
|
|
|
|
window.Show()
|
|
|
|
}
|
|
|
|
widgets.QApplication_Exec()
|
|
|
|
}
|
|
|
|
|
|
|
|
func setValues() {
|
|
|
|
vehicle = getVehicle("")
|
|
|
|
var err error
|
|
|
|
if vehicle == nil {
|
|
|
|
showDialogue("Unable to get vehicle")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
vehicleState, err = vehicle.VehicleState()
|
|
|
|
if err != nil {
|
|
|
|
showDialogue("Unable to get Vehicle State")
|
|
|
|
}
|
|
|
|
chargeStats, err = vehicle.ChargeState()
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
showDialogue("Unable to get Vehicle Charge State")
|
|
|
|
}
|
|
|
|
climateState, err = vehicle.ClimateState()
|
|
|
|
if err != nil {
|
|
|
|
showDialogue("Unable to get Vehicle Climate")
|
|
|
|
}
|
|
|
|
guiSettings, err = vehicle.GuiSettings()
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
showDialogue("Unable to get Gui Settings")
|
|
|
|
}
|
|
|
|
tempSettingVal := climateState.DriverTempSetting
|
|
|
|
insideTempVal := climateState.InsideTemp
|
|
|
|
outsideTempVal := climateState.OutsideTemp
|
|
|
|
if guiSettings.GuiTemperatureUnits == "F" {
|
|
|
|
tempSettingVal = (climateState.DriverTempSetting * 1.8) + 32
|
|
|
|
insideTempVal = (climateState.InsideTemp * 1.8) + 32
|
|
|
|
outsideTempVal = (climateState.OutsideTemp * 1.8) + 32
|
|
|
|
}
|
|
|
|
batteryLevel.SetText(fmt.Sprintf("%+v", chargeStats.BatteryLevel))
|
|
|
|
batteryRange.SetText(fmt.Sprintf("%.2f%+v", chargeStats.BatteryRange,
|
|
|
|
strings.Replace(guiSettings.GuiDistanceUnits, "/hr", "", -1)))
|
|
|
|
batteryRange.SetFixedWidth(10 * len(batteryRange.Text()))
|
|
|
|
chargingState.SetText(chargeStats.ChargingState)
|
|
|
|
|
|
|
|
minutesToFull.SetText(fmt.Sprintf("%+v", chargeStats.MinutesToFullCharge))
|
|
|
|
|
|
|
|
fastChargerInd.SetText(chargeStats.FastChargerBrand)
|
|
|
|
if chargeStats.BatteryHeaterOn {
|
|
|
|
batteryHeaterInd.SetText("On")
|
|
|
|
}
|
|
|
|
|
|
|
|
if chargeStats.ChargePortDoorOpen {
|
|
|
|
chargeDoorOpenInd.SetText("Open")
|
|
|
|
} else {
|
|
|
|
chargeDoorOpenInd.SetText("Closed")
|
|
|
|
}
|
|
|
|
|
|
|
|
insideTemp.SetText(fmt.Sprintf("%.0f", insideTempVal))
|
|
|
|
outsideTemp.SetText(fmt.Sprintf("%.0f", outsideTempVal))
|
|
|
|
tempSetting.SetText(fmt.Sprintf("%.0f", tempSettingVal))
|
|
|
|
|
|
|
|
climateOn.SetChecked(climateState.IsClimateOn)
|
|
|
|
if vehicleState != nil {
|
|
|
|
lockedDoors.SetChecked(vehicleState.Locked)
|
|
|
|
sentryMode.SetChecked(vehicleState.SentryMode)
|
|
|
|
} else {
|
|
|
|
lockedDoors.SetCheckable(false)
|
|
|
|
sentryMode.SetCheckable(false)
|
|
|
|
}
|
|
|
|
startStopCharge.SetChecked(chargeStats.ChargingState == "Charging")
|
|
|
|
if chargeStats.ChargingState == "Disconnected" {
|
|
|
|
startStopCharge.SetCheckable(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func enableClimate(i int) {
|
|
|
|
if i == 0 {
|
|
|
|
vehicle.StartAirConditioning()
|
|
|
|
} else {
|
|
|
|
vehicle.StopAirConditioning()
|
|
|
|
}
|
|
|
|
go setValues()
|
|
|
|
}
|
|
|
|
|
|
|
|
func lockDoors(i int) {
|
|
|
|
if i == 0 {
|
|
|
|
vehicle.UnlockDoors()
|
|
|
|
} else {
|
|
|
|
vehicle.LockDoors()
|
|
|
|
}
|
|
|
|
go setValues()
|
|
|
|
}
|
|
|
|
|
|
|
|
func sentryModeEnable(i int) {
|
|
|
|
if i == 0 {
|
|
|
|
showDialogue("Unable to disable sentry mode.\nUnsupported.")
|
|
|
|
} else {
|
|
|
|
vehicle.EnableSentry()
|
|
|
|
}
|
|
|
|
go setValues()
|
|
|
|
}
|
|
|
|
|
|
|
|
func enableCharging(i int) {
|
|
|
|
if i == 0 {
|
|
|
|
vehicle.StartCharging()
|
|
|
|
} else {
|
|
|
|
vehicle.StopCharging()
|
|
|
|
}
|
|
|
|
go setValues()
|
|
|
|
}
|
|
|
|
|
|
|
|
func honkHorn(c bool) {
|
|
|
|
err := vehicle.HonkHorn()
|
|
|
|
if err != nil {
|
|
|
|
showDialogue("There was an error honking the horn\n%+v", err)
|
|
|
|
fmt.Printf("%+v\n", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func flash(c bool) {
|
|
|
|
err := vehicle.FlashLights()
|
|
|
|
if err != nil {
|
|
|
|
showDialogue("There was an error flashing the lights\n%+v", err)
|
|
|
|
fmt.Printf("%+v\n", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func openTrunk(c bool) {
|
|
|
|
err := vehicle.OpenTrunk("rear")
|
|
|
|
if err != nil {
|
|
|
|
showDialogue("There was an error opening your trunk\n%+v", err)
|
|
|
|
fmt.Printf("%+v\n", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func openFrunk(c bool) {
|
|
|
|
err := vehicle.OpenTrunk("front")
|
|
|
|
if err != nil {
|
|
|
|
showDialogue("There was an error opening your frunk\n%+v", err)
|
|
|
|
fmt.Printf("%+v\n", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func showDialogue(msg string, a ...interface{}) {
|
|
|
|
popup = true
|
|
|
|
dialogue := widgets.NewQDialog(nil, 0)
|
|
|
|
dialogue.SetWindowTitle("TeslaGo Alert")
|
|
|
|
actionHBox := widgets.NewQHBoxLayout()
|
|
|
|
formLayout := widgets.NewQFormLayout(nil)
|
|
|
|
|
|
|
|
contBtn := widgets.NewQPushButton(nil)
|
|
|
|
quitBtn := widgets.NewQPushButton(nil)
|
|
|
|
|
|
|
|
contBtn.SetText("Continue")
|
|
|
|
quitBtn.SetText("Quit")
|
|
|
|
|
|
|
|
contBtn.ConnectClicked(func(checked bool) {
|
|
|
|
window.Show()
|
|
|
|
popup = false
|
|
|
|
dialogue.Close()
|
|
|
|
|
|
|
|
go setValues()
|
|
|
|
})
|
|
|
|
quitBtn.ConnectClicked(func(checked bool) {
|
|
|
|
mainApp.Quit()
|
|
|
|
})
|
|
|
|
|
|
|
|
actionHBox.AddWidget(contBtn, 0, 0)
|
|
|
|
actionHBox.AddWidget(quitBtn, 0, 0)
|
|
|
|
|
|
|
|
message := widgets.NewQLabel(nil, 0)
|
|
|
|
message.SetText(fmt.Sprintf(msg, a...))
|
|
|
|
message.SetWordWrap(true)
|
|
|
|
|
|
|
|
formLayout.AddRow5(message)
|
|
|
|
formLayout.AddRow6(actionHBox)
|
|
|
|
centralWidget := widgets.NewQWidget(dialogue, 0)
|
|
|
|
centralWidget.SetLayout(formLayout)
|
|
|
|
dialogue.SetMinimumWidth(255)
|
|
|
|
dialogue.SetMinimumHeight(50 + (20 * (1 + strings.Count(msg, "\n"))))
|
|
|
|
|
|
|
|
dialogue.Show()
|
|
|
|
}
|