123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /*
- * openhab.cpp
- *
- * Created on: May 25, 2019
- * Author: Philipp Hinz
- */
- #include <stdlib.h>
- #include <pthread.h>
- #include <stdio.h> /* printf, sprintf */
- #include <unistd.h> /* read, write, close */
- #include <string.h> /* memcpy, memset */
- #include <sys/socket.h> /* socket, connect */
- #include <netinet/in.h> /* struct sockaddr_in, struct sockaddr */
- #include <netdb.h> /* struct hostent, gethostbyname */
- #include "openhab.h"
- #include "events.h"
- #include "timer.h"
- #include "logger.h"
- #include "coffee.h"
- coffee_status_t openhabCoffeeState = STATE_IDLE; // Don't use OFF to push initial state
- timer httpTimer(httpTimerHandler);
- #define NL "\r\n" // New line for HTTP Requests
- /**
- * Updates the display state to the matching coffee state
- * @param event Event data
- */
- void openhabStateUpdated(event_t *event) {
- if (event->len != sizeof(coffee_status_t)) {
- logger_error("Invalid use of event %s\n", event->event);
- return;
- }
- coffee_status_t state = *(coffee_status_t*) event->data;
- if ((openhabCoffeeState == STATE_OFF && state != STATE_OFF) || // Machine turns on
- (state == STATE_OFF && openhabCoffeeState != STATE_OFF)) { // machine turns off
- openhabCoffeeState = state;
- httpTimer.call();
- }
- }
- /**
- * This is the handler for time based stripe effects
- * @param *threadid Thread ID
- */
- void *httpTimerHandler(void *threadid) {
- struct hostent *server;
- struct sockaddr_in serv_addr;
- int sockfd, bytes, sent, received, total;
- char message[1024], response[4096], value[4];
- sprintf(value, "%s", (openhabCoffeeState == STATE_OFF ? "OFF" : "ON"));
- /* fill in the parameters */
- sprintf(message, "PUT %s HTTP/1.1" NL
- "Host: %s" NL
- "Connection: close" NL
- "Content-Type: text/plain" NL
- "Content-Length: %d" NL NL
- "%s", OPENHAB_URI, OPENHAB_IP, strlen(value), value);
- /* create the socket */
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- if (sockfd < 0) {
- logger_error("%s:%d could not open socket\n", __FILE__, __LINE__);
- pthread_exit(NULL);
- }
- /* lookup the ip address */
- server = gethostbyname(OPENHAB_IP);
- if (server == NULL) {
- logger_error("%s:%d no such host %s\n", __FILE__, __LINE__, OPENHAB_IP);
- pthread_exit(NULL);
- }
- /* fill in the structure */
- memset(&serv_addr, 0, sizeof(serv_addr));
- serv_addr.sin_family = AF_INET;
- serv_addr.sin_port = htons(OPENHAB_PORT);
- memcpy(&serv_addr.sin_addr.s_addr, server->h_addr,server->h_length);
- /* connect the socket */
- if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))
- < 0) {
- logger_error("%s:%d could not connect to %s on port %d\n", __FILE__,
- __LINE__, OPENHAB_IP, OPENHAB_PORT);
- pthread_exit(NULL);
- }
- /* send the request */
- total = strlen(message);
- sent = 0;
- do {
- bytes = write(sockfd, message + sent, total - sent);
- if (bytes < 0) {
- logger_error("%s:%d ERROR writing message to socket\n", __FILE__,
- __LINE__);
- pthread_exit(NULL);
- }
- if (bytes == 0)
- break;
- sent += bytes;
- } while (sent < total);
- /* receive the response */
- memset(response, 0, sizeof(response));
- total = sizeof(response) - 1;
- received = 0;
- do {
- bytes = read(sockfd, response + received, total - received);
- if (bytes < 0) {
- logger_error("%s:%d ERROR reading response from socket\n", __FILE__,
- __LINE__);
- pthread_exit(NULL);
- }
- if (bytes == 0)
- break;
- received += bytes;
- } while (received < total);
- if (received == total) {
- logger_error("%s:%d ERROR storing complete response from socket\n",
- __FILE__, __LINE__);
- pthread_exit(NULL);
- }
- /* close the socket */
- close(sockfd);
- /* process response */
- logger(V_HAL, "HTTP Response:\n%s\n", response);
- pthread_exit(NULL);
- }
- void openhabInit(void) {
- event_subscribe("statechange", &openhabStateUpdated, "openhab.cpp");
- logger(V_BASIC, "Initialized OpenHAB state updater with target %s:%d\n",
- OPENHAB_IP, OPENHAB_PORT);
- }
|