Skip to content

Instantly share code, notes, and snippets.

@mcspr
Last active December 25, 2019 21:04
Show Gist options
  • Save mcspr/eb68ada9df1e4e08ac3d2a129ac7c680 to your computer and use it in GitHub Desktop.
Save mcspr/eb68ada9df1e4e08ac3d2a129ac7c680 to your computer and use it in GitHub Desktop.
Show tasmota template as text
#include <cstdint>
#include <cstdio>
#include <cassert>
#include <string>
// Arduino-specific defines
#define ARDUINOJSON_ENABLE_PROGMEM 0
#define pgm_read_byte(x) static_cast<uint8_t>(*x)
#define PROGMEM
// Note: language is selected at compile time and we pick one
#include "lib/ArduinoJson-5.13.4/ArduinoJson.h"
#include "tasmota/tasmota_version.h"
#include "tasmota/i18n.h"
#include "tasmota/language/en-GB.h"
#include "tasmota/tasmota_template.h"
// c/p from tasmota/support.ino to avoid adding a bunch of stubs
// TODO: find how much stubs and just use `#include "tasmota/support.ino"`
char* GetTextIndexed(char* destination, size_t destination_size, uint32_t index, const char* haystack)
{
// Returns empty string if not found
// Returns text of found
char* write = destination;
const char* read = haystack;
index++;
while (index--) {
size_t size = destination_size -1;
write = destination;
char ch = '.';
while ((ch != '\0') && (ch != '|')) {
ch = pgm_read_byte(read++);
if (size && (ch != '|')) {
*write++ = ch;
size--;
}
}
if (0 == ch) {
if (index) {
write = destination;
}
break;
}
}
*write = '\0';
return destination;
}
bool ValidTemplateModule(uint32_t index)
{
for (uint32_t i = 0; i < sizeof(kModuleNiceList); i++) {
if (index == pgm_read_byte(kModuleNiceList + i)) {
return true;
}
}
return false;
}
// -----------------------------------------------------------------------------
int gpio_index[] = {
0, 1, 2, 3, 4, 5, 9, 10, 12, 13, 14, 15, 16
};
// Names are grouped in | separated char string
const char* gpioNames(int index) {
if ((index >= 0) && (index < GPIO_SENSOR_END)) {
return kSensorNames;
} else if ((index > GPIO_FIX_START) && (index < GPIO_MAX)) {
return kSensorNamesFixed;
}
return nullptr;
}
const char* adcNames(int index) {
if ((index > ADC0_NONE) && (index < ADC0_MAX)) {
return kAdc0Names;
}
return nullptr;
}
// Note: kModules contains all, kModuleNiceList contains enabled
const mytmplt* getModule(int base) {
if (base == 0) base = SONOFF_DEV;
if (!ValidTemplateModule(base)) return nullptr;
if ((base > 0) && (base < MAXMODULE)) {
return &kModules[base];
}
return nullptr;
}
constexpr size_t GPIO_MAP_SIZE = (sizeof(gpio_index) / sizeof(gpio_index[0]));
int main(int argc, char** argv) {
if (argc != 2) {
for (int index = 0; index < (sizeof(kModules) / sizeof(kModules[0])); ++index) {
printf("%03d %s\n", index, kModules[index].name);
}
return 1;
}
DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parse(argv[1]);
std::string name("Generic");
int flag = -1;
int base = -1;
uint8_t mapping[GPIO_MAP_SIZE] = {0};
if (root[D_JSON_NAME].success()) {
name = root[D_JSON_NAME].as<std::string>();
}
if (root[D_JSON_FLAG].success()) {
flag = root[D_JSON_FLAG].as<int>();
}
if (root[D_JSON_BASE].success()) {
base = root[D_JSON_BASE].as<int>() - 1;
};
if (base >= 0) {
auto module = getModule(base);
if (module) {
memcpy(mapping, module->gp.io, sizeof(mapping));
}
name += " (based on ";
name += module->name;
name += ")";
}
if (root[D_JSON_GPIO].success()) {
JsonArray& values = root["GPIO"];
assert(values.size() == GPIO_MAP_SIZE);
for (auto index = 0; index < GPIO_MAP_SIZE; ++index) {
auto tasmota_index = values[index].as<int>();
if (mapping[index] == GPIO_USER) {
mapping[index] = tasmota_index;
}
}
}
printf("%s\n", name.c_str());
if (flag > 0) {
char buffer[64] = {0};
auto names = adcNames(flag);
GetTextIndexed(buffer, sizeof(buffer), flag, names);
printf("ADC0 %s\n", buffer);
}
for (size_t index = 0; index < GPIO_MAP_SIZE; ++index) {
if (mapping[index] == GPIO_NONE) continue;
char buffer[256] = {0};
auto names = gpioNames(mapping[index]);
if (names) {
GetTextIndexed(buffer, sizeof(buffer), mapping[index], names);
} else {
snprintf(buffer, sizeof(buffer), "%s", "UNKNOWN");
}
printf("GPIO%2d -> %s\n", gpio_index[index], buffer);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment