#include #include #include #include #include #include #include #include #include #include #include #include "gpmb.h" _Bool stin[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; _Bool action[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int inputs[15] = {IN_01, IN_02, IN_03, IN_04, IN_05, IN_06, IN_07, IN_08, IN_09, IN_10, IN_11, IN_12, IN_13, IN_14, IN_15}; int shortout[15] = {16, 9, 10, 11, 12, 14, 15, 15, 18, 17, 20, 22, 24, 26, 28}; int longout[15] = {16, 13, 13, 13, 13, 14, 19, 19, 17, 18, 20, 21, 23, 25, 27}; struct timeval timer[15]; struct timeval now; const int swdelay = 700; const int fixdelay = 50; const int debug = 0; modbus_t *ctx; uint16_t reg[32];// will store read registers values int maxregisters[256]; //will store maximum number of read registers struct ws_events evs; char *message; int main(int argc, char **argv) { if (!bcm2835_init()) { printf("Hiba!\n"); return 1; } for (int i = 0; i < 15; i++) { // Sets the pins as input. bcm2835_gpio_fsel(inputs[i], BCM2835_GPIO_FSEL_INPT); // Sets the Pull-up mode for the pins. bcm2835_gpio_set_pud(inputs[i], BCM2835_GPIO_PUD_UP); } if (debug) printf("Key Test Program!!!!\n"); //Create a new RTU context with proper serial parameters (in this example, //device name /dev/ttyS0, baud rate 9600, no parity bit, 8 data bits, 1 stop bit) ctx = modbus_new_rtu("/dev/ttyUSB0", 9600, 'N', 8, 1); if (!ctx) { fprintf(stderr, "Failed to create the context: %s\n", modbus_strerror(errno)); exit(1); } if (modbus_connect(ctx) == -1) { fprintf(stderr, "Unable to connect: %s\n", modbus_strerror(errno)); modbus_free(ctx); exit(1); } if (debug) modbus_set_debug(ctx, 1); //set the maximum number of read registers for modbus devices maxregisters[2] = 32; maxregisters[3] = 8; maxregisters[11] = 30; maxregisters[12] = 30; maxregisters[13] = 30; maxregisters[14] = 30; maxregisters[15] = 30; maxregisters[16] = 30; pthread_t thread; if (pthread_create(&thread, NULL, data_coll, NULL)) { perror("Thread"); exit(1); } evs.onopen = &onopen; evs.onclose = &onclose; evs.onmessage = &onmessage; ws_socket(&evs, WS_PORT, 1, 1000); while (1) { gettimeofday(&now, NULL); for (int i = 0; i < 15; i++) { // press if ((stin[i] == 0) && (bcm2835_gpio_lev(inputs[i]) == 0)) { if (debug) printf ("press %i\n", i) ; stin[i] = 1; action[i] = 1; gettimeofday(&timer[i], NULL); } // release else if (stin[i]) { if (action[i] && ((now.tv_sec * 1000 + now.tv_usec / 1000) > (timer[i].tv_sec * 1000 + timer[i].tv_usec / 1000 + swdelay))) { if (debug) printf ("release long %i\n", i); action[i] = 0; relay_output_toggle(MODBUS_ADDRESS_RELAY, longout[i]); } else if (bcm2835_gpio_lev(inputs[i]) == 1) { if (action[i]) { if (debug) printf ("release short %i\n", i); relay_output_toggle(MODBUS_ADDRESS_RELAY, shortout[i]); } stin[i] = 0; } } } bcm2835_delay(fixdelay); } modbus_close(ctx); modbus_free(ctx); bcm2835_close(); return 0; } //////////////////////////////////////////////////////////////////////////////// void relay_output_toggle (int slave, int output) { modbus_set_slave(ctx, slave); modbus_write_register(ctx, output, RELAY_SIGNAL_TOGGLE); asprintf(&message, "{\"address\":%i,\"toggle\":%i}", slave, output); ws_sendframe(NULL, message, strlen(message), WS_FR_OP_TXT); free(message); } //////////////////////////////////////////////////////////////////////////////// void relay_output_delay (int slave, int output, int delay) { if (delay < RELAY_DELAY_MIN) delay = RELAY_DELAY_MIN; if (delay > RELAY_DELAY_MAX) delay = RELAY_DELAY_MAX; modbus_set_slave(ctx, slave); modbus_write_register(ctx, output, (RELAY_SIGNAL_DELAY + delay)); asprintf(&message, "{\"address\":%i,\"delay\":%i,\"timeout\":%i}", slave, output, delay); ws_sendframe(NULL, message, strlen(message), WS_FR_OP_TXT); free(message); } //////////////////////////////////////////////////////////////////////////////// void *data_coll() { int sockfd; char buffer[1024]; struct sockaddr_in server_addr, client_addr; int numbytes; int addr_len; int output; int delay; int slave; int value; if (debug) printf("Capture thread started\n"); if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1); } server_addr.sin_family = AF_INET; server_addr.sin_port = htons(DATA_PORT); server_addr.sin_addr.s_addr = INADDR_ANY; memset(&(server_addr.sin_zero), '\0', 8); if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(1); } addr_len = sizeof(client_addr); while (1) { if ((numbytes = recvfrom(sockfd, (char *)buffer, 1024, 0, (struct sockaddr *)&client_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); } buffer[numbytes] = '\0'; if (debug) printf("UDP message received: %s (size: %d byte), from: %s\n", buffer, numbytes, inet_ntoa(client_addr.sin_addr)); if (strstr(buffer, "toggle")) { sscanf(buffer, "%*s %i %i", &slave, &output); relay_output_toggle(slave, output); } else if (strstr(buffer, "delay")) { sscanf(buffer, "%*s %i %i %i", &slave, &output, &delay); relay_output_delay(slave, output, delay); } else if (strstr(buffer, "set")) { sscanf(buffer, "%*s %i %i %i", &slave, &output, &value); modbus_set_slave(ctx, slave); modbus_write_register(ctx, output, value); } } } //////////////////////////////////////////////////////////////////////////////// char* hpstatus() { FILE *fp; char line[128]; char* buffer = NULL; unsigned int size=0; /* Open the command for reading. */ fp = popen("python /tmp/gree.py --json -c 192.168.1.22 -i 502cc6c0ba93 -k f0Hi3Kl6No9Qr2Tu hpstatus", "r"); if (fp == NULL) { printf("Failed to run command\n" ); exit(1); } /* Read the output a line at a time - output it. */ while (fgets(line, sizeof(line), fp) != NULL) { size += strlen(line); strcat(buffer = realloc(buffer,size),line); } if (debug) printf("%s", buffer); /* close */ pclose(fp); return buffer; } //////////////////////////////////////////////////////////////////////////////// void onopen(ws_cli_conn_t *client) { char *cli; cli = ws_getaddress(client); if (debug) printf("Connection opened, addr: %s\n", cli); } void onclose(ws_cli_conn_t *client) { char *cli; cli = ws_getaddress(client); if (debug) printf("Connection closed, addr: %s\n", cli); } void onmessage(ws_cli_conn_t *client, const unsigned char *msg, uint64_t size, int type) { char *cli; cli = ws_getaddress(client); int output; int delay; int slave; int value; if (debug) printf("Websocket message received: %s (size: %" PRId64 ", type: %d), from: %s\n", msg, size, type, cli); if (strstr(msg, "toggle")) { sscanf(msg, "%*s %i %i", &slave, &output); relay_output_toggle(slave, output); } else if (strstr(msg, "delay")) { sscanf(msg, "%*s %i %i %i", &slave, &output, &delay); relay_output_delay(slave, output, delay); } else if (strstr(msg, "set")) { sscanf(msg, "%*s %i %i %i", &slave, &output, &value); modbus_set_slave(ctx, slave); modbus_write_register(ctx, output, value); } else if (strstr(msg, "hpstatus")) { message = hpstatus(); ws_sendframe(client, message, strlen(message), type); free(message); } else if (strstr(msg, "status")) { sscanf(msg, "%*s %i", &slave); modbus_set_slave(ctx, slave); int num = modbus_read_registers(ctx, 0x0001, maxregisters[slave], reg); if (debug) printf("Number of read registers: %i\n", num); if (num != -1) { asprintf(&message, "{\"address\":%i,\"status\":[%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i,%i]}", slave, reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6], reg[7], reg[8], reg[9], reg[10], reg[11], reg[12], reg[13], reg[14], reg[15], reg[16], reg[17], reg[18], reg[19], reg[20], reg[21], reg[22], reg[23], reg[24], reg[25], reg[26], reg[27], reg[28], reg[29], reg[30], reg[31]); ws_sendframe(client, message, strlen(message), type); free(message); } } }