1#include "../include/sensor/sensor.h"
17#define SENSOR_PLUGIN_EXPORT __declspec(dllexport)
19#define SENSOR_PLUGIN_EXPORT
22static void fill_timestamp(
char *buf,
size_t len) {
23 time_t now = time(NULL);
24 const struct tm *ptm = localtime(&now);
26 snprintf(buf, len,
"1970-01-01 00:00:00");
29 if (strftime(buf, len,
"%Y-%m-%d %H:%M:%S", ptm) == 0) {
30 snprintf(buf, len,
"1970-01-01 00:00:00");
34static int mhz19_init(
void) {
36 printf(
"MH-Z19 plugin initialized (real UART on Linux/macOS if available; fallback mock).\n");
38 printf(
"MH-Z19 plugin initialized (mock on Windows).\n");
44static int open_serial_9600(
const char *device) {
45 int fd = open(device, O_RDWR | O_NOCTTY | O_SYNC);
49 memset(&tty, 0,
sizeof(tty));
50 if (tcgetattr(fd, &tty) != 0) {
54 cfsetospeed(&tty, B9600);
55 cfsetispeed(&tty, B9600);
56 tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
57 tty.c_iflag &= ~(IGNBRK | IXON | IXOFF | IXANY);
62 tty.c_cflag |= (CLOCAL | CREAD);
63 tty.c_cflag &= ~(PARENB | PARODD | CSTOPB | CRTSCTS);
64 if (tcsetattr(fd, TCSANOW, &tty) != 0) {
68 tcflush(fd, TCIOFLUSH);
72static unsigned char mhz19_checksum(
const unsigned char *buf) {
74 for (
int i = 1; i < 8; i++)
76 return (
unsigned char)(0xFF - (sum & 0xFF) + 1);
79static int read_mhz19_ppm(
float *ppm_out) {
80 const char *dev = getenv(
"MHZ19_DEVICE");
83 int fd = open_serial_9600(dev);
87 unsigned char cmd[9] = {0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79};
88 if (write(fd, cmd,
sizeof(cmd)) != (ssize_t)
sizeof(cmd)) {
93 unsigned char resp[9];
94 ssize_t got = read(fd, resp,
sizeof(resp));
96 if (got != (ssize_t)
sizeof(resp))
98 if (resp[0] != 0xFF || resp[1] != 0x86)
100 if (resp[8] != mhz19_checksum(resp))
102 int ppm = ((int)resp[2] << 8) | resp[3];
103 if (ppm < 0 || ppm > 10000)
105 *ppm_out = (float)ppm;
113 memset(out, 0,
sizeof(*out));
115 snprintf(out->
model,
sizeof(out->
model),
"MH-Z19");
121 out->co = 400.0f + (float)(rand() % 2600);
123 float real_ppm = 0.0f;
124 if (read_mhz19_ppm(&real_ppm) == 0)
133static int mhz19_shutdown(
void) {
134 printf(
"MH-Z19 plugin shutdown.\n");
141 .plugin_version =
"1.0.0",
142 .description =
"Simulated MH-Z19 CO2 ppm readings mapped to co field.",
145 .read_sample = mhz19_read_sample,
146 .shutdown = mhz19_shutdown,
One air quality reading: pollutant values plus sensor/timestamp metadata.
char timestamp[32]
Reading timestamp, formatted "%Y-%m-%d %H:%M:%S".
char model[64]
Sensor model name, e.g.
int sensor_id
Numeric sensor identifier, matches SensorPlugin::sensor_id.
Runtime contract every sensor plugin (.so/.dylib/.dll) must implement.
int api_version
Must equal SENSOR_PLUGIN_API_VERSION at build time.