Skip to content

Commit

Permalink
tesla-control: enable/disable valet mode
Browse files Browse the repository at this point in the history
Adds valet mode commands to the tesla-control CLI tool. These commands
were already supported in the library and HTTP proxy.
  • Loading branch information
Seth Terashima authored and sethterashima committed Oct 30, 2024
1 parent 5a61b6a commit 55b7965
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 1 deletion.
19 changes: 19 additions & 0 deletions cmd/tesla-control/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,25 @@ func (c *Command) Usage(name string) {
}

var commands = map[string]*Command{
"valet-mode-on": &Command{
help: "Enable valet mode",
requiresAuth: true,
requiresFleetAPI: false,
args: []Argument{
Argument{name: "PIN", help: "Valet mode PIN"},
},
handler: func(ctx context.Context, acct *account.Account, car *vehicle.Vehicle, args map[string]string) error {
return car.EnableValetMode(ctx, args["PIN"])
},
},
"valet-mode-off": &Command{
help: "Disable valet mode",
requiresAuth: true,
requiresFleetAPI: false,
handler: func(ctx context.Context, acct *account.Account, car *vehicle.Vehicle, args map[string]string) error {
return car.DisableValetMode(ctx)
},
},
"unlock": &Command{
help: "Unlock vehicle",
requiresAuth: true,
Expand Down
41 changes: 40 additions & 1 deletion pkg/vehicle/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package vehicle
import (
"context"
"crypto/ecdh"
"errors"
"strings"

"google.golang.org/protobuf/proto"

Expand All @@ -13,8 +15,41 @@ import (
"github.com/teslamotors/vehicle-command/pkg/protocol/protobuf/vcsec"
)

// IsValidPIN returns true if the pin is four digits.
func IsValidPIN(pin string) bool {
if len(pin) != 4 {
return false
}
for _, c := range pin {
if c < '0' || c > '9' {
return false
}
}
return true
}

var ErrInvalidPIN = errors.New("PIN codes must be four digits")

// EnableValetMode enters the vehicle's Valet Mode. This sets certain restrictions but disables PIN
// to Drive. Consult the Owner's Manual for details. The PIN must be a four-digit string.
func (v *Vehicle) EnableValetMode(ctx context.Context, pin string) error {
return v.SetValetMode(ctx, true, pin)
}

// DisableValetMode exits Valet Mode.
func (v *Vehicle) DisableValetMode(ctx context.Context) error {
return v.SetValetMode(ctx, false, "")
}

// SetValetMode enables or disables Valet Mode. A password must be provided when turning valet mode
// on, and should be empty when turning valet mode off.
//
// Deprecated: Use EnableValetMode or DisableValetMode.
func (v *Vehicle) SetValetMode(ctx context.Context, on bool, valetPassword string) error {
return v.executeCarServerAction(ctx,
if on && !IsValidPIN(valetPassword) {
return ErrInvalidPIN
}
err := v.executeCarServerAction(ctx,
&carserver.Action_VehicleAction{
VehicleAction: &carserver.VehicleAction{
VehicleActionMsg: &carserver.VehicleAction_VehicleControlSetValetModeAction{
Expand All @@ -25,6 +60,10 @@ func (v *Vehicle) SetValetMode(ctx context.Context, on bool, valetPassword strin
},
},
})
if !on && err != nil && strings.HasSuffix(err.Error(), "already off") {
return nil
}
return err
}

func (v *Vehicle) ResetValetPin(ctx context.Context) error {
Expand Down
30 changes: 30 additions & 0 deletions pkg/vehicle/security_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package vehicle

import (
"testing"
)

func TestValidPIN(t *testing.T) {
validPINs := []string{
"0000",
"0123",
"4569",
}
invalidPINs := []string{
"",
"123a",
"12345",
"1",
"four",
}
for _, p := range validPINs {
if !IsValidPIN(p) {
t.Errorf("%s is a valid PIN", p)
}
}
for _, p := range invalidPINs {
if IsValidPIN(p) {
t.Errorf("%s is not a valid PIN", p)
}
}
}

0 comments on commit 55b7965

Please sign in to comment.