You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
3.0 KiB
C

#include <errno.h>
#include <fcntl.h>
#include <linux/i2c-dev.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <unistd.h>
static void print_json_error(const char *message)
{
printf("{\"success\":false,\"error\":\"%s\"}\n", message);
}
int main(int argc, char *argv[])
{
if (argc < 5)
{
print_json_error("Uso: EZO_COMMAND bus address delay_ms command [--no-response]");
return 2;
}
const char *bus = argv[1];
int address = (int)strtol(argv[2], NULL, 0);
int delay_ms = atoi(argv[3]);
const char *command = argv[4];
int no_response = argc > 5 && strcmp(argv[5], "--no-response") == 0;
int lock_fd = open("/tmp/photobioreactor-i2c.lock", O_CREAT | O_RDWR, 0660);
if (lock_fd < 0 || flock(lock_fd, LOCK_EX) < 0)
{
print_json_error("No se pudo bloquear el bus I2C");
return 3;
}
int fd = open(bus, O_RDWR);
if (fd < 0)
{
print_json_error("No se pudo abrir el bus I2C");
flock(lock_fd, LOCK_UN);
close(lock_fd);
return 4;
}
if (ioctl(fd, I2C_SLAVE, address) < 0)
{
print_json_error("No se pudo seleccionar el circuito EZO");
close(fd);
flock(lock_fd, LOCK_UN);
close(lock_fd);
return 5;
}
if (write(fd, command, strlen(command)) < 0)
{
print_json_error("Fallo al escribir el comando EZO");
close(fd);
flock(lock_fd, LOCK_UN);
close(lock_fd);
return 6;
}
usleep((useconds_t)delay_ms * 1000);
if (no_response)
{
printf("{\"success\":true,\"response\":\"SENT\"}\n");
close(fd);
flock(lock_fd, LOCK_UN);
close(lock_fd);
return 0;
}
unsigned char response[64] = {0};
int bytes_read = read(fd, response, sizeof(response) - 1);
for (int retry = 0; bytes_read > 0 && response[0] == 254 && retry < 10; retry++)
{
usleep(100000);
memset(response, 0, sizeof(response));
bytes_read = read(fd, response, sizeof(response) - 1);
}
if (bytes_read < 1)
{
print_json_error("El circuito EZO no respondió");
close(fd);
flock(lock_fd, LOCK_UN);
close(lock_fd);
return 7;
}
if (response[0] != 1)
{
char message[64];
snprintf(message, sizeof(message), "Código de respuesta EZO: %u", response[0]);
print_json_error(message);
close(fd);
flock(lock_fd, LOCK_UN);
close(lock_fd);
return 8;
}
char *payload = (char *)&response[1];
payload[bytes_read > 1 ? bytes_read - 1 : 0] = '\0';
for (int i = 0; payload[i] != '\0'; i++)
{
if (payload[i] == '"' || payload[i] == '\\')
{
payload[i] = ' ';
}
}
printf("{\"success\":true,\"response\":\"%s\"}\n",
payload[0] == '\0' ? "*OK" : payload);
close(fd);
flock(lock_fd, LOCK_UN);
close(lock_fd);
return 0;
}