Skip to content

Commit

Permalink
Allow configuring which BT adapter to use
Browse files Browse the repository at this point in the history
Uses diferent vehicle-command, untill teslamotors/vehicle-command#370 gets merged
  • Loading branch information
Lenart12 committed Feb 5, 2025
1 parent b971a05 commit f23f624
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 9 deletions.
18 changes: 18 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"net/url"
"os"
"strings"

"github.com/akamensky/argparse"
"github.com/charmbracelet/log"
Expand All @@ -19,6 +20,7 @@ type Config struct {
CacheMaxAge int // Seconds to cache BLE responses
DashboardBaseURL string // Base URL for proxying dashboard (Useful if the proxy is behind a reverse proxy)
ApiBaseUrl string // Base URL for proxying BLE commands (Useful if the proxy is behind a reverse proxy)
BdAddr string // BLE device address (optional)
}

var AppConfig *Config
Expand Down Expand Up @@ -56,6 +58,21 @@ func LoadConfig() *Config {
}})
dashboardBaseUrl := parser.String("d", "dashboardBaseUrl", &argparse.Options{Help: "Base URL for dashboard (Useful if the proxy is behind a reverse proxy)", Default: ""})
apiBaseUrl := parser.String("a", "apiBaseUrl", &argparse.Options{Help: "Base URL for proxying API commands", Default: ""})
bdAddr := parser.String("B", "bdAddr", &argparse.Options{Help: "Bluetooth device address of the wanted adapter (pick first available adapter by default)", Default: "", Validate: func(args []string) error {
if args[0] != "" {
parts := strings.Split(args[0], ":")
if len(parts) != 6 {
return fmt.Errorf("invalid Bluetooth device address (must be MAC address format)")
}
for _, part := range parts {
if len(part) != 2 {
return fmt.Errorf("invalid Bluetooth device address (must be MAC address format)")
}
}
}
return nil
}})

// Inject environment variables as command line arguments
args := os.Args
for _, arg := range parser.GetArgs() {
Expand Down Expand Up @@ -83,6 +100,7 @@ func LoadConfig() *Config {
CacheMaxAge: *cacheMaxAge,
DashboardBaseURL: *dashboardBaseUrl,
ApiBaseUrl: *apiBaseUrl,
BdAddr: *bdAddr,
}
}

Expand Down
8 changes: 5 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ module github.com/wimaha/TeslaBleHttpProxy
go 1.23.3

require (
github.com/akamensky/argparse v1.4.0
github.com/charmbracelet/log v0.4.0
github.com/gorilla/mux v1.8.1
github.com/pkg/errors v0.9.1
github.com/teslamotors/vehicle-command v0.3.3-0.20250128004836-ebad42aaa852
google.golang.org/protobuf v1.34.2
)

require (
github.com/JuulLabs-OSS/cbgo v0.0.2 // indirect
github.com/akamensky/argparse v1.4.0 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/lipgloss v0.12.1 // indirect
github.com/charmbracelet/x/ansi v0.1.4 // indirect
Expand All @@ -25,12 +27,12 @@ require (
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mgutz/logxi v0.0.0-20161027140823-aebf8a7d67ab // indirect
github.com/muesli/termenv v0.15.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/raff/goble v0.0.0-20200327175727-d63360dcfd80 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/stretchr/testify v1.10.0 // indirect
golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect
golang.org/x/sys v0.24.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
)

replace github.com/teslamotors/vehicle-command => github.com/Lenart12/vehicle-command v0.0.0-20250205103646-aa48216fb084
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/JuulLabs-OSS/cbgo v0.0.1/go.mod h1:L4YtGP+gnyD84w7+jN66ncspFRfOYB5aj9QSXaFHmBA=
github.com/JuulLabs-OSS/cbgo v0.0.2 h1:gCDyT0+EPuI8GOFyvAksFcVD2vF4CXBAVwT6uVnD9oo=
github.com/JuulLabs-OSS/cbgo v0.0.2/go.mod h1:L4YtGP+gnyD84w7+jN66ncspFRfOYB5aj9QSXaFHmBA=
github.com/Lenart12/vehicle-command v0.0.0-20250205103646-aa48216fb084 h1:Os2oDKV6DvA4qsARuf4MeiPhi+9Hog7ngpWxZrR9+0w=
github.com/Lenart12/vehicle-command v0.0.0-20250205103646-aa48216fb084/go.mod h1:ZVR0KE8v3IrQUJAuBrxKkRjPZOVI0oxEqBj8x1eFpDQ=
github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc=
github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
Expand Down
7 changes: 1 addition & 6 deletions internal/ble/control/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
"time"

Expand Down Expand Up @@ -293,11 +292,7 @@ func (bc *BleControl) TryConnectToVehicle(ctx context.Context, firstCommand *com

beacon, err := ble.ScanVehicleBeacon(scanCtx, firstCommand.Vin)
if err != nil {
if strings.Contains(err.Error(), "operation not permitted") {
// The underlying BLE package calls HCIDEVDOWN on the BLE device, presumably as a
// heavy-handed way of dealing with devices that are in a bad state.
return nil, nil, false, fmt.Errorf("failed to scan for vehicle: %s\nTry again after granting this application CAP_NET_ADMIN:\nsudo setcap 'cap_net_admin=eip' \"$(which %s)\"", err, os.Args[0])
} else if scanCtx.Err() != nil {
if scanCtx.Err() != nil {
return nil, nil, false, fmt.Errorf("vehicle not in range: %s", err)
} else {
return nil, nil, true, fmt.Errorf("failed to scan for vehicle: %s", err)
Expand Down
17 changes: 17 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ package main

import (
"embed"
"fmt"
"net/http"
"os"
"strings"

"github.com/charmbracelet/log"
goble "github.com/go-ble/ble"
"github.com/teslamotors/vehicle-command/pkg/connector/ble"
"github.com/wimaha/TeslaBleHttpProxy/config"
"github.com/wimaha/TeslaBleHttpProxy/internal/api/routes"
"github.com/wimaha/TeslaBleHttpProxy/internal/ble/control"
Expand All @@ -25,6 +30,18 @@ func main() {
level, _ := log.ParseLevel(config.AppConfig.LogLevel)
log.SetLevel(level)

// Initialize the BLE device before starting the proxy server
err := ble.InitDevice(goble.NewAddr(config.AppConfig.BdAddr))
if err != nil {
if strings.Contains(err.Error(), "operation not permitted") {
// The underlying BLE package calls HCIDEVDOWN on the BLE device, presumably as a
// heavy-handed way of dealing with devices that are in a bad state.
log.Fatal(fmt.Errorf("failed to initialize BLE device: %s\nTry again after granting this application CAP_NET_ADMIN:\nsudo setcap 'cap_net_admin=eip' \"$(which %s)\"", err, os.Args[0]))
} else {
log.Fatal(fmt.Errorf("failed to initialize BLE device: %s", err))
}
}

control.SetupBleControl()

router := routes.SetupRoutes(static, html)
Expand Down

0 comments on commit f23f624

Please sign in to comment.