Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IKEA VINDRIKTNING AQI Sensor #510

Merged
merged 3 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/components/uart/drivers/ws_uart_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,16 @@ class ws_uart_drv {
@returns The UART device's unique identifier.
*/
/*******************************************************************************/
const char *getDeviceID() { return _deviceID; }
const char *getDriverID() { return _driverID; }

/*******************************************************************************/
/*!
@brief Sets the UART device's unique identifier.
@brief Sets the UART driver's identifer.
@param id
The UART device's unique identifier.
*/
/*******************************************************************************/
void setDriverID(const char *id) { _deviceID = id; }
void setDriverID(const char *id) { _driverID = strdup(id); }

/*******************************************************************************/
/*!
Expand Down Expand Up @@ -169,7 +169,7 @@ class ws_uart_drv {
private:
unsigned long
_prvPoll; ///< Last time the UART device was polled, in milliseconds
const char *_deviceID = nullptr; ///< UART device's ID
const char *_driverID = nullptr; ///< UART device's ID
};

#endif // WS_UART_DRV_H
69 changes: 35 additions & 34 deletions src/components/uart/drivers/ws_uart_drv_pm25aqi.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ class ws_uart_drv_pm25aqi : public ws_uart_drv {
: ws_uart_drv(swSerial, interval) {
_swSerial = swSerial;
pollingInterval = (unsigned long)interval;
// Set driver ID
setDriverID("pms5003");
};
#else
/*******************************************************************************/
Expand All @@ -57,8 +55,6 @@ class ws_uart_drv_pm25aqi : public ws_uart_drv {
: ws_uart_drv(hwSerial, interval) {
_hwSerial = hwSerial;
pollingInterval = (unsigned long)interval;
// Set driver ID
setDriverID("pms5003");
};
#endif // USE_SW_UART

Expand Down Expand Up @@ -148,37 +144,42 @@ class ws_uart_drv_pm25aqi : public ws_uart_drv {
wippersnapper_signal_v1_UARTResponse_init_zero;
msgUARTResponse.which_payload =
wippersnapper_signal_v1_UARTResponse_resp_uart_device_event_tag;
// We'll be sending back six sensor_events: pm10_standard, pm25_standard,
// pm100_standard, pm10_env, pm25_env, and pm100_env
msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 6;
// getDeviceID();
strcpy(msgUARTResponse.payload.resp_uart_device_event.device_id,
getDeviceID());

// Pack sensor data into UART response message
packUARTResponse(&msgUARTResponse, 0,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD,
(float)_data.pm10_standard);

packUARTResponse(&msgUARTResponse, 1,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD,
(float)_data.pm25_standard);

packUARTResponse(&msgUARTResponse, 2,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD,
(float)_data.pm100_standard);

packUARTResponse(&msgUARTResponse, 3,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_ENV,
(float)_data.pm10_env);

packUARTResponse(&msgUARTResponse, 4,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV,
(float)_data.pm25_env);

packUARTResponse(&msgUARTResponse, 5,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_ENV,
(float)_data.pm100_env);
getDriverID());

// check if driverID is pm1006
if (strcmp(getDriverID(), "pm1006") == 0) {
// PM1006 returns only PM2.5_ENV readings
msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 1;
packUARTResponse(&msgUARTResponse, 0,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV,
(float)_data.pm25_env);
} else {
msgUARTResponse.payload.resp_uart_device_event.sensor_event_count = 6;
packUARTResponse(&msgUARTResponse, 0,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_STD,
(float)_data.pm10_standard);

packUARTResponse(&msgUARTResponse, 1,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_STD,
(float)_data.pm25_standard);

packUARTResponse(&msgUARTResponse, 2,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_STD,
(float)_data.pm100_standard);

packUARTResponse(&msgUARTResponse, 3,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM10_ENV,
(float)_data.pm10_env);

packUARTResponse(&msgUARTResponse, 4,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM25_ENV,
(float)_data.pm25_env);

packUARTResponse(&msgUARTResponse, 5,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PM100_ENV,
(float)_data.pm100_env);
}

// Encode message data
uint8_t mqttBuffer[512] = {0};
Expand Down
33 changes: 24 additions & 9 deletions src/components/uart/ws_uart.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,24 +67,30 @@ void ws_uart::initUARTBus(
#ifdef USE_SW_UART
/*******************************************************************************/
/*!
@brief Initializes the pms5003 device driver using SoftwareSerial.
@brief Initializes the PM25AQI device driver using SoftwareSerial.
@param swSerial
Pointer to a SoftwareSerial instance.
@param pollingInterval
Polling interval for the pms5003 device.
@param device_id
Which PM25 device are we communicating with?
@returns True if pms5003 driver was successfully initialized, False
otherwise.
*/
/*******************************************************************************/
bool ws_uart::initUARTDevicePM25AQI(SoftwareSerial *swSerial,
int32_t pollingInterval) {
int32_t pollingInterval,
const char *device_id) {
if (_pm25aqi != nullptr) {
WS_DEBUG_PRINTLN(
"[ERROR, UART]: pms5003 driver already initialized on bus!");
return false;
}
WS_DEBUG_PRINTLN("[INFO, UART]: Initializing PM25AQI driver...");
_pm25aqi = new ws_uart_drv_pm25aqi(swSerial, pollingInterval);
_pm25aqi->setDriverID(
device_id); // Since the AdafruitPM25 driver works with both Adafruit PM
// sensor and PM1006, we need to set the driver ID
if (!_pm25aqi->begin()) {
WS_DEBUG_PRINTLN("[ERROR, UART]: PM25 driver initialization failed!");
return false;
Expand All @@ -101,18 +107,24 @@ bool ws_uart::initUARTDevicePM25AQI(SoftwareSerial *swSerial,
Pointer to a HardwareSerial instance.
@param pollingInterval
Polling interval for the pms5003 device.
@param device_id
Which PM25 device are we communicating with?
@returns True if pms5003 driver was successfully initialized, False
otherwise.
*/
/*******************************************************************************/
bool ws_uart::initUARTDevicePM25AQI(HardwareSerial *hwSerial,
int32_t pollingInterval) {
int32_t pollingInterval,
const char *device_id) {
if (_pm25aqi != nullptr) {
WS_DEBUG_PRINTLN(
"[ERROR, UART]: pms5003 driver already initialized on bus!");
return false;
}
_pm25aqi = new ws_uart_drv_pm25aqi(hwSerial, pollingInterval);
_pm25aqi->setDriverID(
device_id); // Since the AdafruitPM25 driver works with both Adafruit PM
// sensor and PM1006, we need to set the driver ID
if (!_pm25aqi->begin()) {
WS_DEBUG_PRINTLN("[ERROR, UART]: PM25 driver initialization failed!");
return false;
Expand Down Expand Up @@ -148,20 +160,23 @@ bool ws_uart::initUARTDevice(

// Do we already have a device with this ID?
for (ws_uart_drv *ptrUARTDriver : uartDrivers) {
if (strcmp(ptrUARTDriver->getDeviceID(), msgUARTRequest->device_id) == 0) {
if (strcmp(ptrUARTDriver->getDriverID(), msgUARTRequest->device_id) == 0) {
deinitUARTDevice(
msgUARTRequest->device_id); // Deinit the device and free resources
}
}

// Check which device type we are initializing
if (strcmp(msgUARTRequest->device_id, "pms5003") == 0) {
// Attempt to initialize PMS5003 driver with either SW or HW UART
if (strcmp(msgUARTRequest->device_id, "pms5003") == 0 ||
strcmp(msgUARTRequest->device_id, "pm1006") == 0) {
// Attempt to initialize Adafruit_PM25 driver with either SW or HW UART
#ifdef USE_SW_UART
if (!initUARTDevicePM25AQI(_swSerial, msgUARTRequest->polling_interval))
if (!initUARTDevicePM25AQI(_swSerial, msgUARTRequest->polling_interval,
msgUARTRequest->device_id))
return false;
#else
if (!initUARTDevicePM25AQI(_hwSerial, msgUARTRequest->polling_interval))
if (!initUARTDevicePM25AQI(_hwSerial, msgUARTRequest->polling_interval,
msgUARTRequest->device_id))
return false;
#endif
WS_DEBUG_PRINTLN("[INFO, UART]: PM25 UART driver initialized!");
Expand All @@ -185,7 +200,7 @@ void ws_uart::deinitUARTDevice(const char *device_id) {
// Iterate through the vector
while (iter != uartDrivers.end()) {
ws_uart_drv *ptrUARTDriver = *iter; // Get a pointer to the driver
if (strcmp(ptrUARTDriver->getDeviceID(), device_id) == 0) {
if (strcmp(ptrUARTDriver->getDriverID(), device_id) == 0) {
if (ptrUARTDriver == _pm25aqi) {
_pm25aqi = nullptr;
}
Expand Down
6 changes: 4 additions & 2 deletions src/components/uart/ws_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,11 @@ class ws_uart {
void update(); ///< Updates the UART device at every polling interval, must be
///< called by main app.
#ifdef USE_SW_UART
bool initUARTDevicePM25AQI(SoftwareSerial *swSerial, int32_t pollingInterval);
bool initUARTDevicePM25AQI(SoftwareSerial *swSerial, int32_t pollingInterval,
const char *device_id);
#else
bool initUARTDevicePM25AQI(HardwareSerial *hwSerial, int32_t pollingInterval);
bool initUARTDevicePM25AQI(HardwareSerial *hwSerial, int32_t pollingInterval,
const char *device_id);
#endif
private:
#ifdef USE_SW_UART
Expand Down