Easee: use SignalR for server-side updates (#1586)
This commit is contained in:
parent
13ddd6505e
commit
f53b215ce5
5 changed files with 448 additions and 71 deletions
250
charger/easee.go
250
charger/easee.go
|
|
@ -18,15 +18,21 @@ package charger
|
|||
// SOFTWARE.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/avast/retry-go/v3"
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/charger/easee"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/request"
|
||||
"github.com/evcc-io/evcc/util/sponsor"
|
||||
"github.com/philippseith/signalr"
|
||||
"github.com/thoas/go-funk"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
|
@ -34,14 +40,20 @@ import (
|
|||
// Easee charger implementation
|
||||
type Easee struct {
|
||||
*request.Helper
|
||||
charger string
|
||||
site, circuit int
|
||||
status easee.ChargerStatus
|
||||
updated time.Time
|
||||
cache time.Duration
|
||||
log *util.Logger
|
||||
phases int
|
||||
current float64
|
||||
charger string
|
||||
site, circuit int
|
||||
updated time.Time
|
||||
chargeStatus api.ChargeStatus
|
||||
cache time.Duration
|
||||
log *util.Logger
|
||||
mux sync.Mutex
|
||||
phases int
|
||||
chargerEnabled bool
|
||||
enabledStatus bool
|
||||
current, currentPower, sessionEnergy,
|
||||
circuitTotalPhaseConductorCurrentL1,
|
||||
circuitTotalPhaseConductorCurrentL2,
|
||||
circuitTotalPhaseConductorCurrentL3 float64
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
@ -55,10 +67,8 @@ func NewEaseeFromConfig(other map[string]interface{}) (api.Charger, error) {
|
|||
Password string
|
||||
Charger string
|
||||
Circuit int
|
||||
Cache time.Duration
|
||||
}{
|
||||
Cache: 10 * time.Second,
|
||||
}
|
||||
Cache time.Duration // deprecated
|
||||
}{}
|
||||
|
||||
if err := util.DecodeOther(other, &cc); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -84,6 +94,10 @@ func NewEasee(user, password, charger string, circuit int, cache time.Duration)
|
|||
phases: 3,
|
||||
}
|
||||
|
||||
if cache > 0 {
|
||||
c.log.WARN.Println("cache is deprecated and will be removed in a future release")
|
||||
}
|
||||
|
||||
ts, err := easee.TokenSource(log, user, password)
|
||||
if err != nil {
|
||||
return c, err
|
||||
|
|
@ -126,6 +140,11 @@ func NewEasee(user, password, charger string, circuit int, cache time.Duration)
|
|||
c.circuit = site.Circuits[0].ID
|
||||
}
|
||||
|
||||
err = c.subscribe(ts)
|
||||
if err != nil {
|
||||
return c, err
|
||||
}
|
||||
|
||||
// verify charger config
|
||||
config, err := c.chargerConfig(c.charger)
|
||||
if err == nil && config.PhaseMode != 2 {
|
||||
|
|
@ -135,6 +154,126 @@ func NewEasee(user, password, charger string, circuit int, cache time.Duration)
|
|||
return c, err
|
||||
}
|
||||
|
||||
// subscribe connects to the signalR hub
|
||||
func (c *Easee) subscribe(ts oauth2.TokenSource) error {
|
||||
conn, err := signalr.NewHTTPConnection(context.Background(), "https://api.easee.cloud/hubs/chargers",
|
||||
signalr.WithHTTPHeadersOption(func() (res http.Header) {
|
||||
if tok, err := ts.Token(); err == nil {
|
||||
res = http.Header{
|
||||
"Authorization": []string{fmt.Sprintf("Bearer %s", tok.AccessToken)},
|
||||
}
|
||||
}
|
||||
return res
|
||||
}),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
client, err := signalr.NewClient(context.Background(), conn,
|
||||
signalr.Receiver(c),
|
||||
// signalr.Logger(easee.SignalrLogger(c.log.TRACE), false),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := client.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// retry connection
|
||||
go func(closed <-chan struct{}) {
|
||||
<-closed
|
||||
_ = retry.Do(func() error {
|
||||
err := c.subscribe(ts)
|
||||
if err != nil {
|
||||
c.log.ERROR.Println("connect:", err)
|
||||
}
|
||||
return err
|
||||
}, retry.Attempts(256))
|
||||
}(client.Closed())
|
||||
|
||||
return <-client.Send("SubscribeWithCurrentState", c.charger, true)
|
||||
}
|
||||
|
||||
func (c *Easee) observe(typ string, i json.RawMessage) {
|
||||
var res easee.Observation
|
||||
if err := json.Unmarshal(i, &res); err == nil {
|
||||
var floatValue float64
|
||||
var boolValue bool
|
||||
var intValue int
|
||||
switch res.DataType {
|
||||
case easee.Boolean:
|
||||
boolValue = res.Value == "1"
|
||||
case easee.Double:
|
||||
floatValue, err = strconv.ParseFloat(res.Value, 64)
|
||||
if err != nil {
|
||||
c.log.ERROR.Printf("float conversion: %s", res.Value)
|
||||
return
|
||||
}
|
||||
case easee.Integer:
|
||||
intValue, err = strconv.Atoi(res.Value)
|
||||
if err != nil {
|
||||
c.log.ERROR.Printf("int conversion: %s", res.Value)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
switch res.ID {
|
||||
case easee.IS_ENABLED:
|
||||
c.chargerEnabled = boolValue
|
||||
case easee.TOTAL_POWER:
|
||||
c.currentPower = 1e3 * floatValue
|
||||
case easee.SESSION_ENERGY:
|
||||
c.sessionEnergy = floatValue
|
||||
case easee.CIRCUIT_TOTAL_PHASE_CONDUCTOR_CURRENT_L1:
|
||||
c.circuitTotalPhaseConductorCurrentL1 = floatValue
|
||||
case easee.CIRCUIT_TOTAL_PHASE_CONDUCTOR_CURRENT_L2:
|
||||
c.circuitTotalPhaseConductorCurrentL2 = floatValue
|
||||
case easee.CIRCUIT_TOTAL_PHASE_CONDUCTOR_CURRENT_L3:
|
||||
c.circuitTotalPhaseConductorCurrentL3 = floatValue
|
||||
case easee.CHARGER_OP_MODE:
|
||||
switch intValue {
|
||||
case easee.ModeDisconnected:
|
||||
c.chargeStatus = api.StatusA
|
||||
case easee.ModeAwaitingStart, easee.ModeCompleted, easee.ModeReadyToCharge:
|
||||
c.chargeStatus = api.StatusB
|
||||
case easee.ModeCharging:
|
||||
c.chargeStatus = api.StatusC
|
||||
case easee.ModeError:
|
||||
c.chargeStatus = api.StatusF
|
||||
default:
|
||||
c.log.ERROR.Printf("unknown opmode: %d", intValue)
|
||||
c.chargeStatus = api.StatusNone
|
||||
}
|
||||
c.enabledStatus = intValue == easee.ModeCharging || intValue == easee.ModeReadyToCharge
|
||||
}
|
||||
c.updated = time.Now()
|
||||
c.log.TRACE.Printf("%s: %+v", typ, res)
|
||||
} else {
|
||||
c.log.ERROR.Printf("invalid message: %s %s %v", i, typ, err)
|
||||
}
|
||||
}
|
||||
|
||||
// ProductUpdate implements the signalr receiver
|
||||
func (c *Easee) ProductUpdate(i json.RawMessage) {
|
||||
c.observe("ProductUpdate", i)
|
||||
}
|
||||
|
||||
// ChargerUpdate implements the signalr receiver
|
||||
func (c *Easee) ChargerUpdate(i json.RawMessage) {
|
||||
// c.observe("ChargerUpdate", i)
|
||||
}
|
||||
|
||||
// CommandResponse implements the signalr receiver
|
||||
func (c *Easee) CommandResponse(i json.RawMessage) {
|
||||
// c.observe("CommandResponse", i)
|
||||
}
|
||||
|
||||
func (c *Easee) chargers() (res []easee.Charger, err error) {
|
||||
uri := fmt.Sprintf("%s/chargers", easee.API)
|
||||
|
||||
|
|
@ -168,58 +307,29 @@ func (c *Easee) chargerDetails(charger string) (res easee.Site, err error) {
|
|||
return res, err
|
||||
}
|
||||
|
||||
func (c *Easee) state() (easee.ChargerStatus, error) {
|
||||
if time.Since(c.updated) < c.cache {
|
||||
return c.status, nil
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/chargers/%s/state", easee.API, c.charger)
|
||||
req, err := request.New(http.MethodGet, uri, nil, request.JSONEncoding)
|
||||
if err == nil {
|
||||
if err = c.DoJSON(req, &c.status); err == nil {
|
||||
c.updated = time.Now()
|
||||
}
|
||||
}
|
||||
|
||||
return c.status, err
|
||||
}
|
||||
|
||||
// Status implements the api.Charger interface
|
||||
func (c *Easee) Status() (api.ChargeStatus, error) {
|
||||
res, err := c.state()
|
||||
if err != nil {
|
||||
return api.StatusNone, err
|
||||
}
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
switch res.ChargerOpMode {
|
||||
case easee.ModeDisconnected:
|
||||
return api.StatusA, nil
|
||||
case easee.ModeAwaitingStart, easee.ModeCompleted, easee.ModeReadyToCharge:
|
||||
return api.StatusB, nil
|
||||
case easee.ModeCharging:
|
||||
return api.StatusC, nil
|
||||
case easee.ModeError:
|
||||
return api.StatusF, nil
|
||||
default:
|
||||
return api.StatusNone, fmt.Errorf("unknown opmode: %d", res.ChargerOpMode)
|
||||
}
|
||||
return c.chargeStatus, nil
|
||||
}
|
||||
|
||||
// Enabled implements the api.Charger interface
|
||||
func (c *Easee) Enabled() (bool, error) {
|
||||
res, err := c.state()
|
||||
return res.ChargerOpMode == easee.ModeCharging || res.ChargerOpMode == easee.ModeReadyToCharge, err
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
return c.enabledStatus, nil
|
||||
}
|
||||
|
||||
// Enable implements the api.Charger interface
|
||||
func (c *Easee) Enable(enable bool) error {
|
||||
res, err := c.state()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// enable charger once
|
||||
if enable && !res.IsOnline {
|
||||
// enable charger once if it's switched off
|
||||
c.mux.Lock()
|
||||
enablingRequired := enable && !c.chargerEnabled
|
||||
c.mux.Unlock()
|
||||
if enablingRequired {
|
||||
data := easee.ChargerSettings{
|
||||
Enabled: &enable,
|
||||
}
|
||||
|
|
@ -228,11 +338,8 @@ func (c *Easee) Enable(enable bool) error {
|
|||
resp, err := c.Post(uri, request.JSONContent, request.MarshalJSON(data))
|
||||
if err == nil {
|
||||
resp.Body.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
c.updated = time.Time{} // clear cache
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// resume/stop charger
|
||||
|
|
@ -242,8 +349,7 @@ func (c *Easee) Enable(enable bool) error {
|
|||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/chargers/%s/commands/%s", easee.API, c.charger, action)
|
||||
_, err = c.Post(uri, request.JSONContent, nil)
|
||||
c.updated = time.Time{} // clear cache
|
||||
_, err := c.Post(uri, request.JSONContent, nil)
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
@ -272,8 +378,6 @@ func (c *Easee) MaxCurrentMillis(current float64) error {
|
|||
resp, err := c.Post(uri, request.JSONContent, request.MarshalJSON(data))
|
||||
if err == nil {
|
||||
resp.Body.Close()
|
||||
|
||||
c.updated = time.Time{} // clear cache
|
||||
c.current = current
|
||||
}
|
||||
|
||||
|
|
@ -292,25 +396,31 @@ var _ api.Meter = (*Easee)(nil)
|
|||
|
||||
// CurrentPower implements the api.Meter interface
|
||||
func (c *Easee) CurrentPower() (float64, error) {
|
||||
res, err := c.state()
|
||||
return 1e3 * res.TotalPower, err
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
return c.currentPower, nil
|
||||
}
|
||||
|
||||
var _ api.ChargeRater = (*Easee)(nil)
|
||||
|
||||
// ChargedEnergy implements the api.ChargeRater interface
|
||||
func (c *Easee) ChargedEnergy() (float64, error) {
|
||||
res, err := c.state()
|
||||
return res.SessionEnergy, err
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
return c.sessionEnergy, nil
|
||||
}
|
||||
|
||||
var _ api.MeterCurrent = (*Easee)(nil)
|
||||
|
||||
// Currents implements the api.MeterCurrent interface
|
||||
func (c *Easee) Currents() (float64, float64, float64, error) {
|
||||
res, err := c.state()
|
||||
return res.CircuitTotalPhaseConductorCurrentL1,
|
||||
res.CircuitTotalPhaseConductorCurrentL2,
|
||||
res.CircuitTotalPhaseConductorCurrentL3,
|
||||
err
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
|
||||
return c.circuitTotalPhaseConductorCurrentL1,
|
||||
c.circuitTotalPhaseConductorCurrentL2,
|
||||
c.circuitTotalPhaseConductorCurrentL3,
|
||||
nil
|
||||
}
|
||||
|
|
|
|||
40
charger/easee/log.go
Normal file
40
charger/easee/log.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package easee
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/philippseith/signalr"
|
||||
)
|
||||
|
||||
// Logger is a simple logger interface
|
||||
type Logger interface {
|
||||
Println(v ...interface{})
|
||||
}
|
||||
|
||||
type logger struct {
|
||||
b strings.Builder
|
||||
log Logger
|
||||
}
|
||||
|
||||
func SignalrLogger(log Logger) signalr.StructuredLogger {
|
||||
return &logger{log: log}
|
||||
}
|
||||
|
||||
func (l *logger) Log(keyVals ...interface{}) error {
|
||||
for i, v := range keyVals {
|
||||
if i%2 == 0 {
|
||||
if l.b.Len() > 0 {
|
||||
l.b.WriteRune(' ')
|
||||
}
|
||||
l.b.WriteString(fmt.Sprintf("%v", v))
|
||||
l.b.WriteRune('=')
|
||||
} else {
|
||||
l.b.WriteString(fmt.Sprintf("%v", v))
|
||||
}
|
||||
}
|
||||
|
||||
l.log.Println(l.b.String())
|
||||
|
||||
return nil
|
||||
}
|
||||
192
charger/easee/signalr.go
Normal file
192
charger/easee/signalr.go
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
package easee
|
||||
|
||||
import "time"
|
||||
|
||||
type Observation struct {
|
||||
Mid string
|
||||
DataType DataType
|
||||
ID ObservationID
|
||||
Timestamp time.Time
|
||||
Value string
|
||||
}
|
||||
|
||||
type DataType int
|
||||
|
||||
// https://github.com/Masterloop/Masterloop.Core.Types/blob/master/src/Masterloop.Core.Types/Base/DataType.cs
|
||||
const (
|
||||
_ DataType = iota
|
||||
Binary // 1
|
||||
Boolean // 2
|
||||
Double // 3
|
||||
Integer // 4
|
||||
Position // 5
|
||||
String // 6
|
||||
Statistics // 7
|
||||
)
|
||||
|
||||
type ObservationID int
|
||||
|
||||
// https://www.notion.so/Charger-template-c6a20ff7cfea41e2b5f80b00afb34af5
|
||||
const (
|
||||
SELF_TEST_RESULT ObservationID = 1 // PASSED or error codes [String]
|
||||
SELF_TEST_DETAILS ObservationID = 2 // JSON with details from self-test [String]
|
||||
WIFI_EVENT ObservationID = 10 // Enum with WiFi event codes. Requires telemetry debug mode. Will be updated on WiFi events when using cellular, will otherwise be reported in ChargerOfflineReason [Integer]
|
||||
CHARGER_OFFLINE_REASON ObservationID = 11 // Enum describing why charger is offline [Integer]
|
||||
EASEE_LINK_COMMAND_RESPONSE ObservationID = 13 // Response on a EaseeLink command sent to another devic [Integer]
|
||||
EASEE_LINK_DATA_RECEIVED ObservationID = 14 // Data received on EaseeLink from another device [String]
|
||||
LOCAL_PRE_AUTHORIZE_ENABLED ObservationID = 15 // Preauthorize with whitelist enabled. Readback on setting [event] [Boolean]
|
||||
LOCAL_AUTHORIZE_OFFLINE_ENABLED ObservationID = 16 // Allow offline charging for whitelisted RFID token. Readback on setting [event] [Boolean]
|
||||
ALLOW_OFFLINE_TX_FOR_UNKNOWN_ID ObservationID = 17 // Allow offline charging for all RFID tokens. Readback on setting [event] [Boolean]
|
||||
ERRATIC_EVMAX_TOGGLES ObservationID = 18 // 0 == erratic checking disabled, otherwise the number of toggles between states Charging and Charging Complate that will trigger an error [Integer]
|
||||
BACKPLATE_TYPE ObservationID = 19 // Readback on backplate type [Integer]
|
||||
SITE_STRUCTURE ObservationID = 20 // Site Structure [boot] [String]
|
||||
DETECTED_POWER_GRID_TYPE ObservationID = 21 // Detected power grid type according to PowerGridType table [boot] [Integer]
|
||||
CIRCUIT_MAX_CURRENT_P1 ObservationID = 22 // Set circuit maximum current [Amperes] [Double]
|
||||
CIRCUIT_MAX_CURRENT_P2 ObservationID = 23 // Set circuit maximum current [Amperes] [Double]
|
||||
CIRCUIT_MAX_CURRENT_P3 ObservationID = 24 // Set circuit maximum current [Amperes] [Double]
|
||||
LOCATION ObservationID = 25 // Location coordinate [event] [Position]
|
||||
SITE_IDSTRING ObservationID = 26 // Site ID string [event] [String]
|
||||
SITE_IDNUMERIC ObservationID = 27 // Site ID numeric value [event] [Integer]
|
||||
LOCK_CABLE_PERMANENTLY ObservationID = 30 // Lock type2 cable permanently [Boolean]
|
||||
IS_ENABLED ObservationID = 31 // Set true to enable charger, false disables charger [Boolean]
|
||||
CIRCUIT_SEQUENCE_NUMBER ObservationID = 33 // Charger sequence number on circuit [Integer]
|
||||
SINGLE_PHASE_NUMBER ObservationID = 34 // Phase to use in 1-phase charging [Integer]
|
||||
ENABLE3_PHASES_DEPRECATED ObservationID = 35 // Allow charging using 3-phases [Boolean]
|
||||
WI_FI_SSID ObservationID = 36 // WiFi SSID name [String]
|
||||
ENABLE_IDLE_CURRENT ObservationID = 37 // Charger signals available current when EV is done charging [user option] [event] [Boolean]
|
||||
PHASE_MODE ObservationID = 38 // Phase mode on this charger. 1-Locked to 1-Phase, 2-Auto, 3-Locked to 3-phase(only Home) [Integer]
|
||||
FORCED_THREE_PHASE_ON_ITWITH_GND_FAULT ObservationID = 39 // Default disabled. Must be set manually if grid type is indeed three phase IT [Boolean]
|
||||
LED_STRIP_BRIGHTNESS ObservationID = 40 // LED strip brightness, 0-100% [Integer]
|
||||
LOCAL_AUTHORIZATION_REQUIRED ObservationID = 41 // Local RFID authorization is required for charging [user options] [event] [Boolean]
|
||||
AUTHORIZATION_REQUIRED ObservationID = 42 // Authorization is requried for charging [Boolean]
|
||||
REMOTE_START_REQUIRED ObservationID = 43 // Remote start required flag [event] [Boolean]
|
||||
SMART_BUTTON_ENABLED ObservationID = 44 // Smart button is enabled [Boolean]
|
||||
OFFLINE_CHARGING_MODE ObservationID = 45 // Charger behavior when offline [Integer]
|
||||
LEDMODE ObservationID = 46 // Charger LED mode [event] [Integer]
|
||||
MAX_CHARGER_CURRENT ObservationID = 47 // Max current this charger is allowed to offer to car (A). Non volatile. [Double]
|
||||
DYNAMIC_CHARGER_CURRENT ObservationID = 48 // Max current this charger is allowed to offer to car (A). Volatile [Double]
|
||||
MAX_CURRENT_OFFLINE_FALLBACK_P1 ObservationID = 50 // Maximum circuit current P1 when offline [event] [Integer]
|
||||
MAX_CURRENT_OFFLINE_FALLBACK_P2 ObservationID = 51 // Maximum circuit current P2 when offline [event] [Integer]
|
||||
MAX_CURRENT_OFFLINE_FALLBACK_P3 ObservationID = 52 // Maximum circuit current P3 when offline [event] [Integer]
|
||||
CHARGING_SCHEDULE ObservationID = 62 // Charging schedule [json] [String]
|
||||
PAIRED_EQUALIZER ObservationID = 65 // Paired equalizer details [String]
|
||||
WI_FI_APENABLED ObservationID = 68 // True if WiFi Access Point is enabled, otherwise false [Boolean]
|
||||
PAIRED_USER_IDTOKEN ObservationID = 69 // Observed user token when charger put in RFID pairing mode [event] [String]
|
||||
CIRCUIT_TOTAL_ALLOCATED_PHASE_CONDUCTOR_CURRENT_L1 ObservationID = 70 // Total current allocated to L1 by all chargers on the circuit. Sent in by master only [Double]
|
||||
CIRCUIT_TOTAL_ALLOCATED_PHASE_CONDUCTOR_CURRENT_L2 ObservationID = 71 // Total current allocated to L2 by all chargers on the circuit. Sent in by master only [Double]
|
||||
CIRCUIT_TOTAL_ALLOCATED_PHASE_CONDUCTOR_CURRENT_L3 ObservationID = 72 // Total current allocated to L3 by all chargers on the circuit. Sent in by master only [Double]
|
||||
CIRCUIT_TOTAL_PHASE_CONDUCTOR_CURRENT_L1 ObservationID = 73 // Total current in L1 (sum of all chargers on the circuit) Sent in by master only [Double]
|
||||
CIRCUIT_TOTAL_PHASE_CONDUCTOR_CURRENT_L2 ObservationID = 74 // Total current in L2 (sum of all chargers on the circuit) Sent in by master only [Double]
|
||||
CIRCUIT_TOTAL_PHASE_CONDUCTOR_CURRENT_L3 ObservationID = 75 // Total current in L3 (sum of all chargers on the circuit) Sent in by master only [Double]
|
||||
NUMBER_OF_CARS_CONNECTED ObservationID = 76 // Number of cars connected to this circuit [Integer]
|
||||
NUMBER_OF_CARS_CHARGING ObservationID = 77 // Number of cars currently charging [Integer]
|
||||
NUMBER_OF_CARS_IN_QUEUE ObservationID = 78 // Number of cars currently in queue, waiting to be allocated power [Integer]
|
||||
NUMBER_OF_CARS_FULLY_CHARGED ObservationID = 79 // Number of cars that appear to be fully charged [Integer]
|
||||
SOFTWARE_RELEASE ObservationID = 80 // Embedded software package release id [boot] [Integer]
|
||||
ICCID ObservationID = 81 // SIM integrated circuit card identifier [String]
|
||||
MODEM_FW_ID ObservationID = 82 // Modem firmware version [String]
|
||||
OTAERROR_CODE ObservationID = 83 // OTA error code, see table [event] [Integer]
|
||||
MOBILE_NETWORK_OPERATOR ObservationID = 84 // Current mobile network operator [pollable] [String]
|
||||
REBOOT_REASON ObservationID = 89 // Reason of reboot. Bitmask of flags. [Integer]
|
||||
POWER_PCBVERSION ObservationID = 90 // Power PCB hardware version [Integer]
|
||||
COM_PCBVERSION ObservationID = 91 // Communication PCB hardware version [Integer]
|
||||
REASON_FOR_NO_CURRENT ObservationID = 96 // Enum describing why a charger with a car connected is not offering current to the car [Integer]
|
||||
LOAD_BALANCING_NUMBER_OF_CONNECTED_CHARGERS ObservationID = 97 // Number of connected chargers in the load balancin. Including the master. Sent from Master only. [Integer]
|
||||
UDPNUM_OF_CONNECTED_NODES ObservationID = 98 // Number of chargers connected to master through UDP / WIFI [Integer]
|
||||
LOCAL_CONNECTION ObservationID = 99 // Slaves only. Current connection to master, 0 = None, 1= Radio, 2 = WIFI UDP, 3 = Radio and WIFI UDP [Integer]
|
||||
PILOT_MODE ObservationID = 100 // Pilot Mode Letter (A-F) [event] [String]
|
||||
CAR_CONNECTED_DEPRECATED ObservationID = 101 // Car connection state [Boolean]
|
||||
SMART_CHARGING ObservationID = 102 // Smart charging state enabled by capacitive touch button [event] [Boolean]
|
||||
CABLE_LOCKED ObservationID = 103 // Cable lock state [event] [Boolean]
|
||||
CABLE_RATING ObservationID = 104 // Cable rating read [Amperes] [event] [Double]
|
||||
PILOT_HIGH ObservationID = 105 // Pilot signal high [Volt] [debug] [Double]
|
||||
PILOT_LOW ObservationID = 106 // Pilot signal low [Volt] [debug] [Double]
|
||||
BACK_PLATE_ID ObservationID = 107 // Back Plate RFID of charger [boot] [String]
|
||||
USER_IDTOKEN_REVERSED ObservationID = 108 // User ID token string from RFID reading [event] (NB! Must reverse these strings) [String]
|
||||
CHARGER_OP_MODE ObservationID = 109 // Charger operation mode according to charger mode table [event] [Integer]
|
||||
OUTPUT_PHASE ObservationID = 110 // Active output phase(s) to EV according to output phase type table. [event] [Integer]
|
||||
DYNAMIC_CIRCUIT_CURRENT_P1 ObservationID = 111 // Dynamically set circuit maximum current for phase 1 [Amperes] [event] [Double]
|
||||
DYNAMIC_CIRCUIT_CURRENT_P2 ObservationID = 112 // Dynamically set circuit maximum current for phase 2 [Amperes] [event] [Double]
|
||||
DYNAMIC_CIRCUIT_CURRENT_P3 ObservationID = 113 // Dynamically set circuit maximum current for phase 3 [Amperes] [event] [Double]
|
||||
OUTPUT_CURRENT ObservationID = 114 // Available current signaled to car with pilot tone [Double]
|
||||
DERATED_CURRENT ObservationID = 115 // Available current after derating [A] [Double]
|
||||
DERATING_ACTIVE ObservationID = 116 // Available current is limited by the charger due to high temperature [event] [Boolean]
|
||||
DEBUG_STRING ObservationID = 117 // Debug string [String]
|
||||
ERROR_STRING ObservationID = 118 // Descriptive error string [event] [String]
|
||||
ERROR_CODE ObservationID = 119 // Error code according to error code table [event] [Integer]
|
||||
TOTAL_POWER ObservationID = 120 // Total power [kW] [telemetry] [Double]
|
||||
SESSION_ENERGY ObservationID = 121 // Session accumulated energy [kWh] [telemetry] [Double]
|
||||
ENERGY_PER_HOUR ObservationID = 122 // Accumulated energy per hour [kWh] [event] [Double]
|
||||
LEGACY_EV_STATUS ObservationID = 123 // 0 = not legacy ev, 1 = legacy ev detected, 2 = reviving ev [Integer]
|
||||
LIFETIME_ENERGY ObservationID = 124 // Accumulated energy in the lifetime of the charger [kWh] [Double]
|
||||
LIFETIME_RELAY_SWITCHES ObservationID = 125 // Total number of relay switches in the lifetime of the charger (irrespective of the number of phases used) [Integer]
|
||||
LIFETIME_HOURS ObservationID = 126 // Total number of hours in operation [Integer]
|
||||
DYNAMIC_CURRENT_OFFLINE_FALLBACK_DEPRICATED ObservationID = 127 // Maximum circuit current when offline [event] [Integer]
|
||||
USER_IDTOKEN ObservationID = 128 // User ID token string from RFID reading [event] [String]
|
||||
CHARGING_SESSION ObservationID = 129 // Charging sessions [json] [event] [String]
|
||||
CELL_RSSI ObservationID = 130 // Cellular signal strength [dBm] [telemetry] [Integer]
|
||||
CELL_RAT ObservationID = 131 // Cellular radio access technology according to RAT table [event] [Integer]
|
||||
WI_FI_RSSI ObservationID = 132 // WiFi signal strength [dBm] [telemetry] [Integer]
|
||||
CELL_ADDRESS ObservationID = 133 // IP address assigned by cellular network [debug] [String]
|
||||
WI_FI_ADDRESS ObservationID = 134 // IP address assigned by WiFi network [debug] [String]
|
||||
WI_FI_TYPE ObservationID = 135 // WiFi network type letters (G, N, AC, etc) [debug] [String]
|
||||
LOCAL_RSSI ObservationID = 136 // Local radio signal strength [dBm] [telemetry] [Integer]
|
||||
MASTER_BACK_PLATE_ID ObservationID = 137 // Back Plate RFID of master [event] [String]
|
||||
LOCAL_TX_POWER ObservationID = 138 // Local radio transmission power [dBm] [telemetry] [Integer]
|
||||
LOCAL_STATE ObservationID = 139 // Local radio state [event] [String]
|
||||
FOUND_WI_FI ObservationID = 140 // List of found WiFi SSID and RSSI values [event] [String]
|
||||
CHARGER_RAT ObservationID = 141 // Radio access technology in use: 0 = cellular, 1 = wifi [Integer]
|
||||
CELLULAR_INTERFACE_ERROR_COUNT ObservationID = 142 // The number of times since boot the system has reported an error on this interface [poll] [Integer]
|
||||
CELLULAR_INTERFACE_RESET_COUNT ObservationID = 143 // The number of times since boot the interface was reset due to high error count [poll] [Integer]
|
||||
WIFI_INTERFACE_ERROR_COUNT ObservationID = 144 // The number of times since boot the system has reported an error on this interface [poll] [Integer]
|
||||
WIFI_INTERFACE_RESET_COUNT ObservationID = 145 // The number of times since boot the interface was reset due to high error count [poll] [Integer]
|
||||
LOCAL_NODE_TYPE ObservationID = 146 // 0-Unconfigured, 1-Master, 2-Extender, 3-End device [Integer]
|
||||
LOCAL_RADIO_CHANNEL ObservationID = 147 // Channel nr 0 - 11 [Integer]
|
||||
LOCAL_SHORT_ADDRESS ObservationID = 148 // Address of charger on local radio network [Integer]
|
||||
LOCAL_PARENT_ADDR_OR_NUM_OF_NODES ObservationID = 149 // If master-Number of slaves connected, If slave- Address parent [Integer]
|
||||
TEMP_MAX ObservationID = 150 // Maximum temperature for all sensors [Celsius] [telemetry] [Double]
|
||||
TEMP_AMBIENT_POWER_BOARD ObservationID = 151 // Temperature measured by ambient sensor on power board [Celsius] [event] [Double]
|
||||
TEMP_INPUT_T2 ObservationID = 152 // Temperature at input T2 [Celsius] [event] [Double]
|
||||
TEMP_INPUT_T3 ObservationID = 153 // Temperature at input T3 [Celsius] [event] [Double]
|
||||
TEMP_INPUT_T4 ObservationID = 154 // Temperature at input T4 [Celsius] [event] [Double]
|
||||
TEMP_INPUT_T5 ObservationID = 155 // Temperature at input T5 [Celsius] [event] [Double]
|
||||
TEMP_OUTPUT_N ObservationID = 160 // Temperature at type 2 connector plug for N [Celsius] [event] [Double]
|
||||
TEMP_OUTPUT_L1 ObservationID = 161 // Temperature at type 2 connector plug for L1 [Celsius] [event] [Double]
|
||||
TEMP_OUTPUT_L2 ObservationID = 162 // Temperature at type 2 connector plug for L2 [Celsius] [event] [Double]
|
||||
TEMP_OUTPUT_L3 ObservationID = 163 // Temperature at type 2 connector plug for L3 [Celsius] [event] [Double]
|
||||
TEMP_AMBIENT ObservationID = 170 // Ambient temperature [Celsius] [event] [Double]
|
||||
LIGHT_AMBIENT ObservationID = 171 // Ambient light from front side [Percent] [debug] [Integer]
|
||||
INT_REL_HUMIDITY ObservationID = 172 // Internal relative humidity [Percent] [event] [Integer]
|
||||
BACK_PLATE_LOCKED ObservationID = 173 // Back plate confirmed locked [event] [Boolean]
|
||||
CURRENT_MOTOR ObservationID = 174 // Motor current draw [debug] [Double]
|
||||
BACK_PLATE_HALL_SENSOR ObservationID = 175 // Raw sensor value [mV] [Integer]
|
||||
IN_CURRENT_T2 ObservationID = 182 // Calculated current RMS for input T2 [Amperes] [telemetry] [Double]
|
||||
IN_CURRENT_T3 ObservationID = 183 // Current RMS for input T3 [Amperes] [telemetry] [Double]
|
||||
IN_CURRENT_T4 ObservationID = 184 // Current RMS for input T4 [Amperes] [telemetry] [Double]
|
||||
IN_CURRENT_T5 ObservationID = 185 // Current RMS for input T5 [Amperes] [telemetry] [Double]
|
||||
IN_VOLT_T1_T2 ObservationID = 190 // Input voltage RMS between T1 and T2 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T1_T3 ObservationID = 191 // Input voltage RMS between T1 and T3 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T1_T4 ObservationID = 192 // Input voltage RMS between T1 and T4 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T1_T5 ObservationID = 193 // Input voltage RMS between T1 and T5 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T2_T3 ObservationID = 194 // Input voltage RMS between T2 and T3 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T2_T4 ObservationID = 195 // Input voltage RMS between T2 and T4 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T2_T5 ObservationID = 196 // Input voltage RMS between T2 and T5 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T3_T4 ObservationID = 197 // Input voltage RMS between T3 and T4 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T3_T5 ObservationID = 198 // Input voltage RMS between T3 and T5 [Volt] [telemetry] [Double]
|
||||
IN_VOLT_T4_T5 ObservationID = 199 // Input voltage RMS between T4 and T5 [Volt] [telemetry] [Double]
|
||||
OUT_VOLT_PIN1_2 ObservationID = 202 // Output voltage RMS between type 2 pin 1 and 2 [Volt] [telemetry] [Double]
|
||||
OUT_VOLT_PIN1_3 ObservationID = 203 // Output voltage RMS between type 2 pin 1 and 3 [Volt] [telemetry] [Double]
|
||||
OUT_VOLT_PIN1_4 ObservationID = 204 // Output voltage RMS between type 2 pin 1 and 4 [Volt] [telemetry] [Double]
|
||||
OUT_VOLT_PIN1_5 ObservationID = 205 // Output voltage RMS between type 2 pin 1 and 5 [Volt] [telemetry] [Double]
|
||||
VOLT_LEVEL33 ObservationID = 210 // 3.3 Volt Level [Volt] [telemetry] [Double]
|
||||
VOLT_LEVEL5 ObservationID = 211 // 5 Volt Level [Volt] [telemetry] [Double]
|
||||
VOLT_LEVEL12 ObservationID = 212 // 12 Volt Level [Volt] [telemetry] [Double]
|
||||
LTE_RSRP ObservationID = 220 // Reference Signal Received Power (LTE) [-144 .. -44 dBm] [Integer]
|
||||
LTE_SINR ObservationID = 221 // Signal to Interference plus Noise Ratio (LTE) [-20 .. +30 dB] [Integer]
|
||||
LTE_RSRQ ObservationID = 222 // Reference Signal Received Quality (LTE) [-19 .. -3 dB] [Integer]
|
||||
EQ_AVAILABLE_CURRENT_P1 ObservationID = 230 // Available current for charging on P1 according to Equalizer [Double]
|
||||
EQ_AVAILABLE_CURRENT_P2 ObservationID = 231 // Available current for charging on P2 according to Equalizer [Double]
|
||||
EQ_AVAILABLE_CURRENT_P3 ObservationID = 232 // Available current for charging on P3 according to Equalizer [Double]
|
||||
LISTEN_TO_CONTROL_PULSE ObservationID = 56 // True = charger needs control pulse to consider itself online. Readback on charger setting [event] [Boolean]
|
||||
CONTROL_PULSE_RTT ObservationID = 57 // Control pulse round-trip time in milliseconds [Integer]
|
||||
)
|
||||
1
go.mod
1
go.mod
|
|
@ -57,6 +57,7 @@ require (
|
|||
github.com/nirasan/go-oauth-pkce-code-verifier v0.0.0-20170819232839-0fbfe93532da
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/onsi/ginkgo v1.16.4 // indirect
|
||||
github.com/philippseith/signalr v0.3.1-0.20210919120731-d0f92ed220f8
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
github.com/prometheus/common v0.29.0 // indirect
|
||||
github.com/prometheus/procfs v0.7.1 // indirect
|
||||
|
|
|
|||
36
go.sum
36
go.sum
|
|
@ -121,6 +121,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
|
|||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
|
||||
github.com/dave/jennifer v1.4.1 h1:XyqG6cn5RQsTj3qlWQTKlRGAyrTcsk1kUmWdZBzRjDw=
|
||||
github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
|
|
@ -170,7 +172,9 @@ github.com/getkin/kin-openapi v0.2.0/go.mod h1:V1z9xl9oF5Wt7v32ne4FmiF1alpS4dM6m
|
|||
github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs=
|
||||
|
|
@ -182,9 +186,13 @@ github.com/go-interpreter/wagon v0.6.0/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5
|
|||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-kit/log v0.2.0 h1:7i2K3eKTos3Vc0enKCfnVcgHh2olr/MyfboYq7cAcFw=
|
||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
|
||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-ping/ping v0.0.0-20210506233800-ff8be3320020 h1:mdi6AbCEoKCA1xKCmp7UtRB5fvGFlP92PvlhxgdvXEw=
|
||||
|
|
@ -196,6 +204,7 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM
|
|||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
|
|
@ -205,8 +214,11 @@ github.com/goburrow/modbus v0.1.0 h1:DejRZY73nEM6+bt5JSP6IsFolJ9dVcqxsYbpLbeW/ro
|
|||
github.com/goburrow/modbus v0.1.0/go.mod h1:Kx552D5rLIS8E7TyUwQ/UdHEqvX5T8tyiGBTlzMcZBg=
|
||||
github.com/goburrow/serial v0.1.0 h1:v2T1SQa/dlUqQiYIT8+Cu7YolfqAi3K96UmhwYyuSrA=
|
||||
github.com/goburrow/serial v0.1.0/go.mod h1:sAiqG0nRVswsm1C97xsttiYCzSLBmUZ/VSlVLZJ8haA=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0=
|
||||
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
|
||||
github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8=
|
||||
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
|
||||
github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo=
|
||||
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
|
||||
|
|
@ -381,6 +393,7 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX
|
|||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
|
|
@ -397,6 +410,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
|
|||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.7 h1:0hzRabrMN4tSTvMfnL3SCv1ZGeAP23ynzodBgaHeMeg=
|
||||
github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/knq/sysutil v0.0.0-20181215143952-f05b59f0f307/go.mod h1:BjPj+aVjl9FW/cCGiF3nGh5v+9Gd3VCgBQbod/GlMaQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
|
|
@ -478,8 +492,10 @@ github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx
|
|||
github.com/mlnoga/rct v0.0.0-20210927211248-455af36ba3ad h1:Day8m/hpA40ofm/cYfJU9ac8onwWDtm+XlaWSFBm9WM=
|
||||
github.com/mlnoga/rct v0.0.0-20210927211248-455af36ba3ad/go.mod h1:vHVb62/NOw0QkfTMCNxRSxMqvm4+4WQ8HkZQ4Z540GE=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/muka/go-bluetooth v0.0.0-20210508070623-03c23c62f181 h1:2WJZHTfZO2VOzRuVeEXI8Vjy+UAIvugGa+bVhni576I=
|
||||
github.com/muka/go-bluetooth v0.0.0-20210508070623-03c23c62f181/go.mod h1:dMCjicU6vRBk34dqOmIZm0aod6gUwZXOXzBROqGous0=
|
||||
|
|
@ -506,8 +522,9 @@ github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
|
|||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.11.0 h1:+CqWgvj0OZycCaqclBD1pxKHAU+tOkHmQIWvDHq2aug=
|
||||
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/name v0.0.0-20180628100202-0fd16699aae1/go.mod h1:eD5JxqMiuNYyFNmyY9rkJ/slN8y59oEu4Ei7F8OoKWQ=
|
||||
github.com/pascaldekloe/name v1.0.0/go.mod h1:Z//MfYJnH4jVpQ9wkclwu2I2MkHmXTlT9wR5UZScttM=
|
||||
|
|
@ -518,6 +535,8 @@ github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAv
|
|||
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
|
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/peterbourgon/ff v1.2.0/go.mod h1:ljiF7yxtUvZaxUDyUqQa0+uiEOgwVboj+Q2S2+0nq40=
|
||||
github.com/philippseith/signalr v0.3.1-0.20210919120731-d0f92ed220f8 h1:38Dvig3QBzavrVZMwRk6fvY11+XR741dSISgDf78X9w=
|
||||
github.com/philippseith/signalr v0.3.1-0.20210919120731-d0f92ed220f8/go.mod h1:qRINY6ciWK+sZXvVrtYup5u0nPXClEFzGnD4SvfwYxI=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
|
@ -619,6 +638,8 @@ github.com/suapapa/go_eddystone v1.3.1/go.mod h1:bXC11TfJOS+3g3q/Uzd7FKd5g62STQE
|
|||
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tcnksm/go-latest v0.0.0-20170313132115-e3007ae9052e/go.mod h1:d7u6HkTYKSv5m6MCKkOQlHwaShTMl3HjqSGW3XtVhXM=
|
||||
github.com/teivah/onecontext v1.3.0 h1:tbikMhAlo6VhAuEGCvhc8HlTnpX4xTNPTOseWuhO1J0=
|
||||
github.com/teivah/onecontext v1.3.0/go.mod h1:hoW1nmdPVK/0jrvGtcx8sCKYs2PiS4z0zzfdeuEVyb0=
|
||||
github.com/thoas/go-funk v0.9.0 h1:Yzu8aTjTb1sqHZzSZLBt4qaZrFfjNizhA7IfnefjEzo=
|
||||
github.com/thoas/go-funk v0.9.0/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
|
|
@ -626,12 +647,18 @@ github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDH
|
|||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
|
||||
github.com/twitchyliquid64/golang-asm v0.0.0-20190126203739-365674df15fc/go.mod h1:NoCfSFWosfqMqmmD7hApkirIK9ozpHjxRnRxs1l413A=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc=
|
||||
github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
|
||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
|
||||
github.com/volkszaehler/mbmd v0.0.0-20210808132733-8235dc7d1327 h1:GhXik8mWOCLDq7sCJjHjSv49fYUvhxOMMhrGYqAFowI=
|
||||
github.com/volkszaehler/mbmd v0.0.0-20210808132733-8235dc7d1327/go.mod h1:oh17P6CJFJvVlFfLSgbOh+GdgmtuHpxik7gk7Zr/kxg=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
|
|
@ -658,6 +685,8 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
|||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
|
|
@ -701,6 +730,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu
|
|||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
|
|
@ -757,6 +787,7 @@ golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81R
|
|||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
|
|
@ -904,6 +935,7 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
|
@ -1112,6 +1144,8 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
|||
mvdan.cc/sh v2.6.4+incompatible/go.mod h1:IeeQbZq+x2SUGBensq/jge5lLQbS3XT2ktyp3wrt4x8=
|
||||
nhooyr.io/websocket v1.6.5/go.mod h1:F259lAzPRAH0htX2y3ehpJe09ih1aSHN7udWki1defY=
|
||||
nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||
nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g=
|
||||
nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue