103 lines
2.2 KiB
Go
103 lines
2.2 KiB
Go
|
package app
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math"
|
||
|
|
||
|
"git.fuyu.moe/5GPowerQuality/api/app/internal/model"
|
||
|
"git.ultraware.nl/NiseVoid/qb"
|
||
|
"git.ultraware.nl/NiseVoid/qb/qc"
|
||
|
)
|
||
|
|
||
|
// GetScores returns the scores for the trading page
|
||
|
func GetScores(meterID int) []Scores {
|
||
|
m := model.Measurement()
|
||
|
q := m.Select(
|
||
|
m.UGem1, m.UGem2, m.UGem3,
|
||
|
m.IMax1, m.IMax2, m.IMax3,
|
||
|
m.CGem1, m.CGem2, m.CGem3,
|
||
|
).
|
||
|
Where(qc.Eq(m.MeterID, meterID)).
|
||
|
OrderBy(qb.Desc(m.Time))
|
||
|
|
||
|
data := [3]powerData{}
|
||
|
err := db.QueryRow(q).Scan(
|
||
|
&data[0].Voltage, &data[1].Voltage, &data[2].Voltage,
|
||
|
&data[0].MaxAmpere, &data[1].MaxAmpere, &data[2].MaxAmpere,
|
||
|
&data[0].CosPhi, &data[1].CosPhi, &data[2].CosPhi,
|
||
|
)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
scores := make([]Scores, 3)
|
||
|
for k, v := range data {
|
||
|
scores[k] = Scores{
|
||
|
Phase: k + 1,
|
||
|
Producation: productionScore(v),
|
||
|
Usage: usageScore(v),
|
||
|
Storage: storageScore(v),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return scores
|
||
|
}
|
||
|
|
||
|
// Scores contains all scores for a phase
|
||
|
type Scores struct {
|
||
|
Phase int `json:"phase"`
|
||
|
Producation float64 `json:"production"`
|
||
|
Usage float64 `json:"usage"`
|
||
|
Storage float64 `json:"storage"`
|
||
|
}
|
||
|
|
||
|
type powerData struct {
|
||
|
Voltage float64
|
||
|
MaxAmpere float64
|
||
|
CosPhi float64
|
||
|
}
|
||
|
|
||
|
func (data powerData) String() string {
|
||
|
return fmt.Sprintf(`%3.0fV, %3.0fA, %.1fφ`, data.Voltage, data.MaxAmpere, data.CosPhi)
|
||
|
}
|
||
|
|
||
|
func getScoreModifier(expected, value, step float64) float64 {
|
||
|
var neg bool
|
||
|
if value-expected < 0 {
|
||
|
neg = true
|
||
|
}
|
||
|
r := math.Pow((value-expected)/step, 2)
|
||
|
if neg {
|
||
|
r = r * -1
|
||
|
}
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
func productionScore(data powerData) float64 {
|
||
|
vMod := getScoreModifier(230, data.Voltage, 5) * -1
|
||
|
aMod := getScoreModifier(100, data.MaxAmpere, 25) * -1
|
||
|
if aMod > 0 {
|
||
|
aMod = 0
|
||
|
}
|
||
|
cpMod := getScoreModifier(0.8, math.Abs(data.CosPhi), 0.1)
|
||
|
|
||
|
return vMod + aMod + cpMod
|
||
|
}
|
||
|
|
||
|
func usageScore(data powerData) float64 {
|
||
|
vMod := getScoreModifier(230, data.Voltage, 5)
|
||
|
aMod := getScoreModifier(100, data.MaxAmpere, 25) * -1
|
||
|
if aMod > 0 {
|
||
|
aMod = 0
|
||
|
}
|
||
|
|
||
|
return vMod + aMod
|
||
|
}
|
||
|
|
||
|
func storageScore(data powerData) float64 {
|
||
|
vMod := getScoreModifier(230, data.Voltage, 5)
|
||
|
cpMod := getScoreModifier(0.8, math.Abs(data.CosPhi), 0.1) * -1
|
||
|
|
||
|
return vMod + cpMod
|
||
|
}
|