Hi, is it possible to subscribe to a MQTT server -AND- http POST from the same Arduino?
Background: I'm running the home automation platform 'Home Assistant' (HA) and MQTT Server (Mosquito) on a RPi2, a HA timer is set to publish on a certain MQTT topic. I want the Arduino to subscribe to that topic and POST lines of HTTP code determined by the MQTT payload. The ultimate goal is a timer (alarm) on HA that will turn on/off the Denon amplifier ZONE 2.
Progress: The MQTT subscribe works and I can call void Z2_ON and void Z2_OFF, BUT the Arduino will not connect to the Denon. The POST code works fine, if I alter the order the sketch will POST and turn the Denon on, but will not connect to the MQTT server afterwards. It seems the Arduino can only make one connection.
More background: Home Assistant has a Denon module that will directly control the main Zone, but not Zone 2. I'm also looking at an Infra-red option, but would like to get this sketch operational. If anyone is familiar with HA and can recommend a better way to connect to the Arduino or POST HTTP I'd love to hear it.
Thanks in advance for any advice
/*
Denon Remote Control Via MQTT using "POST" Command
Any string published on "arduino/remote" will be read into the string
"command" sent to the serial printer. It will also be used to call relevant
modules.
All code borrowed from folk a lot brighter than me.
*/
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
byte mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(10, 16, 15, 131); //Address of Arduino
IPAddress MQTTserver(10, 16, 15, 161); //Running on the RPi2
IPAddress denon(10,16,15,180); //Denon AVR-X3000
EthernetClient ethClient;
PubSubClient client(ethClient);
String command = "";
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) { //Read MQTT payload into "command"
command += ((char)payload[i]);
}
Serial.println(command); //For testing only
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (client.connect("arduino/remote")) {
Serial.println("connected");
// Once connected, publish an announcement...
//client.publish("arduino/remote","IR Romote Online"); //not needed
// ... and resubscribe
client.subscribe("arduino/remote");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void Z2_ON()
{
if (ethClient.connect(denon, 80)) {
Serial.println("connected");
// Make a HTTP request:
ethClient.println("POST /MainZone/index.put.asp HTTP/1.1");
ethClient.println("Host: 10.16.15.180");
ethClient.println("User-Agent: User-Agent: Arduino/1.0");
ethClient.println("Accept: */*");
ethClient.println("Accept-Language: en-us,en;q=0.5");
ethClient.println("Accept-Encoding: gzip, deflate");
ethClient.println("Connection: keep-alive");
ethClient.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
ethClient.println("X-Requested-With: XMLHttpRequest");
ethClient.println("Referer: http://10.16.15.180/Zone2/index.html");
ethClient.println("Content-Length: 74");
ethClient.println("Cookie: ZoneName=ZONE2");
ethClient.println("Pragma: no-cache");
ethClient.println("");
ethClient.println("cmd0=PutZone_OnOff%2FON&cmd1=aspMainZone_WebUpdateStatus%2F&ZoneName=ZONE2HTTP/1.0 200 OK");
ethClient.println("Cache-Control: no-cache");
ethClient.println("Connection: close");
ethClient.println();
}
else {
// if you didn't get a connection to the server:
Serial.println("connection failed");
}
}
void Z2_OFF() {
//No HTTP POST here as yet.
Serial.println("Turn OFF Zone Two");
}
void setup()
{
Serial.begin(9600);
client.setServer(MQTTserver, 1883);
client.setCallback(callback);
Ethernet.begin(mac, ip);
// Allow the hardware to sort itself out
delay(1500);
}
void monitor_MQTT()
{
if (!client.connected()) {
reconnect();
}
client.loop();
}
void loop()
{
if (command == ""){
monitor_MQTT();
}
else {
Serial.println("MQTT Pub is " + command); //For Testing
if (command == "Z2_ON"){
Z2_ON();
}
if (command == "Z2_OFF"){
Z2_OFF();
}
command = ""; //Reset String command and restart loop
}
}