Air Quality Sensor PMSX003 plugin

Moderators: grovkillen, Stuntteam, TD-er

Post Reply
Message
Author
blindlight
New user
Posts: 1
Joined: 28 Nov 2016, 15:47

Air Quality Sensor PMSX003 plugin

#1 Post by blindlight » 09 Dec 2016, 09:35

hi,
The PMS x003 series are air quality sensors developed by Plantower (Chinese name 攀藤). The air pollution is an extremely serious problem in China.
So the first step I take is air quality monitoring. I make this plugin by hacking others. Here is the code:

Code: Select all

/*
  This plugin reads the Air Quality value(μg/m3) from PMSX003 Sensor
  DevicePin1 - is RX for ESP
  DevicePin2 - is TX for ESP
*/


#define PLUGIN_117
#define PLUGIN_ID_117         117
#define PLUGIN_NAME_117       "Air Quality Sensor PMSX003"
#define PLUGIN_VALUENAME1_117 "PM1.0"
#define PLUGIN_VALUENAME2_117 "PM2.5"
#define PLUGIN_VALUENAME3_117 "PM10"

boolean Plugin_117_init = false;

#include <SoftwareSerial.h>
SoftwareSerial *Plugin_117_PMSX003;

// 32-bytes CMD Air Quality read
byte pmsResp[32];    // 32 bytes bytes response

boolean Plugin_117(byte function, struct EventStruct *event, String& string)
{
  boolean success = false;

  switch (function)
  {

    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_117;
        Device[deviceCount].Type = DEVICE_TYPE_DUAL;
        Device[deviceCount].VType = SENSOR_TYPE_TRIPLE;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = false;
        Device[deviceCount].FormulaOption = true;
        Device[deviceCount].ValueCount = 3;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = true;
        Device[deviceCount].GlobalSyncOption = true;
        break;
      }

    case PLUGIN_GET_DEVICENAME:
      {
        string = F(PLUGIN_NAME_117);
        break;
      }

    case PLUGIN_GET_DEVICEVALUENAMES:
      {
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_117));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_117));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_117));
        break;
      }

    case PLUGIN_INIT:
      {
        Plugin_117_init = true;
        Plugin_117_PMSX003 = new SoftwareSerial(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex]);
        success = true;
        break;
      }

    case PLUGIN_READ:
      {

        if (Plugin_117_init)
        {
          Plugin_117_PMSX003->readBytes(pmsResp, 32);
          int i;
          unsigned int pm1_0 = 0;
          unsigned int pm2_5 = 0;
          unsigned int pm10 = 0;
          unsigned int crccal = 0;
          for (i = 0; i < 30; i++) crccal += pmsResp[i];
          unsigned int crc = (pmsResp[30] << 8) + pmsResp[31];

          if ( !(pmsResp[0] == 0x42 && pmsResp[1] == 0x4D && pmsResp[3] == 0x1C && crccal == crc ) ) {
            // && crccal == crc
            String log = F("PMSX003: CRC error: ");
            log += String(crc); log += " / "; log += String(crccal);
            addLog(LOG_LEVEL_ERROR, log);
            success = false;
            break;

          } else {

            pm1_0 = ((pmsResp[4] << 8) + pmsResp[5]);
            pm2_5 = ((pmsResp[6] << 8) + pmsResp[7]);
            pm10 = ((pmsResp[8] << 8) + pmsResp[9]);
          }

          UserVar[event->BaseVarIndex] = (float)pm1_0;
          UserVar[event->BaseVarIndex + 1] = (float)pm2_5;
          UserVar[event->BaseVarIndex + 2] = (float)pm10;
          String log = F("PMSX003: pm value: ");
          log += pm1_0;
          log += " / ";
          log += pm2_5;
          log += " / ";
          log += pm10;
          addLog(LOG_LEVEL_INFO, log);
          success = true;
          break;
        }
        break;
      }
  }
  return success;
}
it can output 3 values,pm1.0 pm2.5 pm10,when cf=1(whatever it means). Good enough for me.
there're 2 problems:
1. As you can see,I never figure out how GitHub works. So is there anyone can do me a favor by pulling this code. Thanks a lot.
2. There's no device in domoticz can read 3 values with one task. So if you wanna make it work in domoticz, you should separate it into 3 plugins like I do now.
sorry for my bad English.

Post Reply

Who is online

Users browsing this forum: No registered users and 89 guests