Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix temp monitor #33

Merged
merged 2 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 5 additions & 2 deletions bootstrap/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const (
ServiceModeFSMoinitor
ServiceModeHealthcheck
ServiceModeTempMonitor

tempChangeMonitorPeriod = 5 * time.Minute
ipChangeMonitorPeriod = 30 * time.Minute
)

// Main adds standard handlers to the telega bot.
Expand Down Expand Up @@ -53,13 +56,13 @@ func Main(runtime string, serviceMode byte) (status string, err error) {
if (serviceMode & ServiceModePeriodic) == ServiceModePeriodic {
// add periodic tasks
log.Println("adding periodic tasks handlers")
bot.AddPeriodicTask(30*time.Minute, "Public IP Changed:", feed.PublicIP)
bot.AddPeriodicTask(ipChangeMonitorPeriod, "Public IP Changed:", feed.PublicIP)
}

if (serviceMode & ServiceModeTempMonitor) == ServiceModeTempMonitor {
// add temperature change monitoring
log.Println("adding temperature change monitoring")
bot.AddPeriodicTask(5*time.Minute, "Temperature changed:", feed.TemperatureMonitor)
bot.AddPeriodicTask(tempChangeMonitorPeriod, "Temperature changed:", feed.TemperatureMonitor)
}

if (serviceMode & ServiceModeFSMoinitor) == ServiceModeFSMoinitor {
Expand Down
34 changes: 26 additions & 8 deletions feed/temperature.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import (
)

const (
sensorDevicePath = "/sys/bus/w1/devices/28-3c01d607ca0a/w1_slave"
errTemp int32 = -1000
maxRetries = 10
minRereshInterval = 5 * time.Second
monitoredTemperatureDiff = 0.5
sensorDevicePath = "/sys/bus/w1/devices/28-3c01d607ca0a/w1_slave"
sensorDevicePathKey = "device-path"
sensorMinReadingIntervalPathKey = "min-read"
errTemp int32 = -1000
maxRetries = 10
minRereshInterval = 5 * time.Second
monitoredTemperatureDiff = 500
)

var (
Expand Down Expand Up @@ -88,9 +90,17 @@ func getTemperatureReading(fpath string) (int32, error) {
}

func getTemperatureReadingWithRetries(ctx context.Context, fpath string, retries int) (temperature int32, timestamp time.Time, err error) {

var refreshInterval = func() time.Duration {
if p, ok := ctx.Value(sensorMinReadingIntervalPathKey).(time.Duration); ok {
return p
}
return minRereshInterval
}

// do not allow more frequent polls
lastTimeMutex.RLock()
if time.Since(lastTime) < minRereshInterval {
if time.Since(lastTime) < refreshInterval() {
defer lastTimeMutex.RUnlock()
return atomic.LoadInt32(&lastTemp), lastTime, nil
}
Expand Down Expand Up @@ -131,11 +141,19 @@ func getTemperatureReadingWithRetries(ctx context.Context, fpath string, retries
}

// TemperatureMonitor 's for temp changes over the threshold
func TemperatureMonitor(ctx context.Context) (temprature string) {
v, _, err := getTemperatureReadingWithRetries(ctx, sensorDevicePath, 10)
func TemperatureMonitor(ctx context.Context) string {
var devicePath = func() string {
if p, ok := ctx.Value(sensorDevicePathKey).(string); ok {
return p
}
return sensorDevicePath
}

v, _, err := getTemperatureReadingWithRetries(ctx, devicePath(), 10)
if err != nil {
return onError("error reading temperature", err)
}
log.Println("temperature monitor: prev:", monitoredTemperature, "curr:", v)
if math.Abs(float64(v-monitoredTemperature)) > monitoredTemperatureDiff {
monitoredTemperature = v
return fmt.Sprintf("%.1f ℃ 🌡", float32(v)/1000.0)
Expand Down
36 changes: 36 additions & 0 deletions feed/temperature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package feed
import (
"context"
"os"
"path"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -67,3 +68,38 @@ func Test004_tempParseFilePersistent(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, int32(29812), v)
}

func Test005_tempMonitorChanges(t *testing.T) {

const (
datapath = "temp_sensor_readings/"
t88 = "28_8c"
t95 = "29_5c"
t98 = "29_8c"
tr28 = "32_8c"
m108 = "minus_10_8_c"
m104 = "minus_10_4_c"
)

var noDelayCtx = func() context.Context {
return context.WithValue(context.Background(), sensorMinReadingIntervalPathKey, 1*time.Nanosecond)
}

ctx := context.WithValue(noDelayCtx(), sensorDevicePathKey, path.Join(testDataDir, datapath, t98))
assert.True(t, strings.HasPrefix(TemperatureMonitor(ctx), "29.8"))

ctx = context.WithValue(noDelayCtx(), sensorDevicePathKey, path.Join(testDataDir, datapath, t95))
assert.Empty(t, TemperatureMonitor(ctx))

ctx = context.WithValue(noDelayCtx(), sensorDevicePathKey, path.Join(testDataDir, datapath, t88))
assert.True(t, strings.HasPrefix(TemperatureMonitor(ctx), "28.8"))

ctx = context.WithValue(noDelayCtx(), sensorDevicePathKey, path.Join(testDataDir, datapath, tr28))
assert.True(t, strings.HasPrefix(TemperatureMonitor(ctx), "32.8"))

ctx = context.WithValue(noDelayCtx(), sensorDevicePathKey, path.Join(testDataDir, datapath, m108))
assert.True(t, strings.HasPrefix(TemperatureMonitor(ctx), "-10.8"))

ctx = context.WithValue(noDelayCtx(), sensorDevicePathKey, path.Join(testDataDir, datapath, m104))
assert.Empty(t, TemperatureMonitor(ctx))
}
4 changes: 3 additions & 1 deletion telega/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,10 @@ func (b Bot) Run() (string, error) {

func (b *Bot) processPeriodicTasks(chatIDs []int64) {
b.periodicTaskCycle++
log.Println("bot: processing periodic tasks")
for _, h := range b.periodicTasks {
if b.periodicTaskCycle/h.interval == 0 {
log.Println("bot: executing periodic task", h.intro, b.periodicTaskCycle, h.interval, (b.periodicTaskCycle % h.interval))
if b.periodicTaskCycle%h.interval == 0 {
notificationMessageWrapper(b.ctx, h.intro, h.fn, b.bot, chatIDs)
}
}
Expand Down
2 changes: 2 additions & 0 deletions testdata/temp_sensor_readings/28_8c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dd 01 55 05 7f a5 a5 66 81 : crc=81 YES
dd 01 55 05 7f a5 a5 66 81 t=28812
2 changes: 2 additions & 0 deletions testdata/temp_sensor_readings/29_5c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dd 01 55 05 7f a5 a5 66 81 : crc=81 YES
dd 01 55 05 7f a5 a5 66 81 t=29512
2 changes: 2 additions & 0 deletions testdata/temp_sensor_readings/29_8c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dd 01 55 05 7f a5 a5 66 81 : crc=81 YES
dd 01 55 05 7f a5 a5 66 81 t=29812
2 changes: 2 additions & 0 deletions testdata/temp_sensor_readings/32_8c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dd 01 55 05 7f a5 a5 66 81 : crc=81 YES
dd 01 55 05 7f a5 a5 66 81 t=32812
2 changes: 2 additions & 0 deletions testdata/temp_sensor_readings/minus_10_4_c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dd 01 55 05 7f a5 a5 66 81 : crc=81 YES
dd 01 55 05 7f a5 a5 66 81 t=-10412
2 changes: 2 additions & 0 deletions testdata/temp_sensor_readings/minus_10_8_c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dd 01 55 05 7f a5 a5 66 81 : crc=81 YES
dd 01 55 05 7f a5 a5 66 81 t=-10801