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
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;
|
|
}
|