Просмотр исходного кода

Added OpenHAB state push service

Philipp Hinz 6 лет назад
Родитель
Сommit
1421391981
4 измененных файлов с 165 добавлено и 2 удалено
  1. 1 1
      CoffeeCode/buildno
  2. 2 1
      CoffeeCode/main.cpp
  3. 144 0
      CoffeeCode/openhab.cpp
  4. 18 0
      CoffeeCode/openhab.h

+ 1 - 1
CoffeeCode/buildno

@@ -1 +1 @@
-306
+323

+ 2 - 1
CoffeeCode/main.cpp

@@ -27,6 +27,7 @@
 #include "server.h"
 #include "events.h"
 #include "DS18B20.h"
+#include "openhab.h"
 
 const int buildno = (1+(int)(
 #include "buildno"
@@ -130,7 +131,7 @@ int main(int argc, char *argv[]) {
 	displayInit();
 	//temperatur_init();
 	DS18B20_init();
-
+	openhabInit();
 
 	// http://www.tutorialspoint.com/cplusplus/cpp_multithreading.htm
 

+ 144 - 0
CoffeeCode/openhab.cpp

@@ -0,0 +1,144 @@
+/*
+ * 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);
+	logger(V_BASIC, "Initialized OpenHAB state updater with target %s:%d\n",
+	OPENHAB_IP, OPENHAB_PORT);
+}
+

+ 18 - 0
CoffeeCode/openhab.h

@@ -0,0 +1,18 @@
+/*
+ * openhab.h
+ *
+ *  Created on: May 25, 2019
+ *      Author: sebastian
+ */
+
+#ifndef OPENHAB_H_
+#define OPENHAB_H_
+
+#define OPENHAB_IP 		"192.168.0.10" // IP of openhab instance
+#define OPENHAB_PORT	8080 // Port
+#define OPENHAB_URI		"/rest/items/KaffeeOn/state"
+
+void openhabInit(void);
+void *httpTimerHandler(void *threadid);
+
+#endif /* OPENHAB_H_ */