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, }) }