Skip to content

Commit

Permalink
EnergyPanel average power check added
Browse files Browse the repository at this point in the history
  • Loading branch information
hubertat committed Apr 4, 2021
1 parent 96d8ae2 commit e6befb6
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 37 deletions.
109 changes: 109 additions & 0 deletions energy_panel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package main

import (
"bytes"
"encoding/binary"
"fmt"
"time"

"github.com/goburrow/modbus"
)

type VictronGridMeter struct {
ConnectionString string
HoldMinutes int
PowerLevel int

readouts []struct {
When time.Time
TotalPower int
}

raw struct {
Power [3]int16
} `json:"-"`
}

func (vgm *VictronGridMeter) ReadBytes(result []byte) (err error) {
reader := bytes.NewReader(result)
err = binary.Read(reader, binary.BigEndian, &vgm.raw)

return
}

func (vgm *VictronGridMeter) readModbus() (err error) {
slaveId := 31
dataAddr := 2600
dataCount := 3

handler := modbus.NewTCPClientHandler(vgm.ConnectionString)
handler.Timeout = 2 * time.Second
handler.SlaveId = byte(slaveId)

err = handler.Connect()
if err != nil {
return
}
defer handler.Close()

client := modbus.NewClient(handler)
result, err := client.ReadHoldingRegisters(uint16(dataAddr), uint16(dataCount))
if err != nil {
return
}

err = vgm.ReadBytes(result)

return
}

func (vgm *VictronGridMeter) cleanOldReadouts() {
holdDuration := time.Minute * time.Duration(vgm.HoldMinutes)
for ix, readout := range vgm.readouts {
if time.Since(readout.When) > holdDuration {
vgm.readouts = append(vgm.readouts[:ix], vgm.readouts[ix+1:]...)
}
}
}

func (vgm *VictronGridMeter) GetAveragePower() int {
if len(vgm.readouts) == 0 {
return 0
}

var powerSum int
for _, readout := range vgm.readouts {
powerSum += readout.TotalPower
}

return powerSum / len(vgm.readouts)
}

func (vgm *VictronGridMeter) Tick() error {
err := vgm.readModbus()
if err != nil {
return err
}

vgm.cleanOldReadouts()

var totalP int
for _, p := range vgm.raw.Power {
totalP += int(p)
}

vgm.readouts = append(vgm.readouts, struct {
When time.Time
TotalPower int
}{When: time.Now(), TotalPower: totalP})

return nil
}

func (vgm *VictronGridMeter) CheckAvPowerLimit() bool {
return vgm.GetAveragePower() < (-1 * vgm.PowerLevel)
}

func (vgm *VictronGridMeter) GetDebugString() string {
return fmt.Sprintf("VictronGridMeter:: raw energy data: %v; readouts count: %d; average total power: %d", vgm.raw, len(vgm.readouts), vgm.GetAveragePower())
}
93 changes: 56 additions & 37 deletions ow_set.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
package main
package main

import (
"encoding/json"
"fmt"
"log"
"io/ioutil"
"strings"
"strconv"
"log"
"path/filepath"
"encoding/json"
"time"
"strconv"
"strings"
"sync"
"time"
)


type OwSet struct {
Path string `json:",omitempty"`
SlavePrefix string `json:",omitempty"`
Debug bool `json:",omitempty"`

Sensors []*OwSlave `json:",omitempty"`

LogInflux *InfluxWriter `json:",omitempty"`
SendHttp *HttpWriter `json:",omitempty"`

Server *Server `json:",omitempty"`
OffPeak *OffPeak `json:",omitempty"`

RefreshSeconds int `json:",omitempty"`

updated time.Time
refreshInterval time.Duration
tick *time.Ticker
blocker sync.Mutex
}
Path string `json:",omitempty"`
SlavePrefix string `json:",omitempty"`
Debug bool `json:",omitempty"`

Sensors []*OwSlave `json:",omitempty"`

LogInflux *InfluxWriter `json:",omitempty"`
SendHttp *HttpWriter `json:",omitempty"`

Server *Server `json:",omitempty"`
OffPeak *OffPeak `json:",omitempty"`
EnergyPanel *VictronGridMeter `json:",omitempty"`

RefreshSeconds int `json:",omitempty"`

updated time.Time
refreshInterval time.Duration
tick *time.Ticker
blocker sync.Mutex
}

func (os *OwSet) LogDebug(message string) {
if !os.Debug {
Expand All @@ -43,13 +43,13 @@ func (os *OwSet) LogDebug(message string) {
}

func (os *OwSet) Log(message string) {
log.Printf("%s\n", message)
log.Printf("%s\n", message)
}

func (os *OwSet) CheckIfSet() bool {
if len(os.Path) == 0 && len(os.SlavePrefix) == 0 {
return false
}
}

return true
}
Expand Down Expand Up @@ -85,7 +85,7 @@ func (os *OwSet) Set(configPath ...string) error {

for _, slave := range os.Sensors {
slave.InitId()

err = slave.InitThermo()
if err != nil {
return fmt.Errorf("OwSet Set | error initializing thermostat:\n%v", err)
Expand All @@ -112,7 +112,7 @@ func (os *OwSet) InitSlaves(settings ...string) error {
devs, err := ioutil.ReadDir(os.Path)
if err != nil {
return fmt.Errorf("OwSet InitSlaves: error reading dir (%s):\n%w", os.Path, err)
}
}

var zeroId, alreadyHere *OwSlave

Expand All @@ -126,7 +126,7 @@ func (os *OwSet) InitSlaves(settings ...string) error {

alreadyHere = os.GetSlaveById(id)
if alreadyHere != nil {

alreadyHere.SetFromInt(val)
} else {

Expand All @@ -143,7 +143,7 @@ func (os *OwSet) InitSlaves(settings ...string) error {

}
os.updated = time.Now()

return nil
}

Expand Down Expand Up @@ -191,7 +191,7 @@ func (os *OwSet) RefreshAll() error {

os.blocker.Lock()
defer os.blocker.Unlock()

for _, slave := range os.Sensors {

wslave, err := ioutil.ReadFile(filepath.Join(os.Path, fmt.Sprintf("%s%012x", os.SlavePrefix, slave.Id), "w1_slave"))
Expand Down Expand Up @@ -222,14 +222,33 @@ func (os *OwSet) cycling() {
if err != nil {
log.Printf("ERROR [in OwSet] during refreshing during cycling:\n%v", err)
} else {

var offPeakHeatUp, energyPanelHeatUp bool
if os.OffPeak != nil {
os.LogDebug("OffPeak enabled [OwSet], checking state")
heatUpMode := os.OffPeak.Check()
offPeakHeatUp = os.OffPeak.Check()
}
if os.EnergyPanel != nil {
os.LogDebug("EnergyPanel enabled, ticking and checking")
err = os.EnergyPanel.Tick()
if err != nil {
os.Log(fmt.Sprintf("Received error from EnergyPanel.Tick(): %v", err))
} else {
os.LogDebug(os.EnergyPanel.GetDebugString())
energyPanelHeatUp = os.EnergyPanel.CheckAvPowerLimit()
}

}
if offPeakHeatUp || energyPanelHeatUp {
if offPeakHeatUp {
os.LogDebug("Received OffPeak, setting heat up mode")
}
if energyPanelHeatUp {
os.LogDebug("Received OK Power Limit from Energy Panel, setting heat up mode")
}
for _, slave := range os.Sensors {
if slave.Thermostat != nil {
os.LogDebug(fmt.Sprintf("Thermostat found, setting heatUpMode: %v", heatUpMode))
slave.Thermostat.HeatUpMode = heatUpMode
os.LogDebug(fmt.Sprintf("Thermostat found, setting heatUpMode: %v", (energyPanelHeatUp || offPeakHeatUp)))
slave.Thermostat.HeatUpMode = energyPanelHeatUp || offPeakHeatUp
}
}
}
Expand Down

0 comments on commit e6befb6

Please sign in to comment.