163 lines
4.3 KiB
C++
163 lines
4.3 KiB
C++
|
#include <Arduino.h>
|
||
|
#include <ESPAsyncWebServer.h>
|
||
|
#include "AsyncJson.h"
|
||
|
#include "ArduinoJson.h"
|
||
|
#include "hciemulator.h"
|
||
|
#include "index_html.h"
|
||
|
|
||
|
/* create this file and add your wlan credentials
|
||
|
const char* ssid = "MyWLANSID";
|
||
|
const char* password = "MYPASSWORD";
|
||
|
*/
|
||
|
#include "../../../private/credentials.h"
|
||
|
|
||
|
|
||
|
// switch relay sync to the lamp
|
||
|
// e.g. the Wifi Relay Board U4648
|
||
|
#define USERELAY
|
||
|
|
||
|
// use alternative uart pins
|
||
|
//#define SWAPUART
|
||
|
|
||
|
#define RS485 Serial
|
||
|
|
||
|
// Relay Board parameters
|
||
|
#define ESP8266_GPIO2 2 // Blue LED.
|
||
|
#define ESP8266_GPIO4 4 // Relay control.
|
||
|
#define ESP8266_GPIO5 5 // Optocoupler input.
|
||
|
#define LED_PIN ESP8266_GPIO2
|
||
|
|
||
|
|
||
|
// Hörmann HCP2 based on modbus rtu @57.6kB 8E1
|
||
|
HCIEmulator emulator(&RS485);
|
||
|
|
||
|
// webserver on port 80
|
||
|
AsyncWebServer server(80);
|
||
|
|
||
|
|
||
|
// switch GPIO4 und GPIO2 sync to the lamp
|
||
|
void onStatusChanged(const SHCIState& state){
|
||
|
//see https://ucexperiment.wordpress.com/2016/12/18/yunshan-esp8266-250v-15a-acdc-network-wifi-relay-module/
|
||
|
//Setting GPIO4 high, causes the relay to close the NO contact with
|
||
|
if(state.valid){
|
||
|
digitalWrite( ESP8266_GPIO4, state.lampOn );
|
||
|
digitalWrite(LED_PIN, state.lampOn);
|
||
|
}else
|
||
|
{
|
||
|
digitalWrite( ESP8266_GPIO4, false );
|
||
|
digitalWrite(LED_PIN, false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// toggle lamp to expected state
|
||
|
void switchLamp(bool on){
|
||
|
bool toggle = (on && !emulator.getState().lampOn) || (!on && emulator.getState().lampOn);
|
||
|
if(toggle){
|
||
|
emulator.toggleLamp();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// setup mcu
|
||
|
void setup(){
|
||
|
|
||
|
//setup modbus
|
||
|
RS485.begin(57600,SERIAL_8E1);
|
||
|
#ifdef SWAPUART
|
||
|
RS485.swap();
|
||
|
#endif
|
||
|
|
||
|
//setup wifi
|
||
|
WiFi.mode(WIFI_STA);
|
||
|
WiFi.begin(ssid, password);
|
||
|
WiFi.setAutoReconnect(true);
|
||
|
while (WiFi.status() != WL_CONNECTED) {
|
||
|
emulator.poll();
|
||
|
}
|
||
|
|
||
|
// setup http server
|
||
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
||
|
AsyncWebServerResponse *response = request->beginResponse_P( 200, "text/html", index_html,sizeof(index_html));
|
||
|
response->addHeader("Content-Encoding","deflate");
|
||
|
request->send(response);
|
||
|
});
|
||
|
|
||
|
server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request){
|
||
|
const SHCIState& doorstate = emulator.getState();
|
||
|
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||
|
DynamicJsonDocument root(1024);
|
||
|
root["valid"] = doorstate.valid;
|
||
|
root["doorstate"] = doorstate.doorState;
|
||
|
root["doorposition"] = doorstate.doorCurrentPosition;
|
||
|
root["doortarget"] = doorstate.doorTargetPosition;
|
||
|
root["lamp"] = doorstate.lampOn;
|
||
|
root["debug"] = doorstate.reserved;
|
||
|
root["lastresponse"] = emulator.getMessageAge()/1000;
|
||
|
serializeJson(root,*response);
|
||
|
request->send(response);
|
||
|
});
|
||
|
|
||
|
server.on("/command", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
||
|
if (request->hasParam("action")) {
|
||
|
int actionid = request->getParam("action")->value().toInt();
|
||
|
switch (actionid){
|
||
|
case 0:
|
||
|
emulator.closeDoor();
|
||
|
break;
|
||
|
case 1:
|
||
|
emulator.openDoor();
|
||
|
break;
|
||
|
case 2:
|
||
|
emulator.stopDoor();
|
||
|
break;
|
||
|
case 3:
|
||
|
emulator.ventilationPosition();
|
||
|
break;
|
||
|
case 4:
|
||
|
emulator.openDoorHalf();
|
||
|
break;
|
||
|
case 5:
|
||
|
emulator.toggleLamp();
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
request->send(200, "text/plain", "OK");
|
||
|
});
|
||
|
|
||
|
server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
|
||
|
if (request->hasParam("channel") && request->hasParam("state")) {
|
||
|
String channel = request->getParam("channel")->value();
|
||
|
String state = request->getParam("state")->value();
|
||
|
if(channel.equals("door")){
|
||
|
if(state=="1"){
|
||
|
emulator.openDoor();
|
||
|
}else{
|
||
|
emulator.closeDoor();
|
||
|
}
|
||
|
}
|
||
|
if(channel.equals("light")){
|
||
|
switchLamp(state=="1");
|
||
|
}
|
||
|
}
|
||
|
request->send(200, "text/plain", "OK");
|
||
|
});
|
||
|
|
||
|
server.begin();
|
||
|
|
||
|
//setup relay board
|
||
|
#ifdef USERELAY
|
||
|
pinMode( ESP8266_GPIO4, OUTPUT ); // Relay control pin.
|
||
|
pinMode( ESP8266_GPIO5, INPUT_PULLUP ); // Input pin.
|
||
|
pinMode( LED_PIN, OUTPUT ); // ESP8266 module blue L
|
||
|
digitalWrite( ESP8266_GPIO4, 0 );
|
||
|
digitalWrite(LED_PIN,0);
|
||
|
emulator.onStatusChanged(onStatusChanged);
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
// mainloop
|
||
|
void loop(){
|
||
|
emulator.poll();
|
||
|
}
|