mirror of
https://github.com/xoseperez/espurna.git
synced 2026-03-06 16:27:12 +01:00
Refactor WebUI: - remove jquery dependency from the base custom.js and use vanilla JS - remove jquery + jquery-datatables dependency from the RFM69 module - replace jquery-datatables handlers with pure-css table + some basic cell filtering (may be incomplete, but tbh it is not worth additional 50Kb to the .bin size) - introduce a common way to notify about the app errors, show small text notification at the top of the page instead of relying on user to find out about errors by using the Web Developer Tools - replace <span name=...> with <span data-settings-key=...> - replace <div> templates with <template>, disallowing modification without an explicit DOM clone - run `eslint` on html/custom.js and `html-validate` on html/index.html, and fix issues detected by both tools Streamline settings group handling in custom.js & index.html - drop module-specific button-add-... in favour of button-add-settings-group - only enforce data-settings-max requirement when the property actually exists - re-create label for=... and input id=... when settings group is modified, so checkboxes refer to the correct element - introduce additional data-... properties to generalize settings group additions - introduce Enumerable object to track some common list elements for <select>, allow to re-create <option> list when messages come in different order Minor fixes that also came with this: - fix relay code incorrectly parsing the payload, causing no relay names to be displayed in the SWITCHES panel - fix scheduler code accidentally combining keys b/c of the way C parses string literals on separate lines, without any commas in-between - thermostat should not reference tmpUnit directly in the webui, replace with module-specific thermostatUnit that is handled on the device itself - fix index.html initial setup invalid adminPass ids - fix index.html layout when removing specific schedules
195 lines
4.1 KiB
C++
195 lines
4.1 KiB
C++
/*
|
|
|
|
GPIO MODULE
|
|
|
|
Copyright (C) 2017-2019 by Xose Pérez <xose dot perez at gmail dot com>
|
|
|
|
*/
|
|
|
|
#include "espurna.h"
|
|
|
|
// --------------------------------------------------------------------------
|
|
|
|
#include <bitset>
|
|
#include <utility>
|
|
|
|
#include "gpio_pin.h"
|
|
#include "mcp23s08_pin.h"
|
|
|
|
#include "ws.h"
|
|
|
|
namespace settings {
|
|
namespace internal {
|
|
|
|
template <>
|
|
GpioType convert(const String& value) {
|
|
auto type = static_cast<GpioType>(value.toInt());
|
|
switch (type) {
|
|
case GpioType::Hardware:
|
|
case GpioType::Mcp23s08:
|
|
return type;
|
|
case GpioType::None:
|
|
break;
|
|
}
|
|
|
|
return GpioType::None;
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace settings
|
|
|
|
namespace {
|
|
|
|
class GpioHardware : public GpioBase {
|
|
public:
|
|
constexpr static size_t Pins { 17ul };
|
|
|
|
using Mask = std::bitset<Pins>;
|
|
using Pin = GpioPin;
|
|
|
|
GpioHardware() {
|
|
// https://github.com/espressif/esptool/blob/f04d34bcab29ace798d2d3800ba87020cccbbfdd/esptool.py#L1060-L1070
|
|
// "One or the other efuse bit is set for ESP8285"
|
|
// https://github.com/espressif/ESP8266_RTOS_SDK/blob/3c055779e9793e5f082afff63a011d6615e73639/components/esp8266/include/esp8266/efuse_register.h#L20-L21
|
|
// "define EFUSE_IS_ESP8285 (1 << 4)"
|
|
const uint32_t efuse_blocks[4] {
|
|
READ_PERI_REG(0x3ff00050),
|
|
READ_PERI_REG(0x3ff00054),
|
|
READ_PERI_REG(0x3ff00058),
|
|
READ_PERI_REG(0x3ff0005c)
|
|
};
|
|
|
|
_esp8285 = (
|
|
(efuse_blocks[0] & (1 << 4))
|
|
|| (efuse_blocks[2] & (1 << 16))
|
|
);
|
|
}
|
|
|
|
const char* id() const override {
|
|
return "hardware";
|
|
}
|
|
|
|
size_t pins() const override {
|
|
return Pins;
|
|
}
|
|
|
|
bool lock(unsigned char index) const override {
|
|
return _lock[index];
|
|
}
|
|
|
|
void lock(unsigned char index, bool value) override {
|
|
_lock.set(index, value);
|
|
}
|
|
|
|
bool valid(unsigned char index) const override {
|
|
switch (index) {
|
|
case 0 ... 5:
|
|
return true;
|
|
case 9:
|
|
case 10:
|
|
return _esp8285;
|
|
case 12 ... 16:
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
BasePinPtr pin(unsigned char index) {
|
|
return std::make_unique<GpioPin>(index);
|
|
}
|
|
|
|
private:
|
|
bool _esp8285 { false };
|
|
Mask _lock;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
String BasePin::description() const {
|
|
char buffer[64];
|
|
snprintf_P(buffer, sizeof(buffer), PSTR("%s @ GPIO%02u"), id(), pin());
|
|
return buffer;
|
|
}
|
|
|
|
BasePin::~BasePin() {
|
|
}
|
|
|
|
GpioBase& hardwareGpio() {
|
|
static GpioHardware gpio;
|
|
return gpio;
|
|
}
|
|
|
|
GpioBase* gpioBase(GpioType type) {
|
|
GpioBase* ptr { nullptr };
|
|
|
|
switch (type) {
|
|
case GpioType::Hardware:
|
|
ptr = &hardwareGpio();
|
|
break;
|
|
case GpioType::Mcp23s08:
|
|
#if MCP23S08_SUPPORT
|
|
ptr = &mcp23s08Gpio();
|
|
#endif
|
|
break;
|
|
case GpioType::None:
|
|
break;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
BasePinPtr gpioRegister(GpioBase& base, unsigned char gpio) {
|
|
BasePinPtr result;
|
|
|
|
if (gpioLock(base, gpio)) {
|
|
result = std::move(base.pin(gpio));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
BasePinPtr gpioRegister(unsigned char gpio) {
|
|
return gpioRegister(hardwareGpio(), gpio);
|
|
}
|
|
|
|
#if WEB_SUPPORT
|
|
|
|
void _gpioWebSocketOnVisible(JsonObject& root) {
|
|
JsonObject& config = root.createNestedObject("gpioConfig");
|
|
|
|
constexpr GpioType known_types[] {
|
|
GpioType::Hardware,
|
|
#if MCP23S08_SUPPORT
|
|
GpioType::Mcp23s08,
|
|
#endif
|
|
};
|
|
|
|
JsonArray& types = config.createNestedArray("types");
|
|
|
|
for (auto& type : known_types) {
|
|
auto* base = gpioBase(type);
|
|
if (base) {
|
|
JsonArray& entry = types.createNestedArray();
|
|
entry.add(base->id());
|
|
entry.add(static_cast<int>(type));
|
|
|
|
JsonArray& pins = config.createNestedArray(base->id());
|
|
for (unsigned char pin = 0; pin < base->pins(); ++pin) {
|
|
if (base->valid(pin)) {
|
|
pins.add(pin);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
void gpioSetup() {
|
|
#if WEB_SUPPORT
|
|
wsRegister()
|
|
.onVisible(_gpioWebSocketOnVisible);
|
|
#endif
|
|
}
|