You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
3.3 KiB

package meterFirm
import (
"encoding/json"
"log"
"os"
"path/filepath"
"sync"
g "tgk-touch/internal/global"
"tgk-touch/internal/library/meterControl"
"github.com/towgo/towgo/lib/system"
"github.com/towgo/towgo/towgo"
)
type MeterFirmManager struct {
mu sync.RWMutex
meterFirm string
onReload []func()
}
type MeterFirmData struct {
MeterFirm string `json:"meter_firm"`
}
var (
manager *MeterFirmManager = &MeterFirmManager{}
)
func Manager() *MeterFirmManager {
return manager
}
func getMeterFirmFilePath() string {
return filepath.Join(system.GetPathOfProgram(), "data", "meterFirm.json")
}
func (m *MeterFirmManager) Get() string {
m.mu.RLock()
defer m.mu.RUnlock()
return m.meterFirm
}
func (m *MeterFirmManager) Set(firm string) error {
m.mu.Lock()
m.meterFirm = firm
if err := m.saveToFile(); err != nil {
m.mu.Unlock()
return err
}
cbs := m.onReload
m.mu.Unlock()
for _, cb := range cbs {
cb()
}
return nil
}
func (m *MeterFirmManager) RegisterReloadCallback(cb func()) {
m.mu.Lock()
defer m.mu.Unlock()
m.onReload = append(m.onReload, cb)
}
func (m *MeterFirmManager) saveToFile() error {
filePath := getMeterFirmFilePath()
dir := filepath.Dir(filePath)
if err := os.MkdirAll(dir, 0755); err != nil {
return err
}
data := MeterFirmData{
MeterFirm: m.meterFirm,
}
jsonData, err := json.Marshal(data)
if err != nil {
return err
}
return os.WriteFile(filePath, jsonData, 0600)
}
func (m *MeterFirmManager) loadFromFile() error {
m.mu.Lock()
defer m.mu.Unlock()
filePath := getMeterFirmFilePath()
jsonData, err := os.ReadFile(filePath)
if err != nil {
if os.IsNotExist(err) {
m.meterFirm = g.Config().DeviceInfo.MeterFirm
return m.saveToFile()
}
return err
}
var data MeterFirmData
if err := json.Unmarshal(jsonData, &data); err != nil {
return err
}
if data.MeterFirm == "" {
data.MeterFirm = g.Config().DeviceInfo.MeterFirm
}
m.meterFirm = data.MeterFirm
return nil
}
func (m *MeterFirmManager) GetMeterControl() meterControl.IMeterControl {
return meterControl.GetMeterControls(meterControl.MeterFirm(m.Get()))
}
func Init() {
if err := manager.loadFromFile(); err != nil {
g.GVA_LOG.Sugar().Warnf("load meterFirm data failed: %v, using default", err)
manager.meterFirm = g.Config().DeviceInfo.MeterFirm
log.Println("===========", g.Config().DeviceInfo.MeterFirm)
err = manager.saveToFile()
if err != nil {
panic(err)
}
}
towgo.SetFunc("/m9z/meter/getMeterFirm", getMeterFirm)
towgo.SetFunc("/m9z/meter/setMeterFirm", setMeterFirm)
}
func getMeterFirm(rpcConn towgo.JsonRpcConnection) {
rpcConn.WriteResult(map[string]interface{}{
"meter_firm": manager.Get(),
})
}
type SetMeterFirmReq struct {
MeterFirm string `json:"meter_firm"`
}
func setMeterFirm(rpcConn towgo.JsonRpcConnection) {
var req SetMeterFirmReq
rpcConn.ReadParams(&req)
if req.MeterFirm == "" {
rpcConn.WriteError(400, "meter_firm is required")
return
}
_, ok := meterControl.MeterFirms[req.MeterFirm]
if !ok {
rpcConn.WriteError(400, "invalid meter_firm, available: ADL400, DDSD1352, DTS1352")
return
}
if err := manager.Set(req.MeterFirm); err != nil {
rpcConn.WriteError(500, "save meter_firm failed: "+err.Error())
return
}
rpcConn.WriteResult(map[string]interface{}{
"success": true,
"meter_firm": req.MeterFirm,
})
}