{"id":886,"date":"2018-03-24T21:27:22","date_gmt":"2018-03-24T19:27:22","guid":{"rendered":"http:\/\/www.degerdalen.no\/?p=886"},"modified":"2019-05-01T14:20:14","modified_gmt":"2019-05-01T12:20:14","slug":"mqtt-basert-gjaeringskontroll-for-craftbeer-pi","status":"publish","type":"post","link":"https:\/\/www.degerdalen.no\/?p=886","title":{"rendered":"MQTT basert gj\u00e6ringskontroll for Craftbeer Pi"},"content":{"rendered":"<p>Etter et par \u00e5r med lua og esp8266, flytter jeg meg over i Arduino-verden igjen, det vil si &#8211; esp8266 addonen for Arduino IDE<\/p>\n<p>Det finnes vesentlig flere bibliotek og st\u00f8rre community for Arduino kode, s\u00e5 &#8211; intet alvorligere bak.<\/p>\n<p>I de senere m\u00e5nedene har vi arbeidet met MQTT p\u00e5 jobben, s\u00e5 &#8211; det var naturlig for meg \u00e5 benytte denne tankegangen n\u00e5r jeg skulle oppgradere gj\u00e6ringsskapet.<\/p>\n<pre>\n\/\/craftbeerpi mqtt fermentation chamber controller, heavily based on Erick Joaquins MQTT switch code.\n\/\/modified for cbpi json payload, heater\/cooler and publishing of temperature\n\/\/\n\/\/Requires PubSubClient found here: https:\/\/github.com\/knolleary\/pubsubclient\n\/\/<\/code>\n\n<code><code><\/code><\/code>\n\n#include #include\n#include\n#include\n#include\n\n<code><code><\/code><\/code>\n\nvoid callback(char* topic, byte* payload, unsigned int length);\n\n<code><code><\/code><\/code>\n\n\/\/EDIT THESE LINES TO MATCH YOUR SETUP\n\n<code><code><\/code><\/code>\n\n#define MQTT_SERVER \"127.0.0.1\" \/\/you MQTT IP Address\nconst char* ssid = \"replace\";\nconst char* password = \"replace\";\n\n<code><code><\/code><\/code>\n\n\/\/EJ: Data PIN Assignment on WEMOS D1 R2 https:\/\/www.wemos.cc\/product\/d1.html\n\/\/ if you are using Arduino UNO, you will need to change the \"D1 ~ D4\" with the corresponding UNO DATA pin number\n\n<code><code><\/code><\/code>\n\nconst int switchPin1 = D1;\nconst int switchPin2 = D5;\n#define OWBUS D7\n\n<code><code><\/code><\/code>\n\n\/\/onewire setup for temperature sensor\nOneWire oneWire(OWBUS);\nDallasTemperature sensors(&amp;oneWire);\nDeviceAddress tempsens;\n\n<code><code><\/code><\/code>\n\n\/\/timer for posting temperature data - time in milliseconds\nunsigned long interval = 500;\nunsigned long previousMillis = 0;\nunsigned long currentMillis = millis();\n\n<code><code><\/code><\/code>\n\n\/\/buffer for handling json payloads\nStaticJsonBuffer&lt;200&gt;; jsonBuffer;\n\n<code><code><\/code><\/code>\n\n\/\/EJ: These are the MQTT Topic that will be used to manage the state of Relays, change for your settings\n\n<code><code><\/code><\/code>\n\nchar const* switchTopic1 = \"home\/brewery\/bay1\/cool\";\nchar const* switchTopic2 = \"home\/brewery\/bay1\/heat\";\n\n<code><code><\/code><\/code>\n\n\/\/misc\n\n<code><code><\/code><\/code>\n\nWiFiClient wifiClient;\n\n<code><code><\/code><\/code>\n\nPubSubClient client(MQTT_SERVER, 1883, callback, wifiClient);\n\n<code><code><\/code><\/code>\n\nvoid setup_sensors(){\nsensors.begin();\n\/\/Serial.println(sensors.getDeviceCount(), DEC);\nif (!sensors.getAddress(tempsens, 0)) Serial.println(\"Unable to find address for Device 0\");\nsensors.setResolution(tempsens, 10);\n}\n\n<code><code><\/code><\/code>\n\nvoid setup() {\n\/\/initialize the switch as an output and set to HIGH (off)\npinMode(switchPin1, OUTPUT); \/\/ Relay Switch 1\ndigitalWrite(switchPin1, HIGH);\npinMode(switchPin2, OUTPUT); \/\/ Relay Switch 2\ndigitalWrite(switchPin2, HIGH);\n\n<code><code><\/code><\/code>\n\nArduinoOTA.setHostname(\"My Arduino WEMO\"); \/\/ A name given to your ESP8266 module when discovering it as a port in ARDUINO IDE\nArduinoOTA.begin(); \/\/ OTA initialization\n\n<code><code><\/code><\/code>\n\n\/\/start the serial line for debugging\nSerial.begin(115200);\ndelay(100);\n\n<code><code><\/code><\/code>\n\n\/\/start wifi subsystem\nWiFi.begin(ssid, password);\n\/\/attempt to connect to the WIFI network and then connect to the MQTT server\nreconnect();\ndelay(100);\nsetup_sensors();\n\/\/wait a bit before starting the main loop\ndelay(2000);\n}\n\n<code><code><\/code><\/code>\n\nvoid loop(){\ncurrentMillis = millis();\n\/\/reconnect if connection is lost\nif (!client.connected() &amp;&amp; WiFi.status() == 3) {reconnect();}\n\n<code><code><\/code><\/code>\n\n\/\/maintain MQTT connection\nclient.loop();\n\/\/MUST delay to allow ESP8266 WIFI functions to run\ndelay(10);\nArduinoOTA.handle();\nif ((currentMillis - previousMillis) &gt;= interval) {\npostTemp();\npreviousMillis = currentMillis;\n}\n}\n\n<code><code><\/code><\/code>\n\nvoid postTemp(){\nsensors.requestTemperatures();\nfloat tempC = sensors.getTempC(tempsens);\nSerial.print(\"caling \");\nSerial.println(String(tempC).c_str());\nclient.publish(\"home\/brewery\/bay1\/temperature\", String(tempC).c_str(), false);\n}\n\n<code><code><\/code><\/code>\n\nvoid callback(char* topic, byte* payload, unsigned int length) {\n\/\/convert topic to string to make it easier to work with\nString topicStr = topic;\n\/\/EJ: Note: the \"topic\" value gets overwritten everytime it receives confirmation (callback) message from MQTT\n\/\/Print out some debugging info\nSerial.println(\"Callback update.\");\nSerial.print(\"Topic: \");\nSerial.println(topicStr);\nSerial.println((char *)payload);\n\n<code><code><\/code><\/code>\n\nif (topicStr == \"home\/brewery\/bay1\/cool\") {\nString state = jsonState(payload);\nSerial.println((char *)payload);\nif(state == \"on\") {\ndigitalWrite(switchPin1, LOW);\nclient.publish(\"home\/brewery\/bay1\/coolConfirm\", \"1\");\n}\nelse if (state == \"off\") {\ndigitalWrite(switchPin1, HIGH);\nclient.publish(\"home\/brewery\/bay1\/coolConfirm\", \"0\");\n}\n}\nelse if (topicStr == \"home\/brewery\/bay1\/heat\"){\nString state = jsonState(payload);\nif(state == \"on\") {\ndigitalWrite(switchPin2, LOW);\nclient.publish(\"home\/brewery\/bay1\/heatConfirm\", \"1\");\n}\nelse if (state == \"off\") {\ndigitalWrite(switchPin2, HIGH);\nclient.publish(\"home\/brewery\/bay1\/heatConfirm\", \"0\");\n}\n}\njsonBuffer.clear();\n}\n\n<code><code><\/code><\/code>\n\nvoid reconnect() {\n\n<code><code><\/code><\/code>\n\n\/\/attempt to connect to the wifi if connection is lost\nif(WiFi.status() != WL_CONNECTED){\n\/\/debug printing\nSerial.print(\"Connecting to \");\nSerial.println(ssid);\n\n<code><code><\/code><\/code>\n\n\/\/loop while we wait for connection\nwhile (WiFi.status() != WL_CONNECTED) {\ndelay(500);\nSerial.print(\".\");\n}\n\n<code><code><\/code><\/code>\n\n\/\/print out some more debug once connected\nSerial.println(\"\");\nSerial.println(\"WiFi connected\");\nSerial.println(\"IP address: \");\nSerial.println(WiFi.localIP());\n}\n\n<code><code><\/code><\/code>\n\n\/\/make sure we are connected to WIFI before attemping to reconnect to MQTT\nif(WiFi.status() == WL_CONNECTED){\n\/\/ Loop until we're reconnected to the MQTT server\nwhile (!client.connected()) {\nSerial.print(\"Attempting MQTT connection...\");\n\n<code><code><\/code><\/code>\n\n\/\/ Generate client name based on MAC address and last 8 bits of microsecond counter\nString clientName;\nclientName += \"esp8266-\";\nuint8_t mac[6];\nWiFi.macAddress(mac);\nclientName += macToStr(mac);\n\n<code><code><\/code><\/code>\n\n\/\/if connected, subscribe to the topic(s) we want to be notified about\n\/\/EJ: Delete \"mqtt_username\", and \"mqtt_password\" here if you are not using any\nif (client.connect((char*) clientName.c_str(),\"user\", \"pass\")) { \/\/EJ: Update accordingly with your MQTT account\nSerial.print(\"\\tMQTT Connected\");\nclient.subscribe(switchTopic1);\nclient.subscribe(switchTopic2);\n\/\/EJ: Do not forget to replicate the above line if you will have more than the above number of relay switches\n}\n\n<code><code><\/code><\/code>\n\n\/\/otherwise print failed for debugging\nelse{Serial.println(\"\\tFailed.\"); abort();}\n}\n}\n}\n\n<code><code><\/code><\/code>\n\n\/\/generate unique name from MAC addr\nString macToStr(const uint8_t* mac){\n\n<code><code><\/code><\/code>\n\nString result;\n\n<code><code><\/code><\/code>\n\nfor (int i = 0; i &lt; 6; ++i) {\nresult += String(mac[i], 16);\n\n<code><code><\/code><\/code>\n\nif (i &lt; 5){\nresult += ':';\n}\n}\n\n<code><code><\/code><\/code>\n\nreturn result;\n}\n\n<code>\n<\/code>\n\n<code>String jsonState(byte* payload) {\nJsonObject&amp; root = jsonBuffer.parseObject(payload);\nif (!root.success()) {\nSerial.println(\"parseObject() failed\");\n}\nreturn root[\"state\"];\n}\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Etter et par \u00e5r med lua og esp8266, flytter jeg meg over i Arduino-verden igjen, det vil si &#8211; esp8266 addonen for Arduino IDE Det finnes vesentlig flere bibliotek og st\u00f8rre community for Arduino kode, s\u00e5 &#8211; intet alvorligere bak. &hellip; <a href=\"https:\/\/www.degerdalen.no\/?p=886\">Les videre <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[162,11],"tags":[],"_links":{"self":[{"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=\/wp\/v2\/posts\/886"}],"collection":[{"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=886"}],"version-history":[{"count":4,"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=\/wp\/v2\/posts\/886\/revisions"}],"predecessor-version":[{"id":899,"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=\/wp\/v2\/posts\/886\/revisions\/899"}],"wp:attachment":[{"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=886"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=886"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.degerdalen.no\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=886"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}