145 lines
3.0 KiB
Go
145 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"image/color"
|
|
"net"
|
|
"time"
|
|
|
|
"git.openpdu.org/OpenPDU/openpdu/config"
|
|
|
|
"git.openpdu.org/OpenPDU/openpdu/i2c"
|
|
"git.openpdu.org/OpenPDU/openpdu/outlet"
|
|
"git.openpdu.org/OpenPDU/openpdu/syslog"
|
|
"golang.org/x/image/font"
|
|
"golang.org/x/image/font/basicfont"
|
|
"golang.org/x/image/math/fixed"
|
|
"periph.io/x/devices/v3/ssd1306"
|
|
)
|
|
|
|
func init() {
|
|
syslog.Info("display setup")
|
|
config.SetDefault("Display.Type", "none")
|
|
config.SetDefault("Display.W", 128)
|
|
config.SetDefault("Display.H", 32)
|
|
config.SetDefault("Display.Rotated", false)
|
|
config.SetDefault("Display.SwapTopBottom", false)
|
|
config.SetDefault("Display.networkinterface", "eth0")
|
|
}
|
|
|
|
func displayLoop() {
|
|
for {
|
|
if config.GetString("Display.Type") != "ssd1306" {
|
|
time.Sleep(1 * time.Second)
|
|
continue
|
|
}
|
|
|
|
syslog.Info("ssd1306 display starting loop")
|
|
|
|
if i2c.I2Cbus == nil {
|
|
syslog.Warning("ssd1306 i2cbus not found")
|
|
time.Sleep(1 * time.Second)
|
|
continue
|
|
}
|
|
|
|
opts := ssd1306.Opts{
|
|
W: config.GetInt("Display.W"),
|
|
H: config.GetInt("Display.H"),
|
|
Rotated: config.GetBool("Display.Rotated"),
|
|
Sequential: true,
|
|
SwapTopBottom: config.GetBool("Display.SwapTopBottom"),
|
|
}
|
|
|
|
// Open a handle to a ssd1306 connected on the I²C bus:
|
|
dev, err := ssd1306.NewI2C(i2c.I2Cbus, &opts)
|
|
if err != nil {
|
|
syslog.Err(err.Error())
|
|
}
|
|
|
|
syslog.Info("ssd1306 display setup completed")
|
|
|
|
for {
|
|
err := disp(dev)
|
|
if err != nil {
|
|
syslog.Err(err.Error())
|
|
time.Sleep(1 * time.Second)
|
|
syslog.Warning("ssd1306 display disp error")
|
|
continue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func addLabel(img *image.RGBA, x, y int, label string) {
|
|
col := color.RGBA{200, 100, 0, 255}
|
|
point := fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)}
|
|
|
|
d := &font.Drawer{
|
|
Dst: img,
|
|
Src: image.NewUniform(col),
|
|
Face: basicfont.Face7x13,
|
|
Dot: point,
|
|
}
|
|
d.DrawString(label)
|
|
}
|
|
|
|
func getIPs() map[string]string {
|
|
out := map[string]string{}
|
|
ifaces, _ := net.Interfaces()
|
|
// handle err
|
|
for _, i := range ifaces {
|
|
if i.Name == "lo" {
|
|
continue
|
|
}
|
|
addrs, _ := i.Addrs()
|
|
// handle err
|
|
for _, addr := range addrs {
|
|
var ip net.IP
|
|
switch v := addr.(type) {
|
|
case *net.IPNet:
|
|
ip = v.IP
|
|
case *net.IPAddr:
|
|
ip = v.IP
|
|
}
|
|
// process IP address
|
|
if ip.To4() == nil {
|
|
continue
|
|
}
|
|
if len(out) < 1 {
|
|
out[i.Name] = ip.String()
|
|
}
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func dispOutletStatusString() string {
|
|
out := ""
|
|
for o := range outlet.Outlets {
|
|
if outlet.Outlets[o].Channel.Status() {
|
|
out += fmt.Sprint(outlet.Outlets[o].Num)
|
|
} else {
|
|
out += "."
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func disp(dev *ssd1306.Dev) error {
|
|
img := image.NewRGBA(image.Rect(0, 0, 128, 32))
|
|
iface := config.GetString("Display.NetworkInterface")
|
|
ips := getIPs()
|
|
ip, found := ips[iface]
|
|
if !found {
|
|
ip = "unknown"
|
|
}
|
|
lineHeight := 12
|
|
posX := 12
|
|
posY := lineHeight
|
|
addLabel(img, posX, posY, ip)
|
|
posY += lineHeight
|
|
addLabel(img, posX, posY, dispOutletStatusString())
|
|
return dev.Draw(img.Bounds(), img, image.Point{})
|
|
}
|