add gradient and random effect.

This commit is contained in:
2022-08-19 10:55:29 +02:00
parent 8c7f1c6ffc
commit 1f5df2e034
13 changed files with 247 additions and 50 deletions
+60
View File
@@ -0,0 +1,60 @@
package effects
import (
"fmt"
"git.aiterp.net/lucifer3/server/device"
"math"
"time"
)
type Gradient struct {
States []device.State `json:"states,omitempty"`
AnimationMS int64 `json:"AnimationMs,omitempty"`
Reverse bool `json:"backward,omitempty"`
Interpolate bool `json:"interpolate,omitempty"`
}
func (e Gradient) State(index, length, round, _ int) device.State {
if len(e.States) == 0 {
return device.State{}
}
if e.Reverse {
index = length - (index + 1)
}
walkedIndex := (index + round) % length
indexFactor := math.Min(float64(walkedIndex)/float64(length-1), 1)
stateIncrement := 1.0 / float64(len(e.States)-1)
for i := range e.States {
a := float64(i) * stateIncrement
if indexFactor >= a {
si := e.States[i]
sj := e.States[(i+1)%len(e.States)]
f := (indexFactor - a) / stateIncrement
if f < 0 || f > 1 {
panic(f)
}
if e.Interpolate {
return si.Interpolate(sj, f)
} else if f < 0.5 {
return si
} else {
return sj
}
}
}
return e.States[len(e.States)-1]
}
func (e Gradient) Frequency() time.Duration {
return time.Duration(e.AnimationMS) * time.Millisecond
}
func (e Gradient) EffectDescription() string {
return fmt.Sprintf("Gradient(states:%s, anim:%dms, int:%t)", statesDescription(e.States), e.AnimationMS, e.Interpolate)
}
+2 -2
View File
@@ -15,14 +15,14 @@ type Manual struct {
}
func (e Manual) EffectDescription() string {
return fmt.Sprintf("Manual%s", e.State(0, 0, 0).String())
return fmt.Sprintf("Manual%s", e.State(0, 0, 0, 0).String())
}
func (e Manual) Frequency() time.Duration {
return 0
}
func (e Manual) State(int, int, int) device.State {
func (e Manual) State(int, int, int, int) device.State {
return device.State{
Power: e.Power,
Temperature: e.Temperature,
+12 -8
View File
@@ -7,18 +7,22 @@ import (
)
type Pattern struct {
States []device.State `json:"states,omitempty"`
ShiftMS int64 `json:"shiftMs,omitempty"`
States []device.State `json:"states,omitempty"`
AnimationMS int64 `json:"animationMs,omitempty"`
}
func (p Pattern) State(index, round, _ int) device.State {
return p.States[(index+round)%len(p.States)]
func (e Pattern) State(index, _, round, _ int) device.State {
if len(e.States) == 0 {
return device.State{}
}
return e.States[(index+round)%len(e.States)]
}
func (p Pattern) Frequency() time.Duration {
return time.Duration(p.ShiftMS) * time.Millisecond
func (e Pattern) Frequency() time.Duration {
return time.Duration(e.AnimationMS) * time.Millisecond
}
func (p Pattern) EffectDescription() string {
return fmt.Sprintf("Pattern(len:%d, animation:%dms)", len(p.States), p.ShiftMS)
func (e Pattern) EffectDescription() string {
return fmt.Sprintf("Pattern(states:%s, anim:%dms)", statesDescription(e.States), e.AnimationMS)
}
+54
View File
@@ -0,0 +1,54 @@
package effects
import (
"fmt"
"git.aiterp.net/lucifer3/server/device"
"math/rand"
"time"
)
type Random struct {
States []device.State `json:"states,omitempty"`
Interpolate bool `json:"interpolate,omitempty"`
AnimationMS int64 `json:"animationMs,omitempty"`
}
func (e Random) State(_, _, _, _ int) device.State {
if len(e.States) == 0 {
return device.State{}
}
indexFactor := rand.Float64()
stateIncrement := 1.0 / float64(len(e.States)-1)
for i := range e.States {
a := float64(i) * stateIncrement
if indexFactor >= a {
si := e.States[i]
sj := e.States[(i+1)%len(e.States)]
f := (indexFactor - a) / stateIncrement
if f < 0 || f > 1 {
panic(f)
}
if e.Interpolate {
return si.Interpolate(sj, f)
} else if f < 0.5 {
return si
} else {
return sj
}
}
}
return e.States[len(e.States)-1]
}
func (e Random) Frequency() time.Duration {
return time.Duration(e.AnimationMS) * time.Millisecond
}
func (e Random) EffectDescription() string {
return fmt.Sprintf("Random(states:%s, anim:%dms, int:%t)", statesDescription(e.States), e.AnimationMS, e.Interpolate)
}
+23
View File
@@ -0,0 +1,23 @@
package effects
import (
"git.aiterp.net/lucifer3/server/device"
"strings"
)
func statesDescription(states []device.State) string {
sb := strings.Builder{}
sb.Grow(128)
sb.WriteRune('[')
for i, state := range states {
if i > 0 {
sb.WriteString(", ")
}
sb.WriteString(state.String())
}
sb.WriteRune(']')
return sb.String()
}