line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# You may distribute under the terms of either the GNU General Public License |
2
|
|
|
|
|
|
|
# or the Artistic License (the same terms as Perl itself) |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# (C) Paul Evans, 2020-2021 -- leonerd@leonerd.org.uk |
5
|
|
|
|
|
|
|
|
6
|
5
|
|
|
5
|
|
429369
|
use v5.26; |
|
5
|
|
|
|
|
62
|
|
7
|
5
|
|
|
5
|
|
521
|
use Object::Pad 0.57; |
|
5
|
|
|
|
|
9959
|
|
|
5
|
|
|
|
|
21
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
package Device::Chip::BME280 0.05; |
10
|
|
|
|
|
|
|
class Device::Chip::BME280 |
11
|
5
|
|
|
5
|
|
2710
|
:isa(Device::Chip::Base::RegisteredI2C); |
|
5
|
|
|
|
|
29181
|
|
|
5
|
|
|
|
|
166
|
|
12
|
|
|
|
|
|
|
|
13
|
5
|
|
|
5
|
|
2746
|
use Device::Chip::Sensor 0.23 -declare; |
|
5
|
|
|
|
|
11505
|
|
|
5
|
|
|
|
|
25
|
|
14
|
|
|
|
|
|
|
|
15
|
5
|
|
|
5
|
|
2740
|
use Data::Bitfield qw( bitfield enumfield boolfield ); |
|
5
|
|
|
|
|
9187
|
|
|
5
|
|
|
|
|
321
|
|
16
|
5
|
|
|
5
|
|
33
|
use Future::AsyncAwait; |
|
5
|
|
|
|
|
10
|
|
|
5
|
|
|
|
|
28
|
|
17
|
|
|
|
|
|
|
|
18
|
5
|
|
|
5
|
|
178
|
use utf8; |
|
5
|
|
|
|
|
11
|
|
|
5
|
|
|
|
|
19
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=encoding UTF-8 |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=head1 NAME |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
C - chip driver for F |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 SYNOPSIS |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
use Device::Chip::BME280; |
29
|
|
|
|
|
|
|
use Future::AsyncAwait; |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
my $chip = Device::Chip::BME280->new; |
32
|
|
|
|
|
|
|
await $chip->mount( Device::Chip::Adapter::...->new ); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
await $chip->change_config( |
35
|
|
|
|
|
|
|
OSRS_H => 4, |
36
|
|
|
|
|
|
|
OSRS_P => 4, |
37
|
|
|
|
|
|
|
OSRS_T => 4, |
38
|
|
|
|
|
|
|
MODE => "NORMAL", |
39
|
|
|
|
|
|
|
); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
my ( $pressure, $temperature, $humidity ) = await $chip->read_sensor; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
printf "Temperature=%.2fC ", $temperature; |
44
|
|
|
|
|
|
|
printf "Pressure=%dPa ", $pressure; |
45
|
|
|
|
|
|
|
printf "Humidity=%.2f%%\n", $humidity; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=head1 DESCRIPTION |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
This L subclass provides specific communication to a F |
50
|
|
|
|
|
|
|
F attached to a computer via an I²C adapter. |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
The reader is presumed to be familiar with the general operation of this chip; |
53
|
|
|
|
|
|
|
the documentation here will not attempt to explain or define chip-specific |
54
|
|
|
|
|
|
|
concepts or features, only the use of this module to access them. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=cut |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
method I2C_options |
59
|
4
|
|
|
4
|
0
|
1425
|
{ |
60
|
|
|
|
|
|
|
return ( |
61
|
4
|
|
|
|
|
26
|
addr => 0x76, |
62
|
|
|
|
|
|
|
max_bitrate => 400E3, |
63
|
|
|
|
|
|
|
); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
use constant { |
67
|
5
|
|
|
|
|
14294
|
REG_DIG_T1 => 0x88, |
68
|
|
|
|
|
|
|
REG_DIG_P1 => 0x8E, |
69
|
|
|
|
|
|
|
REG_DIG_H1 => 0xA1, |
70
|
|
|
|
|
|
|
REG_ID => 0xD0, |
71
|
|
|
|
|
|
|
REG_RESET => 0xE0, |
72
|
|
|
|
|
|
|
REG_DIG_H2 => 0xE1, |
73
|
|
|
|
|
|
|
REG_CTRL_HUM => 0xF2, |
74
|
|
|
|
|
|
|
REG_STATUS => 0xF3, |
75
|
|
|
|
|
|
|
REG_CTRL_MEAS => 0xF4, |
76
|
|
|
|
|
|
|
REG_CONFIG => 0xF5, |
77
|
|
|
|
|
|
|
REG_PRESS => 0xF7, # 24bit |
78
|
|
|
|
|
|
|
REG_TEMP => 0xFA, # 24bit |
79
|
|
|
|
|
|
|
REG_HUM => 0xFD, |
80
|
5
|
|
|
5
|
|
667
|
}; |
|
5
|
|
|
|
|
11
|
|
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
bitfield { format => "bytes-LE" }, config => |
83
|
|
|
|
|
|
|
# REG_CTRL_HUM |
84
|
|
|
|
|
|
|
OSRS_H => enumfield( 0, qw( SKIP 1 2 4 8 16 16 16 ) ), |
85
|
|
|
|
|
|
|
# REG_CTRL_MEAS |
86
|
|
|
|
|
|
|
MODE => enumfield( 2*8+0, qw( SLEEP FORCED FORCED NORMAL ) ), |
87
|
|
|
|
|
|
|
OSRS_P => enumfield( 2*8+2, qw( SKIP 1 2 4 8 16 16 16 ) ), |
88
|
|
|
|
|
|
|
OSRS_T => enumfield( 2*8+5, qw( SKIP 1 2 4 8 16 16 16 ) ), |
89
|
|
|
|
|
|
|
# REG_CONFIG |
90
|
|
|
|
|
|
|
SPI3W_EN => boolfield( 3*8+0 ), |
91
|
|
|
|
|
|
|
FILTER => enumfield( 3*8+2, qw( OFF 2 4 8 16 16 16 16 ) ), |
92
|
|
|
|
|
|
|
T_SB => enumfield( 3*8+5, qw( 0.5 62.5 125 250 500 1000 10 20 ) ); |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=head1 METHODS |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
The following methods documented in an C expression return L |
97
|
|
|
|
|
|
|
instances. |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=cut |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=head2 read_id |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
$id = await $chip->read_id |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
Returns the chip ID. |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=cut |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
async method read_id |
110
|
1
|
|
|
|
|
3
|
{ |
111
|
1
|
|
|
|
|
6
|
return unpack "C", await $self->read_reg( REG_ID, 1 ); |
112
|
1
|
|
|
1
|
1
|
261
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=head2 read_config |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
$config = await $chip->read_config |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
Returns a C reference containing the chip config, using fields named |
119
|
|
|
|
|
|
|
from the data sheet. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
FILTER => OFF | 2 | 4 | 8 | 16 |
122
|
|
|
|
|
|
|
MODE => SLEEP | FORCED | NORMAL |
123
|
|
|
|
|
|
|
OSRS_H => SKIP | 1 | 2 | 4 | 8 | 16 |
124
|
|
|
|
|
|
|
OSRS_P => SKIP | 1 | 2 | 4 | 8 | 16 |
125
|
|
|
|
|
|
|
OSRS_T => SKIP | 1 | 2 | 4 | 8 | 16 |
126
|
|
|
|
|
|
|
SPI3W_EN => 0 | 1 |
127
|
|
|
|
|
|
|
T_SB => 0.5 | 10 | 20 | 62.5 | 125 | 250 | 500 | 1000 |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=cut |
130
|
|
|
|
|
|
|
|
131
|
5
|
|
|
|
|
5
|
async method read_config () |
|
5
|
|
|
|
|
7
|
|
132
|
5
|
|
|
|
|
14
|
{ |
133
|
5
|
|
|
|
|
19
|
my $bytes = await $self->cached_read_reg( REG_CTRL_HUM, 4 ); |
134
|
|
|
|
|
|
|
|
135
|
5
|
|
|
|
|
17736
|
return { unpack_config( $bytes ) }; |
136
|
5
|
|
|
5
|
1
|
3082
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=head2 change_config |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
await $chip->change_config( %changes ) |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
Writes updates to the configuration registers. |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
Note that these two methods use a cache of configuration bytes to make |
145
|
|
|
|
|
|
|
subsequent modifications more efficient. |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=cut |
148
|
|
|
|
|
|
|
|
149
|
1
|
|
|
|
|
3
|
async method change_config ( %changes ) |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
1
|
|
150
|
1
|
|
|
|
|
3
|
{ |
151
|
1
|
|
|
|
|
3
|
my $config = await $self->read_config; |
152
|
|
|
|
|
|
|
|
153
|
1
|
|
|
|
|
108
|
my $bytes = pack_config( %$config, %changes ); |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# Don't write REG_STATUS |
156
|
1
|
|
|
|
|
181
|
await $self->cached_write_reg( REG_CTRL_HUM, substr( $bytes, 0, 1 ) ); |
157
|
1
|
|
|
|
|
1607
|
await $self->cached_write_reg( REG_CTRL_MEAS, substr( $bytes, 2, 2 ) ); |
158
|
1
|
|
|
1
|
1
|
2581
|
} |
159
|
|
|
|
|
|
|
|
160
|
0
|
|
|
|
|
0
|
async method initialize_sensors () |
|
0
|
|
|
|
|
0
|
|
161
|
0
|
|
|
|
|
0
|
{ |
162
|
0
|
|
|
|
|
0
|
await $self->change_config( |
163
|
|
|
|
|
|
|
MODE => "NORMAL", |
164
|
|
|
|
|
|
|
OSRS_H => 4, |
165
|
|
|
|
|
|
|
OSRS_P => 4, |
166
|
|
|
|
|
|
|
OSRS_T => 4, |
167
|
|
|
|
|
|
|
FILTER => 4, |
168
|
|
|
|
|
|
|
); |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# First read after startup contains junk values |
171
|
0
|
|
|
|
|
0
|
await $self->read_sensor; |
172
|
0
|
|
|
0
|
0
|
0
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=head2 read_status |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
$status = await $chip->read_status; |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=cut |
179
|
|
|
|
|
|
|
|
180
|
0
|
|
|
|
|
0
|
async method read_status () |
|
0
|
|
|
|
|
0
|
|
181
|
0
|
|
|
|
|
0
|
{ |
182
|
0
|
|
|
|
|
0
|
my $byte = await $self->read_reg( REG_STATUS, 1 ); |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
return { |
185
|
0
|
|
|
|
|
0
|
MEASURING => !!( $byte & (1<<3) ), |
186
|
|
|
|
|
|
|
IM_UPDATE => !!( $byte & (1<<0) ), |
187
|
|
|
|
|
|
|
}; |
188
|
0
|
|
|
0
|
1
|
0
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head2 read_raw |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
( $adc_P, $adc_T, $adc_H ) = await $chip->read_raw |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
Returns three integers containing the raw ADC reading values from the sensor. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
This method is mostly for testing or internal purposes only. For converted |
197
|
|
|
|
|
|
|
sensor readings in real-world units you want to use L. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=cut |
200
|
|
|
|
|
|
|
|
201
|
8
|
|
|
|
|
8
|
async method read_raw () |
|
8
|
|
|
|
|
10
|
|
202
|
8
|
|
|
|
|
14
|
{ |
203
|
8
|
|
|
|
|
23
|
my ( $bytesP, $bytesT, $bytesH ) = unpack "a3 a3 a2", |
204
|
|
|
|
|
|
|
await $self->read_reg( REG_PRESS, 8 ); |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
return ( |
207
|
7
|
|
|
|
|
13001
|
unpack( "L>", "\x00" . $bytesP ) >> 4, |
208
|
|
|
|
|
|
|
unpack( "L>", "\x00" . $bytesT ) >> 4, |
209
|
|
|
|
|
|
|
unpack( "S>", $bytesH ), |
210
|
|
|
|
|
|
|
); |
211
|
8
|
|
|
8
|
1
|
251
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# Compensation formulae directly from BME280 datasheet section 8.1 |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
has $_t_fine; |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
has @_dig_T; |
218
|
|
|
|
|
|
|
|
219
|
10
|
|
|
|
|
12
|
async method _compensate_temperature ( $adc_T ) |
|
10
|
|
|
|
|
12
|
|
|
10
|
|
|
|
|
13
|
|
220
|
10
|
|
|
|
|
26
|
{ |
221
|
10
|
100
|
|
|
|
26
|
@_dig_T or |
222
|
|
|
|
|
|
|
@_dig_T = ( undef, unpack "S< s< s<", await $self->read_reg( REG_DIG_T1, 6 ) ); |
223
|
|
|
|
|
|
|
|
224
|
10
|
|
|
|
|
2415
|
my $var1 = ($adc_T / 16384 - $_dig_T[1] / 1024) * $_dig_T[2]; |
225
|
10
|
|
|
|
|
28
|
my $var2 = ($adc_T / 131072 - $_dig_T[1] / 8192) ** 2 * $_dig_T[3]; |
226
|
|
|
|
|
|
|
|
227
|
10
|
|
|
|
|
18
|
$_t_fine = int( $var1 + $var2 ); |
228
|
10
|
|
|
|
|
15
|
my $T = ( $var1 + $var2 ) / 5120.0; |
229
|
10
|
|
|
|
|
52
|
return $T; |
230
|
10
|
|
|
10
|
|
16
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
has @_dig_P; |
233
|
|
|
|
|
|
|
|
234
|
4
|
|
|
|
|
5
|
async method _compensate_pressure ( $adc_P ) |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
5
|
|
235
|
4
|
|
|
|
|
11
|
{ |
236
|
4
|
100
|
|
|
|
14
|
@_dig_P or |
237
|
|
|
|
|
|
|
@_dig_P = ( undef, unpack "S< s< s< s< s< s< s< s< s<", await $self->read_reg( REG_DIG_P1, 18 ) ); |
238
|
|
|
|
|
|
|
|
239
|
4
|
|
|
|
|
2423
|
my $var1 = ($_t_fine / 2) - 64000; |
240
|
4
|
|
|
|
|
11
|
my $var2 = $var1 * $var1 * $_dig_P[6] / 32768; |
241
|
4
|
|
|
|
|
9
|
$var2 = $var2 + $var1 * $_dig_P[5] * 2; |
242
|
4
|
|
|
|
|
7
|
$var2 = ($var2 / 4) + ($_dig_P[4] * 65536); |
243
|
4
|
|
|
|
|
13
|
$var1 = ($_dig_P[3] * $var1 * $var1 / 524288 + $_dig_P[2] * $var1) / 524288; |
244
|
4
|
|
|
|
|
7
|
$var1 = (1 + $var1 / 32768) * $_dig_P[1]; |
245
|
4
|
50
|
|
|
|
13
|
return 0 if $var1 == 0; # avoid exception caused by divide-by-zero |
246
|
4
|
|
|
|
|
7
|
my $P = 1048576 - $adc_P; |
247
|
4
|
|
|
|
|
9
|
$P = ($P - ($var2 / 4096)) * 6250 / $var1; |
248
|
4
|
|
|
|
|
7
|
$var1 = $_dig_P[9] * $P * $P / 2147483648; |
249
|
4
|
|
|
|
|
7
|
$var2 = $P * $_dig_P[8] / 32768; |
250
|
4
|
|
|
|
|
8
|
$P = $P + ($var1 + $var2 + $_dig_P[7]) / 16; |
251
|
4
|
|
|
|
|
16
|
return $P; |
252
|
4
|
|
|
4
|
|
6
|
} |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
has @_dig_H; |
255
|
|
|
|
|
|
|
|
256
|
4
|
|
|
|
|
5
|
async method _compensate_humidity ( $adc_H ) |
|
4
|
|
|
|
|
5
|
|
|
4
|
|
|
|
|
6
|
|
257
|
4
|
|
|
|
|
10
|
{ |
258
|
4
|
100
|
|
|
|
11
|
unless( @_dig_H ) { |
259
|
2
|
|
|
|
|
7
|
@_dig_H = ( |
260
|
|
|
|
|
|
|
undef, |
261
|
|
|
|
|
|
|
unpack( "C", await $self->read_reg( REG_DIG_H1, 1 ) ), |
262
|
|
|
|
|
|
|
unpack( "s< C ccc c", await $self->read_reg( REG_DIG_H2, 7 ) ), |
263
|
|
|
|
|
|
|
); |
264
|
|
|
|
|
|
|
# Reshape the two 12bit values |
265
|
2
|
|
|
|
|
4645
|
my ( $b0, $b1, $b2 ) = splice @_dig_H, 4, 3; |
266
|
2
|
|
|
|
|
11
|
splice @_dig_H, 4, 0, |
267
|
|
|
|
|
|
|
( $b0 << 4 | $b1 & 0x0F ), # H4 |
268
|
|
|
|
|
|
|
( $b1 >> 4 | $b2 << 4 ); # H5 |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
|
271
|
4
|
|
|
|
|
8
|
my $var_H = $_t_fine - 76800; |
272
|
4
|
|
|
|
|
20
|
$var_H = ($adc_H - ($_dig_H[4] * 64.0 + $_dig_H[5] / 16384.0 * $var_H)) * |
273
|
|
|
|
|
|
|
($_dig_H[2] / 65536.0 * (1.0 + $_dig_H[6] / 67108864.0 * $var_H * (1.0 + $_dig_H[3] / 67108864.0 * $var_H))); |
274
|
4
|
|
|
|
|
11
|
$var_H = $var_H * (1.0 - $_dig_H[1] * $var_H / 524288.0); |
275
|
|
|
|
|
|
|
|
276
|
4
|
50
|
|
|
|
11
|
return 0 if $var_H < 0; |
277
|
4
|
50
|
|
|
|
9
|
return 100 if $var_H > 100; |
278
|
4
|
|
|
|
|
18
|
return $var_H; |
279
|
4
|
|
|
4
|
|
67
|
} |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
=head2 read_sensor |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
( $pressure, $temperature, $humidity ) = await $chip->read_sensor |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
Returns the sensor readings appropriately converted into units of Pascals for |
286
|
|
|
|
|
|
|
pressure, degrees Celcius for temperature, and percentage relative for |
287
|
|
|
|
|
|
|
humidity. |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
=cut |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
async method read_sensor |
292
|
1
|
|
|
|
|
3
|
{ |
293
|
1
|
|
|
|
|
3
|
my ( $adc_P, $adc_T, $adc_H ) = await $self->read_raw; |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
# Must do temperature first |
296
|
1
|
|
|
|
|
61
|
my $T = await $self->_compensate_temperature( $adc_T ); |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
return ( |
299
|
1
|
|
|
|
|
59
|
await $self->_compensate_pressure( $adc_P ), |
300
|
|
|
|
|
|
|
$T, |
301
|
|
|
|
|
|
|
await $self->_compensate_humidity( $adc_H ), |
302
|
|
|
|
|
|
|
); |
303
|
1
|
|
|
1
|
1
|
3281
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
has $_pending_read_f; |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
method _next_read |
308
|
12
|
|
|
12
|
|
21
|
{ |
309
|
|
|
|
|
|
|
return $_pending_read_f //= |
310
|
12
|
|
66
|
6
|
|
41
|
$self->read_raw->on_ready(sub { undef $_pending_read_f }); |
|
6
|
|
|
|
|
536
|
|
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
declare_sensor pressure => |
314
|
|
|
|
|
|
|
method => async method { |
315
|
|
|
|
|
|
|
my ( $rawP, $rawT, undef ) = await $self->_next_read; |
316
|
|
|
|
|
|
|
$self->_compensate_temperature( $rawT ); |
317
|
|
|
|
|
|
|
return await $self->_compensate_pressure( $rawP ); |
318
|
|
|
|
|
|
|
}, |
319
|
|
|
|
|
|
|
units => "pascals", |
320
|
|
|
|
|
|
|
sanity_bounds => [ 80_000, 120_000 ], |
321
|
|
|
|
|
|
|
precision => 0; |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
declare_sensor temperature => |
324
|
|
|
|
|
|
|
method => async method { |
325
|
|
|
|
|
|
|
my ( undef, $rawT, undef ) = await $self->_next_read; |
326
|
|
|
|
|
|
|
return await $self->_compensate_temperature( $rawT ); |
327
|
|
|
|
|
|
|
}, |
328
|
|
|
|
|
|
|
units => "°C", |
329
|
|
|
|
|
|
|
sanity_bounds => [ -50, 80 ], |
330
|
|
|
|
|
|
|
precision => 2; |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
declare_sensor humidity => |
333
|
|
|
|
|
|
|
method => async method { |
334
|
|
|
|
|
|
|
my ( undef, $rawT, $rawH ) = await $self->_next_read; |
335
|
|
|
|
|
|
|
$self->_compensate_temperature( $rawT ); |
336
|
|
|
|
|
|
|
return await $self->_compensate_humidity( $rawH ); |
337
|
|
|
|
|
|
|
}, |
338
|
|
|
|
|
|
|
units => "%RH", |
339
|
|
|
|
|
|
|
sanity_bounds => [ -1, 101 ], # give it slight headroom beyond the 0-100 range for rounding errors/etc |
340
|
|
|
|
|
|
|
precision => 2; |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=head1 AUTHOR |
343
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
Paul Evans |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=cut |
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
0x55AA; |