MQTT basert gjæringskontroll for Craftbeer Pi

Etter et par år med lua og esp8266, flytter jeg meg over i Arduino-verden igjen, det vil si – esp8266 addonen for Arduino IDE

Det finnes vesentlig flere bibliotek og større community for Arduino kode, så – intet alvorligere bak.

I de senere månedene har vi arbeidet met MQTT på jobben, så – det var naturlig for meg å benytte denne tankegangen når jeg skulle oppgradere gjæringsskapet.

//craftbeerpi mqtt fermentation chamber controller, heavily based on Erick Joaquins MQTT switch code.
//modified for cbpi json payload, heater/cooler and publishing of temperature
//
//Requires PubSubClient found here: https://github.com/knolleary/pubsubclient
//



#include #include
#include
#include
#include



void callback(char* topic, byte* payload, unsigned int length);



//EDIT THESE LINES TO MATCH YOUR SETUP



#define MQTT_SERVER "127.0.0.1" //you MQTT IP Address
const char* ssid = "replace";
const char* password = "replace";



//EJ: Data PIN Assignment on WEMOS D1 R2 https://www.wemos.cc/product/d1.html
// if you are using Arduino UNO, you will need to change the "D1 ~ D4" with the corresponding UNO DATA pin number



const int switchPin1 = D1;
const int switchPin2 = D5;
#define OWBUS D7



//onewire setup for temperature sensor
OneWire oneWire(OWBUS);
DallasTemperature sensors(&oneWire);
DeviceAddress tempsens;



//timer for posting temperature data - time in milliseconds
unsigned long interval = 500;
unsigned long previousMillis = 0;
unsigned long currentMillis = millis();



//buffer for handling json payloads
StaticJsonBuffer<200>; jsonBuffer;



//EJ: These are the MQTT Topic that will be used to manage the state of Relays, change for your settings



char const* switchTopic1 = "home/brewery/bay1/cool";
char const* switchTopic2 = "home/brewery/bay1/heat";



//misc



WiFiClient wifiClient;



PubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);



void setup_sensors(){
sensors.begin();
//Serial.println(sensors.getDeviceCount(), DEC);
if (!sensors.getAddress(tempsens, 0)) Serial.println("Unable to find address for Device 0");
sensors.setResolution(tempsens, 10);
}



void setup() {
//initialize the switch as an output and set to HIGH (off)
pinMode(switchPin1, OUTPUT); // Relay Switch 1
digitalWrite(switchPin1, HIGH);
pinMode(switchPin2, OUTPUT); // Relay Switch 2
digitalWrite(switchPin2, HIGH);



ArduinoOTA.setHostname("My Arduino WEMO"); // A name given to your ESP8266 module when discovering it as a port in ARDUINO IDE
ArduinoOTA.begin(); // OTA initialization



//start the serial line for debugging
Serial.begin(115200);
delay(100);



//start wifi subsystem
WiFi.begin(ssid, password);
//attempt to connect to the WIFI network and then connect to the MQTT server
reconnect();
delay(100);
setup_sensors();
//wait a bit before starting the main loop
delay(2000);
}



void loop(){
currentMillis = millis();
//reconnect if connection is lost
if (!client.connected() && WiFi.status() == 3) {reconnect();}



//maintain MQTT connection
client.loop();
//MUST delay to allow ESP8266 WIFI functions to run
delay(10);
ArduinoOTA.handle();
if ((currentMillis - previousMillis) >= interval) {
postTemp();
previousMillis = currentMillis;
}
}



void postTemp(){
sensors.requestTemperatures();
float tempC = sensors.getTempC(tempsens);
Serial.print("caling ");
Serial.println(String(tempC).c_str());
client.publish("home/brewery/bay1/temperature", String(tempC).c_str(), false);
}



void callback(char* topic, byte* payload, unsigned int length) {
//convert topic to string to make it easier to work with
String topicStr = topic;
//EJ: Note: the "topic" value gets overwritten everytime it receives confirmation (callback) message from MQTT
//Print out some debugging info
Serial.println("Callback update.");
Serial.print("Topic: ");
Serial.println(topicStr);
Serial.println((char *)payload);



if (topicStr == "home/brewery/bay1/cool") {
String state = jsonState(payload);
Serial.println((char *)payload);
if(state == "on") {
digitalWrite(switchPin1, LOW);
client.publish("home/brewery/bay1/coolConfirm", "1");
}
else if (state == "off") {
digitalWrite(switchPin1, HIGH);
client.publish("home/brewery/bay1/coolConfirm", "0");
}
}
else if (topicStr == "home/brewery/bay1/heat"){
String state = jsonState(payload);
if(state == "on") {
digitalWrite(switchPin2, LOW);
client.publish("home/brewery/bay1/heatConfirm", "1");
}
else if (state == "off") {
digitalWrite(switchPin2, HIGH);
client.publish("home/brewery/bay1/heatConfirm", "0");
}
}
jsonBuffer.clear();
}



void reconnect() {



//attempt to connect to the wifi if connection is lost
if(WiFi.status() != WL_CONNECTED){
//debug printing
Serial.print("Connecting to ");
Serial.println(ssid);



//loop while we wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}



//print out some more debug once connected
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}



//make sure we are connected to WIFI before attemping to reconnect to MQTT
if(WiFi.status() == WL_CONNECTED){
// Loop until we're reconnected to the MQTT server
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");



// Generate client name based on MAC address and last 8 bits of microsecond counter
String clientName;
clientName += "esp8266-";
uint8_t mac[6];
WiFi.macAddress(mac);
clientName += macToStr(mac);



//if connected, subscribe to the topic(s) we want to be notified about
//EJ: Delete "mqtt_username", and "mqtt_password" here if you are not using any
if (client.connect((char*) clientName.c_str(),"user", "pass")) { //EJ: Update accordingly with your MQTT account
Serial.print("\tMQTT Connected");
client.subscribe(switchTopic1);
client.subscribe(switchTopic2);
//EJ: Do not forget to replicate the above line if you will have more than the above number of relay switches
}



//otherwise print failed for debugging
else{Serial.println("\tFailed."); abort();}
}
}
}



//generate unique name from MAC addr
String macToStr(const uint8_t* mac){



String result;



for (int i = 0; i < 6; ++i) {
result += String(mac[i], 16);



if (i < 5){
result += ':';
}
}



return result;
}




String jsonState(byte* payload) {
JsonObject& root = jsonBuffer.parseObject(payload);
if (!root.success()) {
Serial.println("parseObject() failed");
}
return root["state"];
}
Dette innlegget ble publisert i Øl, Tech. Bokmerk permalenken.