-
Notifications
You must be signed in to change notification settings - Fork 4.9k
/
Copy pathxsns_104_pmsa003i.ino
155 lines (131 loc) · 5.27 KB
/
xsns_104_pmsa003i.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
xsns_104_pmsa003i.ino - PMSA003I air quality sensor support for Tasmota
Copyright (C) 2023 Jean-Pierre Deschamps
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_I2C
#ifdef USE_PMSA003I
/*********************************************************************************************\
* PMSA003I - PM2.5 Air Quality Sensor with I2C Interface
*
* Source: Adafruit Industries
* Adaption for TASMOTA: Jean-Pierre Deschamps
*
* I2C Address: 0x12
\*********************************************************************************************/
#define XSNS_104 104
#define XI2C_78 78 // See I2CDEVICES.md
#define PMSA003I_ADDRESS 0x12
#ifndef PMSA003I_WARMUP_DELAY
#define PMSA003I_WARMUP_DELAY 30 // Ignore PMSA003I readings for XX seconds after start
#endif
#include "Adafruit_PM25AQI.h"
struct PMSA003I {
bool type = false;
bool ready = false;
uint8_t warmup_counter; // count for warmup
PM25_AQI_Data data;
Adafruit_PM25AQI aqi = Adafruit_PM25AQI();
} Pmsa003i;
/********************************************************************************************/
void pmsa003i_Init(void)
{
if (!I2cSetDevice(PMSA003I_ADDRESS)) {
// AddLog(LOG_LEVEL_DEBUG, PSTR("PMS: " D_JSON_I2CSCAN_NO_DEVICES_FOUND));
return;
}
if (Pmsa003i.aqi.begin_I2C()) {
Pmsa003i.type = true;
Pmsa003i.warmup_counter = PMSA003I_WARMUP_DELAY;
I2cSetActiveFound(PMSA003I_ADDRESS, "PMSA003I");
// } else {
// AddLog(LOG_LEVEL_DEBUG, PSTR("PMS: " "Begin_I2C failed"));
}
}
void Pmsa003iUpdate(void)
{
if (Pmsa003i.warmup_counter > 0) {
Pmsa003i.warmup_counter--;
return;
}
Pmsa003i.ready = false;
PM25_AQI_Data data;
if (! Pmsa003i.aqi.read(&data)) { // Could not read from AQI
return;
}
Pmsa003i.data = data;
Pmsa003i.ready = true;
}
void Pmsa003iShow(bool json) {
if (Pmsa003i.ready) {
char types[10];
strcpy_P(types, PSTR("PMSA003I"));
if (json) {
ResponseAppend_P(PSTR(",\"%s\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d,\"PB0.3\":%d,\"PB0.5\":%d,\"PB1\":%d,\"PB2.5\":%d,\"PB5\":%d,\"PB10\":%d}"),
types,
Pmsa003i.data.pm10_standard, Pmsa003i.data.pm25_standard, Pmsa003i.data.pm100_standard,
Pmsa003i.data.pm10_env, Pmsa003i.data.pm25_env, Pmsa003i.data.pm100_env,
Pmsa003i.data.particles_03um, Pmsa003i.data.particles_05um, Pmsa003i.data.particles_10um, Pmsa003i.data.particles_25um, Pmsa003i.data.particles_50um, Pmsa003i.data.particles_100um);
#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) {
DomoticzSensor(DZ_COUNT, Pmsa003i.data.pm10_env); // PM1
DomoticzSensor(DZ_VOLTAGE, Pmsa003i.data.pm25_env); // PM2.5
DomoticzSensor(DZ_CURRENT, Pmsa003i.data.pm100_env); // PM10
}
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
// WSContentSend_PD(HTTP_SNS_STANDARD_CONCENTRATION, types, "1", Pmsa003i.data.pm10_standard);
// WSContentSend_PD(HTTP_SNS_STANDARD_CONCENTRATION, types, "2.5", Pmsa003i.data.pm25_standard);
// WSContentSend_PD(HTTP_SNS_STANDARD_CONCENTRATION, types, "10", Pmsa003i.data.pm100_standard);
WSContentSend_PD(HTTP_SNS_ENVIRONMENTAL_CONCENTRATION, types, "1", Pmsa003i.data.pm10_env);
WSContentSend_PD(HTTP_SNS_ENVIRONMENTAL_CONCENTRATION, types, "2.5", Pmsa003i.data.pm25_env);
WSContentSend_PD(HTTP_SNS_ENVIRONMENTAL_CONCENTRATION, types, "10", Pmsa003i.data.pm100_env);
WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "0.3", Pmsa003i.data.particles_03um);
WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "0.5", Pmsa003i.data.particles_05um);
WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "1", Pmsa003i.data.particles_10um);
WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "2.5", Pmsa003i.data.particles_25um);
WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "5", Pmsa003i.data.particles_50um);
WSContentSend_PD(HTTP_SNS_PARTICALS_BEYOND, types, "10", Pmsa003i.data.particles_100um);
#endif
}
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xsns104(uint32_t function)
{
if (!I2cEnabled(XI2C_78)) { return false; }
bool result = false;
if (FUNC_INIT == function) {
pmsa003i_Init();
}
else if (Pmsa003i.type) {
switch (function) {
case FUNC_EVERY_SECOND:
Pmsa003iUpdate();
break;
case FUNC_JSON_APPEND:
Pmsa003iShow(1);
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
Pmsa003iShow(0);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_PMSA003I
#endif // USE_I2C