air-sensors

Air Quality Sensor library
git clone https://www.brianlane.com/git/air-sensors
Log | Files | Refs | README | LICENSE

pmsa003i_test.go (3832B)


      1 // Copyright 2020 by Brian C. Lane <bcl@brianlane.com>. All rights reserved.
      2 // Use of this source code is governed under the Apache License, Version 2.0
      3 // that can be found in the LICENSE file.
      4 
      5 package pmsa003i
      6 
      7 import (
      8 	"fmt"
      9 	"strings"
     10 	"testing"
     11 
     12 	"periph.io/x/periph/conn/i2c/i2ctest"
     13 )
     14 
     15 var (
     16 	GoodSensorData = []byte{
     17 		0x42, 0x4d, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01,
     18 		0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05,
     19 		0x00, 0x7e, 0x00, 0x2a, 0x00, 0x0f, 0x00, 0x09,
     20 		0x00, 0x03, 0x00, 0x03, 0x97, 0x00, 0x02, 0x14}
     21 	BadStartSensorData = []byte{
     22 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     23 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     24 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     25 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
     26 	BadChecksumSensorData = []byte{
     27 		0x42, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     28 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     29 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     30 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
     31 )
     32 
     33 func TestWord(t *testing.T) {
     34 	data := []byte{0x00, 0x01, 0x80, 0x0A, 0x55, 0xAA, 0xFF, 0x7F}
     35 	result := []uint16{0x0001, 0x800A, 0x55AA, 0xFF7F}
     36 	for i := 0; i < len(result); i++ {
     37 		if word(data, i*2) != result[i] {
     38 			t.Errorf("word error: i == %d", i)
     39 		}
     40 	}
     41 }
     42 
     43 func TestChecksum(t *testing.T) {
     44 	if !checksum(GoodSensorData) {
     45 		t.Fatal("Checksum Error")
     46 	}
     47 }
     48 
     49 func TestFailReadChipID(t *testing.T) {
     50 	bus := i2ctest.Playback{
     51 		// Chip ID detection read fail.
     52 		Ops:       []i2ctest.IO{},
     53 		DontPanic: true,
     54 	}
     55 	if _, err := New(&bus); err == nil {
     56 		t.Fatal("can't read chip ID")
     57 	}
     58 }
     59 
     60 func TestBadSensorData(t *testing.T) {
     61 	bus := i2ctest.Playback{
     62 		Ops: []i2ctest.IO{
     63 			// Bad sensor data
     64 			{Addr: 0x12, W: []byte{}, R: BadStartSensorData},
     65 		},
     66 	}
     67 	if _, err := New(&bus); err == nil {
     68 		t.Fatal("Bad sensor data Error")
     69 	}
     70 }
     71 
     72 func TestGoodSensorData(t *testing.T) {
     73 	bus := i2ctest.Playback{
     74 		Ops: []i2ctest.IO{
     75 			// Bad sensor data
     76 			{Addr: 0x12, W: []byte{}, R: GoodSensorData},
     77 		},
     78 	}
     79 	if _, err := New(&bus); err != nil {
     80 		t.Fatalf("Good sensor data Error: %s", err)
     81 	}
     82 }
     83 
     84 func TestReadSensorBadStart(t *testing.T) {
     85 	bus := i2ctest.Playback{
     86 		Ops: []i2ctest.IO{
     87 			// Bad start word sensor data
     88 			{Addr: 0x12, W: []byte{}, R: GoodSensorData},
     89 			{Addr: 0x12, W: []byte{}, R: BadStartSensorData},
     90 		},
     91 	}
     92 	d, err := New(&bus)
     93 	if err != nil {
     94 		t.Fatalf("Good sensor data Error: %s", err)
     95 	}
     96 	_, err = d.ReadSensor()
     97 	if err == nil {
     98 		t.Fatal("Read Sensor bad start Error")
     99 	}
    100 	if !strings.Contains(fmt.Sprintf("%s", err), "Bad start word") {
    101 		t.Fatalf("Not bad start Error: %s", err)
    102 	}
    103 }
    104 
    105 func TestReadSensorBadChecksum(t *testing.T) {
    106 	bus := i2ctest.Playback{
    107 		Ops: []i2ctest.IO{
    108 			// Bad checksum sensor data
    109 			{Addr: 0x12, W: []byte{}, R: GoodSensorData},
    110 			{Addr: 0x12, W: []byte{}, R: BadChecksumSensorData},
    111 		},
    112 	}
    113 	d, err := New(&bus)
    114 	if err != nil {
    115 		t.Fatalf("Good sensor data Error: %s", err)
    116 	}
    117 	_, err = d.ReadSensor()
    118 	if err == nil {
    119 		t.Fatal("Read Sensor bad checksum Error")
    120 	}
    121 	if !strings.Contains(fmt.Sprintf("%s", err), "Bad checksum") {
    122 		t.Fatalf("Not bad checksum Error: %s", err)
    123 	}
    124 }
    125 
    126 func TestReadSensor(t *testing.T) {
    127 	bus := i2ctest.Playback{
    128 		Ops: []i2ctest.IO{
    129 			// Bad checksum sensor data
    130 			{Addr: 0x12, W: []byte{}, R: GoodSensorData},
    131 			{Addr: 0x12, W: []byte{}, R: GoodSensorData},
    132 		},
    133 	}
    134 	d, err := New(&bus)
    135 	if err != nil {
    136 		t.Fatalf("Good sensor data Error: %s", err)
    137 	}
    138 	r, err := d.ReadSensor()
    139 	if err != nil {
    140 		t.Fatalf("Read Sensor Error: %s", err)
    141 	}
    142 	expected := Results{
    143 		CfPm1:    0,
    144 		CfPm2_5:  1,
    145 		CfPm10:   5,
    146 		EnvPm1:   0,
    147 		EnvPm2_5: 1,
    148 		EnvPm10:  5,
    149 		Cnt0_3:   126,
    150 		Cnt0_5:   42,
    151 		Cnt1:     15,
    152 		Cnt2_5:   9,
    153 		Cnt5:     3,
    154 		Cnt10:    3,
    155 		Version:  151,
    156 	}
    157 	if r != expected {
    158 		t.Fatalf("Read Sensor Data Error: %v", r)
    159 	}
    160 }