Arduino and JSON

Hello,
I am building a network of sensors for my home that will communicate with a MQTT broker that then sends the sensor feedback to a web app. As a result, I want my devices to send their payloads as JSON packets. I am working on a temperature sensor right now and I am having a problem sending over the JSON packet. The code compiles but the message does not get to the broker and my device notifies me that client.publish was not successful. I think it may be due to how I am loading the buffer and issues with lack of memory due to the size of the packet. Below is my source code, and I would appreciate feedback on how to fix this issue. Thank you!

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_Si7021.h>
#include <ArduinoJson.h>


// Update these with values suitable for your network.

const char* ssid = "********";
const char* password = "*****";
//const char* mqtt_server = "*********";
const char* mqtt_server = "broker.hivemq.com";
const char* clientID = "Device1";
const char* outTopic = "test";
const char* inTopic = "Request";


float humidity, temp_c,temp_f;  // Values read from sensor

unsigned long previousMillis = 0;        // will store last temp was read
const long interval = 2000;              // interval at which to read sensor
Adafruit_Si7021 sensor;

WiFiClient espClient;
PubSubClient client(espClient);
char msg[50];

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  // Conver the incoming byte array to a string
  payload[length] = '\0'; // Null terminator used to terminate the char array
  String message = (char*)payload;

  Serial.print("Message arrived on topic: [");
  Serial.print(topic);
  Serial.print("], ");
  Serial.println(message);

  if(message == "send"){

  gettemperature();
  Serial.print("Sending temperature:");
  Serial.println(temp_f);
  dtostrf(temp_f , 2, 2, msg);
  StaticJsonBuffer<1000> JSONbuffer;
  JsonObject& root = JSONbuffer.createObject();
  root["clientId"] = "Android-Autobahn";
  root["eventType"] = "TEMPERATURE";
  root["alertId"] = "12345";
  root["timestamp"] = "1524151676676";
  JsonObject& location = root.createNestedObject("location");
  JsonObject& gps = location.createNestedObject("gps");
  JsonObject& geometry = gps.createNestedObject("geometry");
  JsonArray& coordinates = geometry.createNestedArray("coordinates");

  coordinates.add(10.1);
  coordinates.add(11);
  geometry["type"] = "Point";
  gps["type"] = "Feature";
  JsonObject& sensorEvents = root.createNestedObject("sensorEvent");
  sensorEvents["type"]= "THERMOMETER";
  sensorEvents["subtype"]="highTemp";
  sensorEvents["value"]=msg;
  sensorEvents["threshold"]="72";

  char JSONmessageBuffer[1000];
  root.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));
  Serial.println("Sending message to MQTT topic..");
  Serial.println(JSONmessageBuffer);

  if (client.publish("test", JSONmessageBuffer) == true) { //update when server is changed
    Serial.println("Success sending message");
  } else {
    Serial.println("Error sending message");
  }
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(clientID)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(outTopic, clientID);
      // ... and resubscribe
      client.subscribe(inTopic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
  sensor = Adafruit_Si7021(); 

 if (sensor.begin()) { 
   Serial.println('Sensor ready'); 
 } else { 
   // TODO: We should probably reset the device if this happens 
   Serial.println('SENSOR FAILED TO START'); 
 } 

}

void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();
}

void gettemperature() {

  if(currentMillis - previousMillis >= interval) {
    // save the last time you read the sensor 
    previousMillis = currentMillis;   

    temp_c = sensor.readTemperature();     // Read temperature as Celcius
    temp_f = temp_c*1.8+32;

  }
}
float humidity, temp_c,temp_f;  // Values read from sensor

Why do these need to be global?

  String message = (char*)payload;

That was stupid. Just process the payload.

  StaticJsonBuffer<1000> JSONbuffer;

WTF? 1000 bytes?

  char JSONmessageBuffer[1000];
  root.printTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));

And make a copy of it.

Just which Arduino did you say you were using?

How much data does printTo() actually copy into the array?

Just which Arduino did you say you were using?

OP's not using an Arduino but an ESP8266 as the include lines show. This chip should have enough memory for such stuff.

Have you tried publishing just the temperature value to the MQTT server instead of the lengthy JSON structure? Are you sure your MQTT server accepts messages of that length? Did you patch the PubSubClient library (it has a default maximum message length of 128)?

pylon:
Have you tried publishing just the temperature value to the MQTT server instead of the lengthy JSON structure? Are you sure your MQTT server accepts messages of that length? Did you patch the PubSubClient library (it has a default maximum message length of 128)?

I think therein lies the issue. I thought it might be a hardware issue but its probably an issue with the library and its limitation. Do you by any chance know why the limitation is 128 bytes and if i may simply open the library files and change the value?

Do you by any chance know why the limitation is 128 bytes and if i may simply open the library files and change the value?

To know the why I would have to ask the developer. I guess it's because 128 byte is more than enough for the majority of use cases and because the library was developed for an Arduino (UNO has 2k of RAM) and not an ESP8266 (64k of RAM). In the embedded world usually you don't waste RAM for stuff better done on bigger machines. You seem to prepare the JSON for a web application on the ESP and transmit that using an MQTT server. You probably should re-think if that concept uses the right tools for that task.
But to answer you question: it seems that you can simply increase the value in the .h file.