Methods for reading and writing single holding registers. Unfortunately the writes don't seem to have much effect, the registers are reset after a short period or instantly. Maybe due to something with the library, but no errors are produced. Closes gh-5

This commit is contained in:
Jarno Rankinen 2023-03-02 14:24:05 +02:00
parent bcb8d55126
commit ce1c569564
2 changed files with 80 additions and 7 deletions

View File

@ -19,7 +19,7 @@ import (
var static embed.FS
var (
version = "0.0.7"
version = "0.0.8"
pingvin pingvinKL.PingvinKL
DEBUG = false
)
@ -58,12 +58,36 @@ func coils(w http.ResponseWriter, r *http.Request) {
func registers(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
if DEBUG {
log.Println("Received request for /registers")
}
pathparams := strings.Split(strings.TrimPrefix(r.URL.Path, "/api/v1/registers/"), "/")
if len(pathparams[0]) == 0 {
json.NewEncoder(w).Encode(pingvin.Registers)
if DEBUG {
log.Println("Handled request for /registers")
} else if len(pathparams[0]) > 0 && r.Method == "GET" && len(pathparams) < 2 { // && r.Method == "POST"
intaddr, err := strconv.Atoi(pathparams[0])
if err != nil {
log.Println("ERROR: Could not parse register address", pathparams[0])
log.Println(err)
return
}
pingvin.ReadRegister(uint16(intaddr))
json.NewEncoder(w).Encode(pingvin.Registers[intaddr])
} else if len(pathparams[0]) > 0 && r.Method == "POST" && len(pathparams) == 2 {
intaddr, err := strconv.Atoi(pathparams[0])
if err != nil {
log.Println("ERROR: Could not parse register address", pathparams[0])
log.Println(err)
return
}
intval, err := strconv.Atoi(pathparams[1])
if err != nil {
log.Println("ERROR: Could not parse register value", pathparams[1])
log.Println(err)
return
}
_, err = pingvin.WriteRegister(uint16(intaddr), uint16(intval))
if err != nil {
log.Println(err)
}
json.NewEncoder(w).Encode(pingvin.Registers[intaddr])
}
}

View File

@ -180,6 +180,55 @@ func (p *PingvinKL) updateCoils() {
}
}
func (p *PingvinKL) ReadRegister(addr uint16) (int, error) {
handler := p.getHandler()
p.buslock.Lock()
defer p.buslock.Unlock()
err := handler.Connect()
if err != nil {
log.Println("ERROR: ReadRegister:", err)
return 0, err
}
defer handler.Close()
client := modbus.NewClient(handler)
results, err := client.ReadHoldingRegisters(addr, 1)
if err != nil {
log.Println("ERROR: ReadRegister:", err)
return 0, err
}
if p.Registers[addr].Type == "uint16" {
p.Registers[addr].Value = int(uint16(results[0]) << 8)
p.Registers[addr].Value += int(uint16(results[1]))
} else if p.Registers[addr].Type == "int16" {
p.Registers[addr].Value = int(int16(results[0]) << 8)
p.Registers[addr].Value += int(int16(results[1]))
}
return p.Registers[addr].Value, nil
}
func (p *PingvinKL) WriteRegister(addr uint16, value uint16) (uint16, error) {
handler := p.getHandler()
p.buslock.Lock()
defer p.buslock.Unlock()
err := handler.Connect()
if err != nil {
log.Println("ERROR: WriteRegister:", err)
return 0, err
}
defer handler.Close()
client := modbus.NewClient(handler)
_, err = client.WriteSingleRegister(addr, value)
if err != nil {
log.Println("ERROR: WriteRegister:", err)
return 0, err
}
val, err := p.ReadRegister(addr)
if val == int(value) {
return value, nil
}
return 0, fmt.Errorf("Failed to write register")
}
func (p *PingvinKL) updateRegisters() {
handler := p.getHandler()
p.buslock.Lock()