pductl

package module
v0.0.0-...-98ba4ae Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 15, 2024 License: Apache-2.0 Imports: 15 Imported by: 0

README

PDU Controller & Prometheus exporter

A little Go tool to control and monitor Baytech PDUs via the serial console port.

Newer generations feature Ethernet connectivity. This is mainly for older models which can be found for quite affordable prices on the second hand market.

Supported Models

Documentation

Please see pductl(3) and pdud(3).

Example Usage

bash setup_ca.sh

go run ./cmd/pdud \
    --tls-cacert certs/ca.crt \
    --tls-key certs/server.key \
    --tls-cert certs/server.crt
    --address serial:/dev/ttyUSB0 &

go run ./cmd/pductl \
    --tls-cacert certs/ca.crt \
    --tls-key certs/client1.key \
    --tls-cert certs/client1.crt \
    --address http://localhost:8080 \
    status
Forward Serial Port via TCP
socat -d tcp-listen:4142,reuseaddr,fork file:/dev/ttyUSB0,cs8,b9600,cstopb=0,raw,echo=0

Authors

License

This code is license under the Apache-2.0 licence.

  • SPDX-FileCopyrightText: 2024 Steffen Vogel post@steffenvogel.de
  • SPDX-License-Identifier: Apache-2.0

Documentation

Index

Constants

View Source
const (
	All = "all"
)

Variables

View Source
var (
	ErrNotFound        = errors.New("failed to find outlet")
	ErrInvalidOutletID = errors.New("invalid outlet ID")
	ErrLoginRequired   = errors.New("login required")
	ErrInvalidPassword = errors.New("invalid password")
)
View Source
var (
	ErrMissingClientCert = errors.New("missing client certificate")
	ErrAccessDenied      = errors.New("access denied")
)
View Source
var ErrNotPolledYet = errors.New("status has not been polled yet")

Functions

func CalcEnergy

func CalcEnergy(prevSts, newSts *Status)

func Handler

func Handler(mux *http.ServeMux, p PDU, cfg *Config) http.Handler

Types

type AccessControlEntry

type AccessControlEntry struct {
	Name       string   `mapstructure:"name"`
	Operations []string `mapstructure:"operations"`
	Outlets    []struct {
		ID         string   `mapstructure:"id"`
		Operations []string `mapstructure:"operations"`
		// contains filtered or unexported fields
	} `mapstructure:"outlets"`
	// contains filtered or unexported fields
}

type AccessControlList

type AccessControlList []AccessControlEntry

func (AccessControlList) Check

func (a AccessControlList) Check(commonName, operationID, outletID string) bool

func (AccessControlList) Init

func (a AccessControlList) Init() (err error)

type BreakerMetrics

type BreakerMetrics struct {
	TrueRMSCurrent prometheus.Gauge
	PeakRMSCurrent prometheus.Gauge
}

type BreakerStatus

type BreakerStatus = api.BreakerStatus

type Config

type Config struct {
	Listen       string        `mapstructure:"listen"`
	Address      string        `mapstructure:"address"`
	Username     string        `mapstructure:"username"`
	Password     string        `mapstructure:"password"`
	PollInterval time.Duration `mapstructure:"poll_interval"`
	Format       string        `mapstructure:"format"`
	Metrics      bool          `mapstructure:"metrics"`

	TLS struct {
		CACert   string `mapstructure:"cacert"`
		Cert     string `mapstructure:"cert"`
		Key      string `mapstructure:"key"`
		Insecure bool   `mapstructure:"insecure"`
	} `mapstructure:"tls"`

	ACL AccessControlList `mapstructure:"acl"`
}

func ParseConfig

func ParseConfig(flags *flag.FlagSet) (*Config, error)

type GroupMetrics

type GroupMetrics struct {
	TrueRMSCurrent prometheus.Gauge
	TrueRMSVoltage prometheus.Gauge
	PeakRMSCurrent prometheus.Gauge
	AveragePower   prometheus.Gauge
	Power          prometheus.Gauge
	Energy         prometheus.Counter
}

type GroupStatus

type GroupStatus = api.GroupStatus

type LoginPDU

type LoginPDU interface {
	PDU

	Login(username, password string) error
	Logout() error
	WithLogin(username, password string, cb func()) error
}

type Metrics

type Metrics struct {
	Timestamp   prometheus.Gauge
	Temperature prometheus.Gauge
	TotalEnergy prometheus.Counter

	Breakers []BreakerMetrics
	Groups   []GroupMetrics
	Outlets  []OutletMetrics
}

func NewMetrics

func NewMetrics(sts *Status) *Metrics

func (*Metrics) Update

func (m *Metrics) Update(prevSts, newSts *Status)

type OutletMetrics

type OutletMetrics struct {
	TrueRMSCurrent prometheus.Gauge
	TrueRMSVoltage prometheus.Gauge
	PeakRMSCurrent prometheus.Gauge
	AveragePower   prometheus.Gauge
	Power          prometheus.Gauge
	State          prometheus.Gauge
	Locked         prometheus.Gauge
	Energy         prometheus.Counter
}

type OutletStatus

type OutletStatus = api.OutletStatus

type PDU

type PDU interface {
	Close() error
	SwitchOutlet(id string, state bool) (err error)
	LockOutlet(id string, state bool) (err error)
	RebootOutlet(id string) error
	ClearMaximumCurrents() error
	Status(detailed bool) (*Status, error)
	Temperature() (float64, error)
	WhoAmI() (string, error)
}

type PolledPDU

type PolledPDU struct {
	PDU
	// contains filtered or unexported fields
}

func NewPolledPDU

func NewPolledPDU(p PDU, interval time.Duration, username, password string, onStatus func(*Status)) *PolledPDU

func (*PolledPDU) ClearMaximumCurrents

func (p *PolledPDU) ClearMaximumCurrents() error

func (*PolledPDU) Close

func (p *PolledPDU) Close() error

func (*PolledPDU) LockOutlet

func (p *PolledPDU) LockOutlet(id string, state bool) (err error)

func (*PolledPDU) RebootOutlet

func (p *PolledPDU) RebootOutlet(id string) error

func (*PolledPDU) Status

func (p *PolledPDU) Status(detailed bool) (*Status, error)

func (*PolledPDU) SwitchOutlet

func (p *PolledPDU) SwitchOutlet(id string, state bool) (err error)

func (*PolledPDU) Temperature

func (p *PolledPDU) Temperature() (float64, error)

type Server

type Server struct {
	PDU
}

func (*Server) ClearMaximumCurrents

Clear peak RMS current (POST /clear)

func (*Server) LockOutlet

Switch lock state of outlet (POST /outlet/{id}/lock)

func (*Server) RebootOutlet

Reboot the outlet (POST /outlet/{id}/reboot)

func (*Server) Status

Get status of PDU (GET /status)

func (*Server) SwitchOutlet

Switch state of outlet (POST /outlet/{id}/state)

func (*Server) Temperature

Get temperature of PDU (GET /temperature)

func (*Server) WhoAmI

Get current user (GET /whoami)

type Status

type Status = api.Status

Directories

Path Synopsis
cmd
internal
api
Package api provides primitives to interact with the openapi HTTP API.
Package api provides primitives to interact with the openapi HTTP API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL