Skip to content

Commit ae916c7

Browse files
authored
Merge pull request #510 from brentru/add-ikea-pm-sensor
Add IKEA VINDRIKTNING AQI Sensor
2 parents ad6ac41 + ba3f860 commit ae916c7

File tree

4 files changed

+67
-49
lines changed

4 files changed

+67
-49
lines changed

src/components/uart/drivers/ws_uart_drv.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,16 @@ class ws_uart_drv {
8989
@returns The UART device's unique identifier.
9090
*/
9191
/*******************************************************************************/
92-
const char *getDeviceID() { return _deviceID; }
92+
const char *getDriverID() { return _driverID; }
9393

9494
/*******************************************************************************/
9595
/*!
96-
@brief Sets the UART device's unique identifier.
96+
@brief Sets the UART driver's identifer.
9797
@param id
9898
The UART device's unique identifier.
9999
*/
100100
/*******************************************************************************/
101-
void setDriverID(const char *id) { _deviceID = id; }
101+
void setDriverID(const char *id) { _driverID = strdup(id); }
102102

103103
/*******************************************************************************/
104104
/*!
@@ -169,7 +169,7 @@ class ws_uart_drv {
169169
private:
170170
unsigned long
171171
_prvPoll; ///< Last time the UART device was polled, in milliseconds
172-
const char *_deviceID = nullptr; ///< UART device's ID
172+
const char *_driverID = nullptr; ///< UART device's ID
173173
};
174174

175175
#endif // WS_UART_DRV_H

src/components/uart/drivers/ws_uart_drv_pm25aqi.h

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ class ws_uart_drv_pm25aqi : public ws_uart_drv {
4040
: ws_uart_drv(swSerial, interval) {
4141
_swSerial = swSerial;
4242
pollingInterval = (unsigned long)interval;
43-
// Set driver ID
44-
setDriverID("pms5003");
4543
};
4644
#else
4745
/*******************************************************************************/
@@ -57,8 +55,6 @@ class ws_uart_drv_pm25aqi : public ws_uart_drv {
5755
: ws_uart_drv(hwSerial, interval) {
5856
_hwSerial = hwSerial;
5957
pollingInterval = (unsigned long)interval;
60-
// Set driver ID
61-
setDriverID("pms5003");
6258
};
6359
#endif // USE_SW_UART
6460

@@ -148,37 +144,42 @@ class ws_uart_drv_pm25aqi : public ws_uart_drv {
148144
wippersnapper_signal_v1_UARTResponse_init_zero;
149145
msgUARTResponse.which_payload =
150146
wippersnapper_signal_v1_UARTResponse_resp_uart_device_event_tag;
151-
// We'll be sending back six sensor_events: pm10_standard, pm25_standard,
152-
// pm100_standard, pm10_env, pm25_env, and pm100_env
153-
msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 6;
154-
// getDeviceID();
155147
strcpy(msgUARTResponse.payload.resp_uart_device_event.device_id,
156-
getDeviceID());
157-
158-
// Pack sensor data into UART response message
159-
packUARTResponse(&msgUARTResponse, 0,
160-
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD,
161-
(float)_data.pm10_standard);
162-
163-
packUARTResponse(&msgUARTResponse, 1,
164-
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD,
165-
(float)_data.pm25_standard);
166-
167-
packUARTResponse(&msgUARTResponse, 2,
168-
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD,
169-
(float)_data.pm100_standard);
170-
171-
packUARTResponse(&msgUARTResponse, 3,
172-
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_ENV,
173-
(float)_data.pm10_env);
174-
175-
packUARTResponse(&msgUARTResponse, 4,
176-
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV,
177-
(float)_data.pm25_env);
178-
179-
packUARTResponse(&msgUARTResponse, 5,
180-
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_ENV,
181-
(float)_data.pm100_env);
148+
getDriverID());
149+
150+
// check if driverID is pm1006
151+
if (strcmp(getDriverID(), "pm1006") == 0) {
152+
// PM1006 returns only PM2.5_ENV readings
153+
msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 1;
154+
packUARTResponse(&msgUARTResponse, 0,
155+
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV,
156+
(float)_data.pm25_env);
157+
} else {
158+
msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 6;
159+
packUARTResponse(&msgUARTResponse, 0,
160+
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD,
161+
(float)_data.pm10_standard);
162+
163+
packUARTResponse(&msgUARTResponse, 1,
164+
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD,
165+
(float)_data.pm25_standard);
166+
167+
packUARTResponse(&msgUARTResponse, 2,
168+
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD,
169+
(float)_data.pm100_standard);
170+
171+
packUARTResponse(&msgUARTResponse, 3,
172+
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_ENV,
173+
(float)_data.pm10_env);
174+
175+
packUARTResponse(&msgUARTResponse, 4,
176+
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV,
177+
(float)_data.pm25_env);
178+
179+
packUARTResponse(&msgUARTResponse, 5,
180+
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_ENV,
181+
(float)_data.pm100_env);
182+
}
182183

183184
// Encode message data
184185
uint8_t mqttBuffer[512] = {0};

src/components/uart/ws_uart.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,24 +67,30 @@ void ws_uart::initUARTBus(
6767
#ifdef USE_SW_UART
6868
/*******************************************************************************/
6969
/*!
70-
@brief Initializes the pms5003 device driver using SoftwareSerial.
70+
@brief Initializes the PM25AQI device driver using SoftwareSerial.
7171
@param swSerial
7272
Pointer to a SoftwareSerial instance.
7373
@param pollingInterval
7474
Polling interval for the pms5003 device.
75+
@param device_id
76+
Which PM25 device are we communicating with?
7577
@returns True if pms5003 driver was successfully initialized, False
7678
otherwise.
7779
*/
7880
/*******************************************************************************/
7981
bool ws_uart::initUARTDevicePM25AQI(SoftwareSerial *swSerial,
80-
int32_t pollingInterval) {
82+
int32_t pollingInterval,
83+
const char *device_id) {
8184
if (_pm25aqi != nullptr) {
8285
WS_DEBUG_PRINTLN(
8386
"[ERROR, UART]: pms5003 driver already initialized on bus!");
8487
return false;
8588
}
8689
WS_DEBUG_PRINTLN("[INFO, UART]: Initializing PM25AQI driver...");
8790
_pm25aqi = new ws_uart_drv_pm25aqi(swSerial, pollingInterval);
91+
_pm25aqi->setDriverID(
92+
device_id); // Since the AdafruitPM25 driver works with both Adafruit PM
93+
// sensor and PM1006, we need to set the driver ID
8894
if (!_pm25aqi->begin()) {
8995
WS_DEBUG_PRINTLN("[ERROR, UART]: PM25 driver initialization failed!");
9096
return false;
@@ -101,18 +107,24 @@ bool ws_uart::initUARTDevicePM25AQI(SoftwareSerial *swSerial,
101107
Pointer to a HardwareSerial instance.
102108
@param pollingInterval
103109
Polling interval for the pms5003 device.
110+
@param device_id
111+
Which PM25 device are we communicating with?
104112
@returns True if pms5003 driver was successfully initialized, False
105113
otherwise.
106114
*/
107115
/*******************************************************************************/
108116
bool ws_uart::initUARTDevicePM25AQI(HardwareSerial *hwSerial,
109-
int32_t pollingInterval) {
117+
int32_t pollingInterval,
118+
const char *device_id) {
110119
if (_pm25aqi != nullptr) {
111120
WS_DEBUG_PRINTLN(
112121
"[ERROR, UART]: pms5003 driver already initialized on bus!");
113122
return false;
114123
}
115124
_pm25aqi = new ws_uart_drv_pm25aqi(hwSerial, pollingInterval);
125+
_pm25aqi->setDriverID(
126+
device_id); // Since the AdafruitPM25 driver works with both Adafruit PM
127+
// sensor and PM1006, we need to set the driver ID
116128
if (!_pm25aqi->begin()) {
117129
WS_DEBUG_PRINTLN("[ERROR, UART]: PM25 driver initialization failed!");
118130
return false;
@@ -148,20 +160,23 @@ bool ws_uart::initUARTDevice(
148160

149161
// Do we already have a device with this ID?
150162
for (ws_uart_drv *ptrUARTDriver : uartDrivers) {
151-
if (strcmp(ptrUARTDriver->getDeviceID(), msgUARTRequest->device_id) == 0) {
163+
if (strcmp(ptrUARTDriver->getDriverID(), msgUARTRequest->device_id) == 0) {
152164
deinitUARTDevice(
153165
msgUARTRequest->device_id); // Deinit the device and free resources
154166
}
155167
}
156168

157169
// Check which device type we are initializing
158-
if (strcmp(msgUARTRequest->device_id, "pms5003") == 0) {
159-
// Attempt to initialize PMS5003 driver with either SW or HW UART
170+
if (strcmp(msgUARTRequest->device_id, "pms5003") == 0 ||
171+
strcmp(msgUARTRequest->device_id, "pm1006") == 0) {
172+
// Attempt to initialize Adafruit_PM25 driver with either SW or HW UART
160173
#ifdef USE_SW_UART
161-
if (!initUARTDevicePM25AQI(_swSerial, msgUARTRequest->polling_interval))
174+
if (!initUARTDevicePM25AQI(_swSerial, msgUARTRequest->polling_interval,
175+
msgUARTRequest->device_id))
162176
return false;
163177
#else
164-
if (!initUARTDevicePM25AQI(_hwSerial, msgUARTRequest->polling_interval))
178+
if (!initUARTDevicePM25AQI(_hwSerial, msgUARTRequest->polling_interval,
179+
msgUARTRequest->device_id))
165180
return false;
166181
#endif
167182
WS_DEBUG_PRINTLN("[INFO, UART]: PM25 UART driver initialized!");
@@ -185,7 +200,7 @@ void ws_uart::deinitUARTDevice(const char *device_id) {
185200
// Iterate through the vector
186201
while (iter != uartDrivers.end()) {
187202
ws_uart_drv *ptrUARTDriver = *iter; // Get a pointer to the driver
188-
if (strcmp(ptrUARTDriver->getDeviceID(), device_id) == 0) {
203+
if (strcmp(ptrUARTDriver->getDriverID(), device_id) == 0) {
189204
if (ptrUARTDriver == _pm25aqi) {
190205
_pm25aqi = nullptr;
191206
}

src/components/uart/ws_uart.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,11 @@ class ws_uart {
4444
void update(); ///< Updates the UART device at every polling interval, must be
4545
///< called by main app.
4646
#ifdef USE_SW_UART
47-
bool initUARTDevicePM25AQI(SoftwareSerial *swSerial, int32_t pollingInterval);
47+
bool initUARTDevicePM25AQI(SoftwareSerial *swSerial, int32_t pollingInterval,
48+
const char *device_id);
4849
#else
49-
bool initUARTDevicePM25AQI(HardwareSerial *hwSerial, int32_t pollingInterval);
50+
bool initUARTDevicePM25AQI(HardwareSerial *hwSerial, int32_t pollingInterval,
51+
const char *device_id);
5052
#endif
5153
private:
5254
#ifdef USE_SW_UART

0 commit comments

Comments
 (0)