mirror of
https://github.com/rwinkhart/uni-nut.git
synced 2026-09-06 08:57:12 -04:00
Add support for authentication and auto-ID-detection
This commit is contained in:
@@ -5,7 +5,7 @@ Ubiquiti UPS units seem to use a somewhat non-standard format for responses from
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
1. Enable the NUT server on your Ubiquiti UniFi-connected UPS unit.
|
1. Enable the NUT server on your Ubiquiti UniFi-connected UPS unit.
|
||||||
- Do **NOT** enable the "Login Credential" option!
|
- The "Login Credential" setting is optional; if enabled, be sure to use the .Authenticate() method immediately after dialing!
|
||||||
2. This module can now be used to get variables from your UPS's NUT server as follows:
|
2. This module can now be used to get variables from your UPS's NUT server as follows:
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
@@ -18,12 +18,29 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
host := "IP:PORT"
|
host := "IP:PORT"
|
||||||
upsID := "UPS-ID"
|
username := "username"
|
||||||
|
password := "password"
|
||||||
|
|
||||||
|
// connect to NUT server
|
||||||
client, err := nut.Dial(host)
|
client, err := nut.Dial(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
err = client.GetListVar(upsID)
|
|
||||||
|
// authenticate (if "Login Credential" is enabled on the NUT server)
|
||||||
|
err = client.Authenticate(username, password)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto-detect UPS ID
|
||||||
|
upsID, err := client.Identify()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// list all variables from your UPS
|
||||||
|
err = client.ListVar(upsID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@@ -32,3 +49,5 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This module also features a .GetVar() method for retrieving the value of only one variable.
|
||||||
|
|||||||
@@ -36,6 +36,36 @@ func (c *Client) Close() error {
|
|||||||
return c.conn.Close()
|
return c.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Authenticate logs into credential-protected sessions.
|
||||||
|
// If authentication is enabled on your NUT server, run
|
||||||
|
// this immediately after dialing.
|
||||||
|
func (c *Client) Authenticate(username, password string) error {
|
||||||
|
var err error
|
||||||
|
if err = c.write("USERNAME " + username + "\nPASSWORD " + password); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = c.clearBuffer("OK L", "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identify detects the ID of the connected UPS.
|
||||||
|
// This only works when there is only one UPS per
|
||||||
|
// NUT server, which is the case with UniFi UPS units.
|
||||||
|
func (c *Client) Identify() (string, error) {
|
||||||
|
if err := c.write("LIST UPS"); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
l, err := c.clearBuffer("END", "UPS")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Split(l, " ")[1], nil
|
||||||
|
}
|
||||||
|
|
||||||
// ListVar updates NutKeyValMap with the current status of all variables from <upsID>.
|
// ListVar updates NutKeyValMap with the current status of all variables from <upsID>.
|
||||||
func (c *Client) ListVar(upsID string) error {
|
func (c *Client) ListVar(upsID string) error {
|
||||||
cmd := "LIST VAR \"" + upsID + "\""
|
cmd := "LIST VAR \"" + upsID + "\""
|
||||||
@@ -70,8 +100,7 @@ outer:
|
|||||||
|
|
||||||
// GetVar returns the value of the specified variable for <upsID>.
|
// GetVar returns the value of the specified variable for <upsID>.
|
||||||
func (c *Client) GetVar(upsID, varName string) (string, error) {
|
func (c *Client) GetVar(upsID, varName string) (string, error) {
|
||||||
cmd := "GET VAR \"" + upsID + "\" \"" + varName + "\""
|
if err := c.write("GET VAR \"" + upsID + "\" \"" + varName + "\""); err != nil {
|
||||||
if err := c.write(cmd); err != nil {
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
l, err := c.read()
|
l, err := c.read()
|
||||||
@@ -86,7 +115,6 @@ func (c *Client) GetVar(upsID, varName string) (string, error) {
|
|||||||
return value, nil
|
return value, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// newClient wraps an existing net.Conn.
|
|
||||||
func newClient(conn net.Conn) *Client {
|
func newClient(conn net.Conn) *Client {
|
||||||
return &Client{conn, bufio.NewReader(conn)}
|
return &Client{conn, bufio.NewReader(conn)}
|
||||||
}
|
}
|
||||||
@@ -106,3 +134,19 @@ func (c *Client) read() (string, error) {
|
|||||||
}
|
}
|
||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Client) clearBuffer(tillPrefix, storePrefix string) (string, error) {
|
||||||
|
var stored string
|
||||||
|
for {
|
||||||
|
l, err := c.read()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if storePrefix != "" && strings.HasPrefix(l, storePrefix) {
|
||||||
|
stored = l
|
||||||
|
} else if strings.HasPrefix(l, tillPrefix) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stored, nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user