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.

164 lines
3.5 KiB

package m9zApi
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"sort"
"sync"
"time"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/towgo/towgo/lib/system"
g "tgk-touch/internal/global"
"tgk-touch/internal/library/m9z"
)
var l sync.Mutex
var historyLock sync.Mutex
var filePath = system.GetPathOfProgram() + "data/data.json"
const (
maxItems = 50
)
func ScanM9z() {
if !l.TryLock() {
return
}
defer l.Unlock()
cuid := g.Config().DeviceInfo.DeviceId
for i := 0; i < configuredLoopCount(); i++ {
read, err := m9z.SubLoopParametersRead(cuid, uint(i))
if err != nil {
g.Log().Error("sub loop parameters read error:", err)
continue
}
if read == nil {
continue
}
faults := m9z.BuildLoopFaults(uint(i+1), read.AlarmStatus, read.AlarmCode)
recordLoopFaults(cuid, uint(i+1), read.DCVoltage, faults)
}
}
func recordLoopFaults(commUid string, loopIdx uint, voltage float32, faults []m9z.LoopFault) {
for _, fault := range faults {
item := M9zFaultHistory{
CommUid: commUid,
LoopIdx: loopIdx,
Voltage: voltage,
FaultMsg: fault.Message,
FaultCode: fault.Code,
FaultTime: time.Now(),
}
if err := addData(item); err != nil {
g.Log().Error(gerror.Wrap(err, "create error"))
}
}
}
func readData() ([]M9zFaultHistory, error) {
if _, err := os.Stat(filePath); os.IsNotExist(err) {
file, err := createFileWithPath(filePath)
if err != nil {
return nil, gerror.Wrap(err, "create file error")
}
_ = file.Close()
return []M9zFaultHistory{}, nil
}
data, err := os.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("读取文件失败: %v", err)
}
var items []M9zFaultHistory
if len(data) > 0 {
if err := json.Unmarshal(data, &items); err != nil {
return nil, fmt.Errorf("解析 JSON 失败: %v", err)
}
}
for i := range items {
items[i].ID = int64(i + 1)
}
return items, nil
}
func writeData(items []M9zFaultHistory) error {
data, err := json.MarshalIndent(items, "", " ")
if err != nil {
return fmt.Errorf("序列化 JSON 失败: %v", err)
}
return os.WriteFile(filePath, data, 0644)
}
func addData(newItem M9zFaultHistory) error {
historyLock.Lock()
defer historyLock.Unlock()
items, err := readData()
if err != nil {
return gerror.Wrap(err, "readData")
}
for _, item := range items {
if item.CommUid == newItem.CommUid &&
item.LoopIdx == newItem.LoopIdx &&
item.FaultCode == newItem.FaultCode &&
item.FaultMsg == newItem.FaultMsg &&
item.OperateStatus == 0 {
return nil
}
}
if newItem.FaultTime.IsZero() {
newItem.FaultTime = time.Now()
}
items = append(items, newItem)
if len(items) > maxItems {
sort.Slice(items, func(i, j int) bool {
return items[i].FaultTime.Before(items[j].FaultTime)
})
items = items[len(items)-maxItems:]
}
for i := range items {
items[i].ID = int64(i + 1)
}
if err := writeData(items); err != nil {
return gerror.Wrap(err, "writeData")
}
return nil
}
func deleteById(id int) error {
historyLock.Lock()
defer historyLock.Unlock()
items, err := readData()
if err != nil {
return gerror.Wrap(err, "readData")
}
if id < 1 || id > len(items) {
return fmt.Errorf("ID %d 超出范围", id)
}
items = append(items[:id-1], items[id:]...)
for i := id - 1; i < len(items); i++ {
items[i].ID = int64(i + 1)
}
return writeData(items)
}
func createFileWithPath(filePath string) (*os.File, error) {
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
return nil, err
}
return os.Create(filePath)
}