modelRT/model/measurement_model.go

177 lines
5.2 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package model define model struct of model runtime service
package model
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"modelRT/constants"
)
// MeasurementDataSource define measurement data source struct
type MeasurementDataSource struct {
Type int `json:"type"`
IOAddress IOAddress `json:"io_address"`
}
// IOAddress define interface of IO address
type IOAddress interface{}
// CL3611Address define CL3611 protol struct
type CL3611Address struct {
Station string `json:"station"`
Device string `json:"device"`
Channel string `json:"channel"`
}
// Power104Address define electricity 104 protol struct
type Power104Address struct {
Station string `json:"station"`
Packet int `json:"packet"`
Offset int `json:"offset"`
}
// NewCL3611DataSource define func of create CL3611 data source
func NewCL3611DataSource(station, device, channel string) (*MeasurementDataSource, error) {
return &MeasurementDataSource{
Type: constants.DataSourceTypeCL3611,
IOAddress: CL3611Address{
Station: station,
Device: device,
Channel: channel,
},
}, nil
}
// NewPower104DataSource define func of create Power104 data source
func NewPower104DataSource(station string, packet, offset int) (*MeasurementDataSource, error) {
return &MeasurementDataSource{
Type: constants.DataSourceTypePower104,
IOAddress: Power104Address{
Station: station,
Packet: packet,
Offset: offset,
},
}, nil
}
func generateChannelName(prefix string, number int, suffix string) (string, error) {
switch prefix {
case constants.ChannelPrefixTelemetry:
if number > 10 {
return "", constants.ErrExceedsLimitType
}
var builder strings.Builder
numberStr := strconv.Itoa(number)
builder.Grow(len(prefix) + len(numberStr) + len(suffix))
builder.WriteString(prefix)
builder.WriteString(numberStr)
builder.WriteString(suffix)
channelName := builder.String()
return channelName, nil
case constants.ChannelPrefixTelesignal:
var numberStr string
if number < 10 {
numberStr = "0" + strconv.Itoa(number)
}
numberStr = strconv.Itoa(number)
var builder strings.Builder
builder.Grow(len(prefix) + len(numberStr) + len(suffix))
builder.WriteString(prefix)
builder.WriteString(numberStr)
builder.WriteString(suffix)
channelName := builder.String()
return channelName, nil
default:
return "", constants.ErrUnsupportedChannelPrefixType
}
}
// NewTelemetryChannel define func of generate telemetry channel CL3611 data source
func NewTelemetryChannel(station, device, channelNameSuffix string, channelNumber int) (*MeasurementDataSource, error) {
channelName, err := generateChannelName(constants.ChannelPrefixTelemetry, channelNumber, channelNameSuffix)
if err != nil {
return nil, fmt.Errorf("failed to generate channel name: %w", err)
}
return NewCL3611DataSource(station, device, channelName)
}
// NewTelesignalChannel define func of generate telesignal channel CL3611 data source
func NewTelesignalChannel(station, device, channelNameSuffix string, channelNumber int) (*MeasurementDataSource, error) {
channelName, err := generateChannelName(constants.ChannelPrefixTelesignal, channelNumber, channelNameSuffix)
if err != nil {
return nil, fmt.Errorf("failed to generate channel name: %w", err)
}
return NewCL3611DataSource(station, device, channelName)
}
// NewStandardChannel define func of generate standard channel CL3611 data source
func NewStandardChannel(station, device, channelType string) (*MeasurementDataSource, error) {
return NewCL3611DataSource(station, device, channelType)
}
// ParseDataSourceFromJSON define func of parse data source from json string
func ParseDataSourceFromJSON(jsonStr string) (MeasurementDataSource, error) {
var data struct {
Type int `json:"type"`
IOAddress json.RawMessage `json:"io_address"`
}
if err := json.Unmarshal([]byte(jsonStr), &data); err != nil {
return MeasurementDataSource{}, err
}
var source MeasurementDataSource
source.Type = data.Type
switch data.Type {
case constants.DataSourceTypeCL3611:
var addr CL3611Address
if err := json.Unmarshal(data.IOAddress, &addr); err != nil {
return MeasurementDataSource{}, err
}
source.IOAddress = addr
case constants.DataSourceTypePower104:
var addr Power104Address
if err := json.Unmarshal(data.IOAddress, &addr); err != nil {
return MeasurementDataSource{}, err
}
source.IOAddress = addr
default:
// 对于未知类型保持原始JSON数据
source.IOAddress = data.IOAddress
}
return source, nil
}
// ToJSON define func of convert data source to json string
func (m MeasurementDataSource) ToJSON() (string, error) {
bytes, err := json.Marshal(m)
if err != nil {
return "", err
}
return string(bytes), nil
}
// GetIOAddress define func of get IO address with correct type
func (m MeasurementDataSource) GetIOAddress() (IOAddress, error) {
switch m.Type {
case constants.DataSourceTypeCL3611:
if addr, ok := m.IOAddress.(CL3611Address); ok {
return addr, nil
}
return nil, constants.ErrInvalidAddressType
case constants.DataSourceTypePower104:
if addr, ok := m.IOAddress.(Power104Address); ok {
return addr, nil
}
return nil, constants.ErrInvalidAddressType
default:
return nil, constants.ErrUnknownDataType
}
}