You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
devices/sen6x/vocnox_test.go

233 lines
6.0 KiB
Go

// Copyright 2026 The Periph Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.
package sen6x
import (
"testing"
)
func TestDevGetVOCAlgorithmTuningParameters(t *testing.T) {
cmd := []byte{0x60, 0xd0}
cases := []writeAndReadTestCase[*VOCNOxAlgorithmTuningParameters]{
{
name: "all values set",
model: SEN66,
tx: cmd,
rx: []byte{
0x00, 0x64, 0xfe, // Index offset
0x00, 0x0c, 0xfc, // Learning time offset
0x00, 0x0c, 0xfc, // Learning time gain
0x00, 0xb4, 0xfa, // Gating max duration
0x00, 0x32, 0x26, // Initial std dev estimate
0x00, 0xe6, 0xe6, // Gain factor
},
want: &VOCNOxAlgorithmTuningParameters{
IndexOffset: int16(100),
LearningTimeOffsetHours: int16(12),
LearningTimeGainHours: int16(12),
GatingMaxDurationMinutes: int16(180),
InitialStdDevEstimate: int16(50),
GainFactor: int16(230),
},
},
{
name: "bad crc",
model: SEN66,
tx: cmd,
rx: []byte{
0x00, 0x64, 0xfe, // Index offset
0x00, 0x0c, 0xfc, // Learning time offset
0x00, 0x0c, 0xfc, // Learning time gain
0x00, 0xb4, 0xfa, // Gating max duration
0x00, 0x32, 0x26, // Initial std dev estimate
0x00, 0xe6, 0xff, // Gain factor with incorrect CRC (should be 0xe6)
},
wantErr: true,
},
{
// This fails before sending any data, so no tx or rx set.
name: "model without VOC/NOx capability",
model: SEN62,
wantErr: true,
},
}
runWriteAndReadTests(t, cases, (*Dev).GetVOCAlgorithmTuningParameters)
}
func TestDevSetVOCAlgorithmTuningParameters(t *testing.T) {
cases := []writeTestCase{
{
name: "success",
model: SEN66,
tx: []byte{
0x60, 0xd0, // Command
0x00, 0x64, 0xfe, // Index offset
0x00, 0x0c, 0xfc, // Learning time offset
0x00, 0x0c, 0xfc, // Learning time gain
0x00, 0xb4, 0xfa, // Gating max duration
0x00, 0x32, 0x26, // Initial std dev estimate
0x00, 0xe6, 0xe6, // Gain factor
},
},
{
name: "model without VOC/NOx capability",
model: SEN62,
wantErr: true,
},
}
params := VOCNOxAlgorithmTuningParameters{
IndexOffset: int16(100),
LearningTimeOffsetHours: int16(12),
LearningTimeGainHours: int16(12),
GatingMaxDurationMinutes: int16(180),
InitialStdDevEstimate: int16(50),
GainFactor: int16(230),
}
runWriteTests(t, cases, func(d *Dev) error {
return d.SetVOCAlgorithmTuningParameters(params)
})
}
func TestDevGetVOCAlgorithmState(t *testing.T) {
cmd := []byte{0x61, 0x81}
cases := []writeAndReadTestCase[[8]byte]{
{
name: "success",
model: SEN66,
tx: cmd,
rx: []byte{0x08, 0x43, 0xd8, 0x8b, 0x2b, 0xd4, 0x0f, 0x34, 0x19, 0xa7, 0x72, 0x4a},
want: [8]byte{0x08, 0x43, 0x8b, 0x2b, 0x0f, 0x34, 0xa7, 0x72},
},
{
// writeAndRead will fail because no response is set.
name: "read error",
model: SEN66,
tx: cmd,
dontPanic: true,
wantErr: true,
},
{
name: "model without VOC/NOx capability",
model: SEN62,
wantErr: true,
},
}
runWriteAndReadTests(t, cases, (*Dev).GetVOCAlgorithmState)
}
func TestDevSetVOCAlgorithmState(t *testing.T) {
cases := []writeTestCase{
{
name: "success",
model: SEN66,
tx: []byte{
0x61, 0x81, // Command
0x08, 0x43, 0xd8, 0x8b, 0x2b, 0xd4, 0x0f, 0x34, 0x19, 0xa7, 0x72, 0x4a, // VOC alg state
},
},
{
name: "model without VOC/NOx capability",
model: SEN62,
wantErr: true,
},
}
runWriteTests(t, cases, func(d *Dev) error {
return d.SetVOCAlgorithmState([8]byte{0x08, 0x43, 0x8b, 0x2b, 0x0f, 0x34, 0xa7, 0x72})
})
}
func TestDevGetNOxAlgorithmTuningParameters(t *testing.T) {
cmd := []byte{0x60, 0xe1}
cases := []writeAndReadTestCase[*VOCNOxAlgorithmTuningParameters]{
{
name: "all values set",
model: SEN66,
tx: cmd,
rx: []byte{
0x00, 0x01, 0xb0, // Index offset
0x00, 0x0c, 0xfc, // Learning time offset
0x00, 0x0c, 0xfc, // Learning time gain
0x02, 0xd0, 0x5c, // Gating max duration
0x00, 0x32, 0x26, // Initial std dev estimate
0x00, 0xe6, 0xe6, // Gain factor
},
want: &VOCNOxAlgorithmTuningParameters{
IndexOffset: int16(1),
LearningTimeOffsetHours: int16(12),
LearningTimeGainHours: int16(12),
GatingMaxDurationMinutes: int16(720),
InitialStdDevEstimate: int16(50),
GainFactor: int16(230),
},
},
{
name: "bad crc",
model: SEN66,
tx: cmd,
rx: []byte{
0x00, 0x01, 0xb0, // Index offset
0x00, 0x0c, 0xfc, // Learning time offset
0x00, 0x0c, 0xfc, // Learning time gain
0x02, 0xd0, 0x5c, // Gating max duration
0x00, 0x32, 0x26, // Initial std dev estimate
0x00, 0xe6, 0xff, // Gain factor with incorrect CRC (should be 0xe6)
},
wantErr: true,
},
{
// This fails before sending a command, so no tx or rx set.
name: "model without VOC/NOx capability",
model: SEN62,
wantErr: true,
},
}
runWriteAndReadTests(t, cases, (*Dev).GetNOxAlgorithmTuningParameters)
}
func TestDevSetNOxAlgorithmTuningParameters(t *testing.T) {
cases := []writeTestCase{
{
name: "success",
model: SEN66,
tx: []byte{
0x60, 0xe1, // Command
0x00, 0x01, 0xb0, // Index offset
0x00, 0x0c, 0xfc, // Learning time offset
0x00, 0x0c, 0xfc, // Learning time gain
0x02, 0xd0, 0x5c, // Gating max duration
0x00, 0x32, 0x26, // Initial std dev estimate
0x00, 0xe6, 0xe6, // Gain factor
},
},
{
name: "model without VOC/NOx capability",
model: SEN62,
wantErr: true,
},
}
params := VOCNOxAlgorithmTuningParameters{
IndexOffset: int16(1),
LearningTimeOffsetHours: int16(12),
LearningTimeGainHours: int16(12),
GatingMaxDurationMinutes: int16(720),
InitialStdDevEstimate: int16(50),
GainFactor: int16(230),
}
runWriteTests(t, cases, func(d *Dev) error {
return d.SetNOxAlgorithmTuningParameters(params)
})
}