Long-lived access token fails sometimes

Hi,

I have a homemade sensor that uses the Long-lived access token to authenticate towards the api on homeassistant.
Every now and then (can’t reproduce in a stable way), I get a error message in home assistant logs telling me that this device failed to authenticate.
But there is not much more information in the error log.

What can I do to get more information from homeassistant?
Can/should I increase the log level?
Does the sensor get any information back from the api about the error (not just a 401)?

This is the code I am using on my sensor: (Sorry for the messy code, not quite done so haven’t cleaned everything yet)

code

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
#include <secrets.h>

String ssid = SECRET_SSID;
String password = SECRET_PASS;
String payload;
String apiKey = SECRET_HAKey;
String hostName = "esp12_mailboxsensor01";
IPAddress ip(192,168,1,154);
IPAddress gw(192,168,1,1);
IPAddress dns(192,168,1,2);
IPAddress subnet(255,255,255,0);

int sensorPin = 12;
int enablePin = 5;
int sensor;
int code;

//Enable getvcc
ADC_MODE(ADC_VCC);

void setup() {

  //Enable power signal as soon as possible
  pinMode(enablePin, OUTPUT);
  digitalWrite(enablePin, HIGH);

  pinMode(sensorPin,INPUT);

//  Serial.begin(115200);
//  Serial.println();
  HTTPClient http;

    //Connect to WIFI
  WiFi.mode(WIFI_STA);
  WiFi.hostname(hostName);
//  WiFi.config(ip, subnet, gw, dns);
  WiFi.begin(ssid, password);

  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
//    Serial.println("WiFi failed, retrying.");
  }

    //Check if update is needed
  http.begin("http://192.168.1.20:8123/api/states/input_boolean.ota_update");
  http.addHeader("Authorization", "Bearer "+apiKey);
  http.addHeader("Content-Type", "application/json");
  int httpCode = http.GET();

//  Serial.println(httpCode);

  if (httpCode > 0){
    payload = http.getString();
//    Serial.println(payload);
  }
  http.end();

  if (payload.indexOf("\"state\": \"on\"") >= 0){
    
    ESP8266WebServer httpServer(80);
    ESP8266HTTPUpdateServer httpUpdater;

    MDNS.begin(hostName);

    httpUpdater.setup(&httpServer);
    httpServer.begin();
  
    MDNS.addService("http", "tcp", 80);
    
    //Turn off the update toggle
    http.begin("http://192.168.1.20:8123/api/services/input_boolean/turn_off");
    http.addHeader("Authorization", "Bearer "+apiKey);
    http.addHeader("Content-Type", "application/json");
    http.POST("{\"entity_id\": \"input_boolean.ota_update\"}");
//     http.writeToStream(&Serial);
    http.end();

   //Handle the update, continue forever, after the update it will reboot
   //URL= ip/update
    while (true){
      httpServer.handleClient();
      MDNS.update();
      delay(10000);
//      Serial.println("hei");
    }
  }

  //Get the battery voltage and send to HA
  float vcc = ESP.getVcc();
  vcc = vcc / 1000;
  String svcc = String(vcc,3);
//  Serial.println(svcc);
  http.begin("http://192.168.1.20:8123/api/states/sensor."+hostName+"_vcc_voltage");
  http.addHeader("Authorization", "Bearer "+apiKey);
  http.addHeader("Content-Type", "application/json");
  code = http.POST("{\"state\": \""+svcc+"\", \"attributes\": {\"unit_of_measurement\": \"V\", \"icon\": \"mdi:flash\"}}");
//  while (code != 200 && code != 201 && code != 202) {
//    code = http.POST("{\"state\": \""+svcc+"\", \"attributes\": {\"unit_of_measurement\": \"V\", \"icon\": \"mdi:flash\"}}");
//  }
//  Serial.println(code);
//  http.writeToStream(&Serial);
//  Serial.println();
  http.end();
//  delay(3000);
  sensor = digitalRead(sensorPin);
  
  //Send new data to HA
  http.begin("http://192.168.1.20:8123/api/states/sensor."+hostName+"_opening");
  http.addHeader("Authorization", "Bearer "+apiKey);
  http.addHeader("Content-Type", "application/json");
  if (sensor == 0){
    code = http.POST("{\"state\": \"on\", \"attributes\": {\"device_class\": \"opening\", \"icon\": \"mdi:mailbox_open\"}}");
//    while (code != 200 && code != 201 && code != 202) {
//      code = http.POST("{\"state\": \"on\", \"attributes\": {\"device_class\": \"opening\", \"icon\": \"mdi:mailbox_open\"}}");
//    }
  }
  else if (sensor == 1) {
    code = http.POST("{\"state\": \"off\", \"attributes\": {\"device_class\": \"opening\", \"icon\": \"mdi:mailbox_up\"}}");
//    while (code != 200 && code != 201 && code != 202) {
//      code = http.POST("{\"state\": \"off\", \"attributes\": {\"device_class\": \"opening\", \"icon\": \"mdi:mailbox_up\"}}");
//    }
  }
  
//  Serial.println(sensor);
//  Serial.println(code);
//  http.writeToStream(&Serial);
//  Serial.println();
//  payload = http.getString();
  http.end();
  
  digitalWrite(enablePin, LOW);
  
}

void loop() {
  //Don't want to loop anything
}

Are you sure it’s that device? It could be another device.

That I am 100% sure of.
The error log states what ip address the device has, and if you see in the code there are some while loops that are commented out, when these were active the device would stay in that loop forever since the result code from Home Assistant were 401.

An update that might help others, even though it seems like it’s not a direct problem with home assistant, maybe just with how the api is handling same tcp ports on different posts. (I don’t have enough data to confirm this, but my solution seems to solve my problem)

First about getting more information from home assistant.
I did not find anything that I could do directly with home assistant, but arduino ide has a good debug tool that can be used with the serial interface.
Just choose debug port and debug level under the tools menu. (I chose HTTP_CLIENT under debug level)

By doing this I could see that another test server I had was giving me a 404 when ESP8266HTTPClient was reusing the same tcp port. (The test server was a very simple python webserver)
So to avoid this I had to use this code:

HTTPClient http;
http.setReuse(false);

I haven’t seen the problem since. I will update this if I get that problem again.