|
package main |
|
|
|
import ( |
|
"encoding/json" |
|
"errors" |
|
"fmt" |
|
"os" |
|
"strconv" |
|
"time" |
|
|
|
"github.com/jsgoecke/tesla" |
|
"github.com/spf13/viper" |
|
"gopkg.in/redis.v4" |
|
) |
|
|
|
func makeTimeStamp() string { |
|
return strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10) |
|
} |
|
|
|
func storeStatusInRedis(redis_client *redis.Client, chargeState *tesla.ChargeState) error { |
|
if chargeState == nil || redis_client == nil { |
|
return errors.New("nil argument passed") |
|
} |
|
stringChargeState := make(map[string]string) |
|
stringChargeState["When"] = makeTimeStamp() |
|
stringChargeState["ChargingState"] = chargeState.ChargingState |
|
stringChargeState["ChargeLimitSoc"] = strconv.Itoa(chargeState.ChargeLimitSoc) |
|
stringChargeState["BatteryLevel"] = strconv.Itoa(chargeState.BatteryLevel) |
|
stringChargeState["UsableBatteryLevel"] = strconv.Itoa(chargeState.UsableBatteryLevel) |
|
stringChargeState["ChargeCurrentRequest"] = strconv.Itoa(chargeState.ChargeCurrentRequest) |
|
stringChargeState["ChargeCurrentRequestMax"] = strconv.Itoa(chargeState.ChargeCurrentRequestMax) |
|
stringChargeState["BatteryRange"] = strconv.FormatFloat(chargeState.BatteryRange*1.60934, 'f', 2, 64) |
|
stringChargeState["EstBatteryRange"] = strconv.FormatFloat(chargeState.EstBatteryRange*1.60934, 'f', 2, 64) |
|
stringChargeState["IdealBatteryRange"] = strconv.FormatFloat(chargeState.IdealBatteryRange*1.60934, 'f', 2, 64) |
|
stringChargeState["ChargeEnergyAdded"] = strconv.FormatFloat(chargeState.ChargeEnergyAdded, 'f', 2, 64) |
|
stringChargeState["ChargeRangeAddedRated"] = strconv.FormatFloat(chargeState.ChargeMilesAddedRated*1.60934, 'f', 2, 64) |
|
stringChargeState["ChargeRangeAddedIdeal"] = strconv.FormatFloat(chargeState.ChargeMilesAddedIdeal*1.60934, 'f', 2, 64) |
|
stringChargeState["TimeToFullCharge"] = strconv.FormatFloat(chargeState.TimeToFullCharge, 'f', 2, 64) |
|
stringChargeState["ChargeRate"] = strconv.FormatFloat(chargeState.ChargeRate, 'f', 2, 64) |
|
stringChargeState["ChargePortDoorOpen"] = strconv.FormatBool(chargeState.ChargePortDoorOpen) |
|
|
|
_, err := redis_client.HMSet("tesla_state", stringChargeState).Result() |
|
if err != nil { |
|
return (err) |
|
} |
|
return (nil) |
|
} |
|
|
|
func main() { |
|
viper.SetConfigName("tesla") |
|
viper.AddConfigPath("$HOME/.config/") |
|
viper.AddConfigPath(".") |
|
err := viper.ReadInConfig() |
|
if err != nil { |
|
panic(err) |
|
} |
|
|
|
redis_client := redis.NewClient(&redis.Options{ |
|
Addr: "localhost:6379", |
|
Password: "", |
|
DB: 0, |
|
}) |
|
|
|
_, err = redis_client.Ping().Result() |
|
if err != nil { |
|
redis_client = nil |
|
} |
|
|
|
client, err := tesla.NewClient( |
|
&tesla.Auth{ |
|
ClientID: viper.GetString("client_id"), |
|
ClientSecret: viper.GetString("client_secret"), |
|
Email: viper.GetString("username"), |
|
Password: viper.GetString("password"), |
|
}) |
|
if err != nil { |
|
panic(err) |
|
} |
|
|
|
vehicles, err := client.Vehicles() |
|
if err != nil { |
|
panic(err) |
|
} |
|
vehicle := vehicles[0] |
|
|
|
if len(os.Args) == 2 { |
|
if os.Args[1] == "start" { |
|
vehicle.StartCharging() |
|
} else if os.Args[1] == "stop" { |
|
vehicle.StopCharging() |
|
} else if os.Args[1] == "state" || os.Args[1] == "status" { |
|
chargeState, _ := vehicle.ChargeState() |
|
data, err := json.Marshal(chargeState) |
|
if err != nil { |
|
panic(err) |
|
} |
|
fmt.Println(string(data)) |
|
if redis_client != nil { |
|
err = storeStatusInRedis(redis_client, chargeState) |
|
if err != nil { |
|
panic(err) |
|
} |
|
} |
|
} else { |
|
i, err := strconv.Atoi(os.Args[1]) |
|
if err != nil { |
|
fmt.Println("Usage: tesla [state|start|stop|50-100]") |
|
} else { |
|
chargeState, err := vehicle.ChargeState() |
|
if err != nil { |
|
panic(err) |
|
} |
|
if chargeState.ChargeLimitSoc != i { |
|
err := vehicle.SetChargeLimit(i) |
|
if err != nil { |
|
panic(err) |
|
} |
|
chargeState, err = vehicle.ChargeState() |
|
if err != nil { |
|
panic(err) |
|
} |
|
} |
|
data, err := json.Marshal(chargeState) |
|
if err != nil { |
|
panic(err) |
|
} |
|
fmt.Println(string(data)) |
|
if redis_client != nil { |
|
err = storeStatusInRedis(redis_client, chargeState) |
|
if err != nil { |
|
panic(err) |
|
} |
|
} |
|
} |
|
} |
|
} else { |
|
fmt.Println("Usage: tesla_charge [start|stop]") |
|
} |
|
} |