Browse Source

Retry Redis connection a few times on failure; add null display spec; try to clear boot count upon successful OTA; bump to 0.2.3.8

tags/0.2.3.8
Ryan Joseph 1 year ago
parent
commit
7e7e238bc2
7 changed files with 80 additions and 25 deletions
  1. +35
    -4
      zero_watch.ino
  2. +1
    -1
      zw_common.h
  3. +8
    -3
      zw_displays.cpp
  4. +5
    -3
      zw_logging.h
  5. +3
    -10
      zw_provision.cpp
  6. +26
    -4
      zw_redis.cpp
  7. +2
    -0
      zw_redis.h

+ 35
- 4
zero_watch.ino View File

@@ -197,8 +197,11 @@ bool processUpdate(String &updateJson, ZWRedisResponder &responder)
zlog("Starting OTA update of %0.2fKB\n", (szb / 1024.0));
zlog("Image source (md5=%s):\n\t%s\n", md5, fqUrl);

if (runUpdate(fqUrl, md5, szb, preUpdateIRQDisableFunc,
[]() { return gRedis->postCompletedUpdate(); }))
if (runUpdate(fqUrl, md5, szb, preUpdateIRQDisableFunc, []() {
if (gRedis->incrementBootcount(true) != 0)
zlog("WARNING: unable to reset bootcount!\n");
return gRedis->postCompletedUpdate();
}))
{
zlog("OTA update wrote successfully! Restarting in %d seconds...\n",
OTA_RESET_DELAY);
@@ -426,12 +429,40 @@ void setup()

gRedis = new ZWRedis(gHostname, redisConfig);

if (!gRedis->connect())
#define NUM_RETRIES 5
int redisConnectRetries = NUM_RETRIES;
float redisWaitRetryTime = 50;
float redisWaitRetryBackoffMult = 1.37;

int errnos[NUM_RETRIES];
while (!gRedis->connect() && --redisConnectRetries)
{
// seen: ECONNABORTED (makes sense)
errnos[NUM_RETRIES - (redisConnectRetries + 1)] = errno;
zlog("Redis connect failed but %d retries left, waiting %0.2fs and trying again (m=%0.3f)\n",
redisConnectRetries, redisWaitRetryTime, redisWaitRetryBackoffMult);
redisWaitRetryTime *= redisWaitRetryBackoffMult;
redisWaitRetryBackoffMult *= redisWaitRetryBackoffMult;
delay(redisWaitRetryTime);
}

if (!redisConnectRetries)
{
zlog("ERROR: redis init failed!");
zlog("ERROR: redis init failed!\n");
__haltOrCatchFire();
}

if (redisConnectRetries != NUM_RETRIES)
{
String seenErrnos = "";
for (int i = 0; i < NUM_RETRIES && errnos[i]; i++)
seenErrnos += String(errnos[i]) + " ";
zlog("Redis connection had to be retried %d times. Saw: %s\n",
NUM_RETRIES - redisConnectRetries, seenErrnos.c_str());
gRedis->logCritical("Redis connection had to be retried %d times. Saw: %s",
NUM_RETRIES - redisConnectRetries, seenErrnos.c_str());
}

zlog("Redis connection established, reading config...\n");

readConfigAndUserKeys();


+ 1
- 1
zw_common.h View File

@@ -1,7 +1,7 @@
#ifndef __ZW_COMMON__H__
#define __ZW_COMMON__H__

#define ZEROWATCH_VER "0.2.3.0"
#define ZEROWATCH_VER "0.2.3.8"
#define DEBUG 1

struct ZWAppConfig


+ 8
- 3
zw_displays.cpp View File

@@ -84,6 +84,10 @@ DisplaySpec gDisplays_ETEST[] = {
{33, 32, nullptr, {"zero:sensor:DHTXX:relative_humidity:.list", 0, 5, 0.0, 0, noop, d_humidPercent}},
{-1, -1, nullptr, {nullptr, -1, -1, -1.0, -1, noop, d_def}}};

DisplaySpec gDisplays_NULLSPEC[] = {
{-1, -1, nullptr, {nullptr, -1, -1, -1.0, -1, noop, d_def}}
};

DisplaySpec *zwdisplayInit(String &hostname)
{
DisplaySpec *retSpec = NULL;
@@ -96,12 +100,13 @@ DisplaySpec *zwdisplayInit(String &hostname)
{
retSpec = gDisplays_AMINI;
}
else if (hostname.equals("etest") || hostname.equals("espresso"))
else if (hostname.equals("etest"))
{
retSpec = gDisplays_ETEST;
}
else {
zlog("zwdisplayInit: ERROR unconfigured hostname '%s'\n", hostname.c_str());
else
{
retSpec = gDisplays_NULLSPEC;
}

if (retSpec)


+ 5
- 3
zw_logging.h View File

@@ -8,14 +8,16 @@ extern void (*gPublishLogsEmit)(const char* fmt, ...);

#define dprint(fmt, ...) do { \
if (gConfig.debug) { \
Serial.printf(fmt, ##__VA_ARGS__); \
Serial.printf("[%s:%d] " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
} } while (0)

#define zlog(fmt, ...) do { \
if (gConfig.publishLogs && gPublishLogsEmit) { \
gPublishLogsEmit(fmt, ##__VA_ARGS__); \
if (gConfig.debug) gPublishLogsEmit("[%s:%d] " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
else gPublishLogsEmit(fmt, ##__VA_ARGS__); \
} else { \
Serial.printf(fmt, ##__VA_ARGS__); \
if (gConfig.debug) Serial.printf("[%s:%d] " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
else Serial.printf(fmt, ##__VA_ARGS__); \
} } while (0)

#endif

+ 3
- 10
zw_provision.cpp View File

@@ -37,12 +37,12 @@ void CFG_EEPROM_read()
dprint("CFG_EEPROM_read: reading %d for lengths\n", CFG_HEADER_SIZE);
zwassert(EEPROM.readBytes(CFG_EEPROM_ADDR, lengths, CFG_HEADER_SIZE) == CFG_HEADER_SIZE);

dprint("CFG_EEPROM_read: LENGTHS: ");
String lengthsStr = "";
for (int i = 0; i < CFG_ELEMENTS; i++)
{
dprint("%d ", lengths[i]);
lengthsStr += String(lengths[i]) + " ";
}
dprint("\n");
dprint("CFG_EEPROM_read: LENGTHS: %s\n", lengthsStr.c_str());

EEPROMCFG_WiFiSSID = (char *)malloc(lengths[0] + 1);
bzero(EEPROMCFG_WiFiSSID, lengths[0] + 1);
@@ -267,11 +267,4 @@ void verifyProvisioning()
zlog("\n\nThis device is not provisioned! Please use ZEROWATCH_PROVISIONING_MODE to initialize it.");
__haltOrCatchFire();
}

// TODO: better place for this? I'm sure there is one...
if (!(gHostname.equals("ezero") || gHostname.equals("amini") || gHostname.equals("etest") || gHostname.equals("espresso")))
{
zlog("ERROR: Unrecognized hostname '%s', halting forever!\n", __hnShadowBuf);
__haltOrCatchFire();
}
}

+ 26
- 4
zw_redis.cpp View File

@@ -1,5 +1,6 @@
#include "zw_redis.h"
#include "zw_logging.h"
#include <errno.h>

#define REDIS_KEY(x) String(hostname + x).c_str()

@@ -13,7 +14,8 @@ bool ZWRedis::connect()

if (!connection.wifi->connect(configuration.host, configuration.port))
{
dprint("Redis connection failed");
dprint("Redis connection failed (wifi): %s (%d)\n", strerror(errno), errno);
perror("redis: wifi");
delete connection.wifi, connection.wifi = nullptr;
return false;
}
@@ -77,8 +79,12 @@ bool ZWRedis::heartbeat(int expire)
int ZWRedis::incrementBootcount(bool reset)
{
REDIS_KEY_CREATE_LOCAL(":bootcount");
auto bc = connection.redis->get(redisKey_local);
auto bcNext = (reset ? 0 : bc.toInt()) + 1;
int bcNext = 0;

if (!reset)
{
bcNext = connection.redis->get(redisKey_local).toInt() + 1;
}

if (connection.redis->set(redisKey_local, String(bcNext).c_str()))
{
@@ -203,6 +209,22 @@ bool ZWRedis::registerDevice(const char* registryName, const char* hostname, con
return connection.redis->hset(registryName, ident, hostname);
}

void ZWRedis::logCritical(const char* format, ...)
{
#define BUFLEN 2048
char _buf[BUFLEN];
bzero(_buf, BUFLEN);
va_list args;
va_start(args, format);
vsnprintf(_buf, BUFLEN, format, args);
va_end(args);
// SHIT! need LPUSH
//connection.redis->lset
// I guess this'll work ok for now...
static unsigned long __keyCount = 0;
connection.redis->hset(REDIS_KEY(":criticalLog"), String(++__keyCount).c_str(), _buf);
}

void ZWRedisResponder::setValue(const char *format, ...)
{
#define BUFLEN 2048
@@ -211,6 +233,6 @@ void ZWRedisResponder::setValue(const char *format, ...)
va_list args;
va_start(args, format);
vsnprintf(_buf, BUFLEN, format, args);
redis.responderHelper(key.c_str(), _buf, expire);
va_end(args);
redis.responderHelper(key.c_str(), _buf, expire);
}

+ 2
- 0
zw_redis.h View File

@@ -97,6 +97,8 @@ public:

bool registerDevice(const char* registryName, const char* hostname, const char* ident);

void logCritical(const char* fmt, ...);

private:
ZWAppConfig _lastReadConfig;
};


Loading…
Cancel
Save