Fix various issues in NRGKick implementation (#164)
This commit is contained in:
parent
bc4fcead95
commit
044eb8732e
3 changed files with 60 additions and 51 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/muka/go-bluetooth/api"
|
||||
"github.com/muka/go-bluetooth/bluez/profile/adapter"
|
||||
|
|
@ -11,19 +12,19 @@ import (
|
|||
"github.com/muka/go-bluetooth/bluez/profile/device"
|
||||
)
|
||||
|
||||
func FindDevice(a *adapter.Adapter1, hwaddr string) (*device.Device1, error) {
|
||||
dev, err := Discover(a, hwaddr)
|
||||
func FindDevice(a *adapter.Adapter1, hwaddr string, timeout time.Duration) (*device.Device1, error) {
|
||||
dev, err := Discover(a, hwaddr, timeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dev == nil {
|
||||
return nil, errors.New("Device not found, is it advertising?")
|
||||
return nil, errors.New("device not found, is it advertising?")
|
||||
}
|
||||
|
||||
return dev, nil
|
||||
}
|
||||
|
||||
func Discover(a *adapter.Adapter1, hwaddr string) (*device.Device1, error) {
|
||||
func Discover(a *adapter.Adapter1, hwaddr string, timeout time.Duration) (*device.Device1, error) {
|
||||
err := a.FlushDevices()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -34,28 +35,31 @@ func Discover(a *adapter.Adapter1, hwaddr string) (*device.Device1, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
defer cancel()
|
||||
timer := time.NewTimer(timeout)
|
||||
|
||||
for ev := range discovery {
|
||||
dev, err1 := device.NewDevice1(ev.Path)
|
||||
if err != nil {
|
||||
return nil, err1
|
||||
for {
|
||||
select {
|
||||
case ev := <-discovery:
|
||||
dev, err := device.NewDevice1(ev.Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dev == nil || dev.Properties == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
p := dev.Properties
|
||||
if p.Address != hwaddr {
|
||||
continue
|
||||
}
|
||||
|
||||
cancel()
|
||||
return dev, nil
|
||||
case <-timer.C:
|
||||
cancel()
|
||||
return nil, errors.New("discovery timeout exceeded")
|
||||
}
|
||||
|
||||
if dev == nil || dev.Properties == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
p := dev.Properties
|
||||
|
||||
if p.Address != hwaddr {
|
||||
continue
|
||||
}
|
||||
|
||||
return dev, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func Connect(dev *device.Device1, ag *agent.SimpleAgent, adapterID string) error {
|
||||
|
|
|
|||
|
|
@ -18,16 +18,20 @@ import (
|
|||
"github.com/muka/go-bluetooth/hw"
|
||||
)
|
||||
|
||||
const nrgTimeout = 30 * time.Second
|
||||
|
||||
// NRGKickBLE charger implementation
|
||||
type NRGKickBLE struct {
|
||||
log *util.Logger
|
||||
timer *time.Timer
|
||||
adapter *adapter.Adapter1
|
||||
agent *agent.SimpleAgent
|
||||
dev *device.Device1
|
||||
device string
|
||||
macaddress string
|
||||
pin int
|
||||
log *util.Logger
|
||||
timer *time.Timer
|
||||
adapter *adapter.Adapter1
|
||||
agent *agent.SimpleAgent
|
||||
dev *device.Device1
|
||||
device string
|
||||
macaddress string
|
||||
pin int
|
||||
pauseCharging bool
|
||||
current int
|
||||
}
|
||||
|
||||
// NewNRGKickBLEFromConfig creates a NRGKickBLE charger from generic config
|
||||
|
|
@ -107,9 +111,9 @@ func NewNRGKickBLE(device, macaddress string, pin int) *NRGKickBLE {
|
|||
}
|
||||
|
||||
func (nrg *NRGKickBLE) connect() (*device.Device1, error) {
|
||||
dev, err := nrgble.FindDevice(nrg.adapter, nrg.macaddress)
|
||||
dev, err := nrgble.FindDevice(nrg.adapter, nrg.macaddress, nrgTimeout)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("findDevice: %s", err)
|
||||
return nil, fmt.Errorf("find device: %s", err)
|
||||
}
|
||||
|
||||
err = nrgble.Connect(dev, nrg.agent, nrg.device)
|
||||
|
|
@ -196,15 +200,16 @@ func (nrg *NRGKickBLE) write(service string, val interface{}) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (nrg *NRGKickBLE) defaultSettings(info nrgble.Info) nrgble.Settings {
|
||||
func (nrg *NRGKickBLE) mergeSettings(info nrgble.Info) nrgble.Settings {
|
||||
return nrgble.Settings{
|
||||
PIN: nrg.pin,
|
||||
ChargingEnergyLimit: 19997, // magic const for "disable"
|
||||
KWhPer100: info.KWhPer100,
|
||||
AmountPerKWh: info.AmountPerKWh,
|
||||
Efficiency: info.Efficiency,
|
||||
PauseCharging: info.PauseCharging,
|
||||
BLETransmissionPower: info.BLETransmissionPower,
|
||||
PauseCharging: nrg.pauseCharging, // apply last value
|
||||
Current: nrg.current, // apply last value
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +220,7 @@ func (nrg *NRGKickBLE) Status() (api.ChargeStatus, error) {
|
|||
return api.StatusF, err
|
||||
}
|
||||
|
||||
nrg.log.TRACE.Printf("power: %+v", res)
|
||||
nrg.log.TRACE.Printf("read power: %+v", res)
|
||||
|
||||
switch res.CPSignal {
|
||||
case 3:
|
||||
|
|
@ -237,7 +242,7 @@ func (nrg *NRGKickBLE) Enabled() (bool, error) {
|
|||
return false, err
|
||||
}
|
||||
|
||||
nrg.log.TRACE.Printf("info: %+v", res)
|
||||
nrg.log.TRACE.Printf("read info: %+v", res)
|
||||
|
||||
return !res.PauseCharging, nil
|
||||
}
|
||||
|
|
@ -249,10 +254,10 @@ func (nrg *NRGKickBLE) Enable(enable bool) error {
|
|||
return err
|
||||
}
|
||||
|
||||
nrg.log.TRACE.Printf("info: %+v", res)
|
||||
nrg.pauseCharging = !enable // use cached value to work around API roundtrip delay
|
||||
settings := nrg.mergeSettings(res)
|
||||
|
||||
settings := nrg.defaultSettings(res)
|
||||
settings.PauseCharging = !enable
|
||||
nrg.log.TRACE.Printf("write settings: %+v", settings)
|
||||
|
||||
return nrg.write(nrgble.SettingsService, &settings)
|
||||
}
|
||||
|
|
@ -264,10 +269,10 @@ func (nrg *NRGKickBLE) MaxCurrent(current int64) error {
|
|||
return err
|
||||
}
|
||||
|
||||
nrg.log.TRACE.Printf("info: %+v", res)
|
||||
nrg.current = int(current) // use cached value to work around API roundtrip delay
|
||||
settings := nrg.mergeSettings(res)
|
||||
|
||||
settings := nrg.defaultSettings(res)
|
||||
settings.Current = int(current)
|
||||
nrg.log.TRACE.Printf("write settings: %+v", settings)
|
||||
|
||||
return nrg.write(nrgble.SettingsService, &settings)
|
||||
}
|
||||
|
|
@ -279,7 +284,7 @@ func (nrg *NRGKickBLE) CurrentPower() (float64, error) {
|
|||
return 0, err
|
||||
}
|
||||
|
||||
nrg.log.TRACE.Printf("power: %+v", res)
|
||||
nrg.log.TRACE.Printf("read power: %+v", res)
|
||||
|
||||
return float64(res.TotalPower) * 10, nil
|
||||
}
|
||||
|
|
@ -291,7 +296,7 @@ func (nrg *NRGKickBLE) TotalEnergy() (float64, error) {
|
|||
return 0, err
|
||||
}
|
||||
|
||||
nrg.log.TRACE.Printf("energy: %+v", res)
|
||||
nrg.log.TRACE.Printf("read energy: %+v", res)
|
||||
|
||||
return float64(res.TotalEnergy) / 1000, nil
|
||||
}
|
||||
|
|
@ -303,7 +308,7 @@ func (nrg *NRGKickBLE) Currents() (float64, float64, float64, error) {
|
|||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
nrg.log.TRACE.Printf("voltage/current: %+v", res)
|
||||
nrg.log.TRACE.Printf("read voltage/current: %+v", res)
|
||||
|
||||
return float64(res.CurrentL1) / 100,
|
||||
float64(res.CurrentL2) / 100,
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ func (nrg *NRGKickConnect) Status() (api.ChargeStatus, error) {
|
|||
// Enabled implements the Charger.Enabled interface
|
||||
func (nrg *NRGKickConnect) Enabled() (bool, error) {
|
||||
var settings NRGSettings
|
||||
err := nrg.getJSON(nrg.apiURL(apiSettings), settings)
|
||||
err := nrg.getJSON(nrg.apiURL(apiSettings), &settings)
|
||||
|
||||
return *settings.Values.ChargingStatus.Charging, err
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ func (nrg *NRGKickConnect) MaxCurrent(current int64) error {
|
|||
// CurrentPower implements the Meter interface
|
||||
func (nrg *NRGKickConnect) CurrentPower() (float64, error) {
|
||||
var measurements NRGMeasurements
|
||||
err := nrg.getJSON(nrg.apiURL(apiMeasurements), measurements)
|
||||
err := nrg.getJSON(nrg.apiURL(apiMeasurements), &measurements)
|
||||
|
||||
return 1000 * measurements.ChargingPower, err
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ func (nrg *NRGKickConnect) CurrentPower() (float64, error) {
|
|||
// TotalEnergy implements the MeterEnergy interface
|
||||
func (nrg *NRGKickConnect) TotalEnergy() (float64, error) {
|
||||
var measurements NRGMeasurements
|
||||
err := nrg.getJSON(nrg.apiURL(apiMeasurements), measurements)
|
||||
err := nrg.getJSON(nrg.apiURL(apiMeasurements), &measurements)
|
||||
|
||||
return measurements.ChargingEnergyOverAll, err
|
||||
}
|
||||
|
|
@ -173,7 +173,7 @@ func (nrg *NRGKickConnect) TotalEnergy() (float64, error) {
|
|||
// Currents implements the MeterCurrent interface
|
||||
func (nrg *NRGKickConnect) Currents() (float64, float64, float64, error) {
|
||||
var measurements NRGMeasurements
|
||||
err := nrg.getJSON(nrg.apiURL(apiMeasurements), measurements)
|
||||
err := nrg.getJSON(nrg.apiURL(apiMeasurements), &measurements)
|
||||
|
||||
if len(measurements.ChargingCurrentPhase) != 3 {
|
||||
return 0, 0, 0, fmt.Errorf("unexpected response: %v", measurements)
|
||||
|
|
@ -189,6 +189,6 @@ func (nrg *NRGKickConnect) Currents() (float64, float64, float64, error) {
|
|||
// NOTE: apparently shows energy of a stopped charging session, hence substituted by TotalEnergy
|
||||
// func (nrg *NRGKickConnect) ChargedEnergy() (float64, error) {
|
||||
// var measurements NRGMeasurements
|
||||
// err := nrg.getJSON(nrg.apiURL(apiMeasurements), measurements)
|
||||
// err := nrg.getJSON(nrg.apiURL(apiMeasurements), &measurements)
|
||||
// return measurements.ChargingEnergy, err
|
||||
// }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue