Browse Source

* made ethernet pinout configurable

* combined common network functions into class
* seperated wifi station from AP mode
pull/1549/head
lumapu 10 months ago
parent
commit
a44a5833ca
  1. 48
      src/config/settings.h
  2. 2
      src/eth/ahoyeth.cpp
  3. 82
      src/network/AhoyEthernet.h
  4. 8
      src/network/AhoyEthernetSpi.h
  5. 194
      src/network/AhoyNetwork.h
  6. 29
      src/network/AhoyNetworkHelper.h
  7. 70
      src/network/AhoyWifiAp.h
  8. 14
      src/web/RestApi.h
  9. 64
      src/web/html/setup.html
  10. 5
      src/web/lang.json
  11. 47
      src/web/web.h
  12. 2
      src/wifi/ahoywifi.h

48
src/config/settings.h

@ -63,6 +63,19 @@ typedef struct {
uint8_t gateway[4]; // standard gateway
} cfgIp_t;
#if defined(ETHERNET)
typedef struct {
bool enabled;
uint8_t pinCs;
uint8_t pinSclk;
uint8_t pinMiso;
uint8_t pinMosi;
uint8_t pinIrq;
uint8_t pinRst;
} cfgEth_t;
#endif
typedef struct {
char deviceName[DEVNAME_LEN];
char adminPwd[PWD_LEN];
@ -72,15 +85,16 @@ typedef struct {
uint8_t region;
int8_t timezone;
char apPwd[PWD_LEN];
#if !defined(ETHERNET)
// wifi
char stationSsid[SSID_LEN];
char stationPwd[PWD_LEN];
char apPwd[PWD_LEN];
bool isHidden;
#endif /* !defined(ETHERNET) */
cfgIp_t ip;
cfgEth_t eth;
} cfgSys_t;
typedef struct {
@ -393,7 +407,17 @@ class settings {
snprintf(mCfg.sys.apPwd, PWD_LEN, WIFI_AP_PWD);
mCfg.sys.isHidden = false;
}
#endif /* !defined(ETHERNET) */
#endif
#if defined(ETHERNET)
mCfg.sys.eth.enabled = false;
mCfg.sys.eth.pinCs = DEF_ETH_CS_PIN;
mCfg.sys.eth.pinSclk = DEF_ETH_SCK_PIN;
mCfg.sys.eth.pinMiso = DEF_ETH_MISO_PIN;
mCfg.sys.eth.pinMosi = DEF_ETH_MOSI_PIN;
mCfg.sys.eth.pinIrq = DEF_ETH_IRQ_PIN;
mCfg.sys.eth.pinRst = DEF_ETH_RST_PIN;
#endif
snprintf(mCfg.sys.deviceName, DEVNAME_LEN, DEF_DEVICE_NAME);
mCfg.sys.region = 0; // Europe
@ -544,6 +568,16 @@ class settings {
ah::ip2Char(mCfg.sys.ip.dns1, buf); obj[F("dns1")] = String(buf);
ah::ip2Char(mCfg.sys.ip.dns2, buf); obj[F("dns2")] = String(buf);
ah::ip2Char(mCfg.sys.ip.gateway, buf); obj[F("gtwy")] = String(buf);
#if defined(ETHERNET)
obj[F("en")] = mCfg.sys.eth.enabled;
obj[F("cs")] = mCfg.sys.eth.pinCs;
obj[F("sclk")] = mCfg.sys.eth.pinSclk;
obj[F("miso")] = mCfg.sys.eth.pinMiso;
obj[F("mosi")] = mCfg.sys.eth.pinMosi;
obj[F("irq")] = mCfg.sys.eth.pinIrq;
obj[F("rst")] = mCfg.sys.eth.pinRst;
#endif
} else {
#if !defined(ETHERNET)
getChar(obj, F("ssid"), mCfg.sys.stationSsid, SSID_LEN);
@ -567,6 +601,16 @@ class settings {
if(mCfg.sys.protectionMask == 0)
mCfg.sys.protectionMask = DEF_PROT_INDEX | DEF_PROT_LIVE | DEF_PROT_SERIAL | DEF_PROT_SETUP
| DEF_PROT_UPDATE | DEF_PROT_SYSTEM | DEF_PROT_API | DEF_PROT_MQTT | DEF_PROT_HISTORY;
#if defined(ETHERNET)
getVal<bool>(obj, F("en"), &mCfg.sys.eth.enabled);
getVal<uint8_t>(obj, F("cs"), &mCfg.sys.eth.pinCs);
getVal<uint8_t>(obj, F("sclk"), &mCfg.sys.eth.pinSclk);
getVal<uint8_t>(obj, F("miso"), &mCfg.sys.eth.pinMiso);
getVal<uint8_t>(obj, F("mosi"), &mCfg.sys.eth.pinMosi);
getVal<uint8_t>(obj, F("irq"), &mCfg.sys.eth.pinIrq);
getVal<uint8_t>(obj, F("rst"), &mCfg.sys.eth.pinRst);
#endif
}
}

2
src/eth/ahoyeth.cpp

@ -31,7 +31,7 @@ void ahoyeth::setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNe
WiFi.onEvent([this](WiFiEvent_t event, arduino_event_info_t info) -> void { this->onEthernetEvent(event, info); });
Serial.flush();
mEthSpi.begin(DEF_ETH_MISO_PIN, DEF_ETH_MOSI_PIN, DEF_ETH_SCK_PIN, DEF_ETH_CS_PIN, DEF_ETH_IRQ_PIN, DEF_ETH_RST_PIN);
mEthSpi.begin(config->sys.eth.pinMiso, config->sys.eth.pinMosi, config->sys.eth.pinSclk, config->sys.eth.pinCs, config->sys.eth.pinIrq, config->sys.eth.pinRst);
if(mConfig->sys.ip.ip[0] != 0) {
IPAddress ip(mConfig->sys.ip.ip);

82
src/network/AhoyEthernet.h

@ -0,0 +1,82 @@
//-----------------------------------------------------------------------------
// 2024 Ahoy, https://ahoydtu.de
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//-----------------------------------------------------------------------------
#ifndef __AHOY_ETHERNET_H__
#define __AHOY_ETHERNET_H__
#include <functional>
#include <AsyncUDP.h>
#include <ETH.h>
#include "AhoyEthernetSpi.h"
#include "AhoyEthernet.h"
class AhoyEthernet : public AhoyNetwork {
public:
void begin() override {
setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool {
return ETH.config(ip, gateway, mask, dns1, dns2);
});
}
void tickNetworkLoop() override {
switch(mState) {
case NetworkState::DISCONNECTED:
break;
}
}
private:
/*switch (event) {
case ARDUINO_EVENT_ETH_START:
DPRINTLN(DBG_VERBOSE, F("ETH Started"));
if(String(mConfig->sys.deviceName) != "")
ETH.setHostname(mConfig->sys.deviceName);
else
ETH.setHostname(F("ESP32_W5500"));
break;
case ARDUINO_EVENT_ETH_CONNECTED:
DPRINTLN(DBG_VERBOSE, F("ETH Connected"));
break;
case ARDUINO_EVENT_ETH_GOT_IP:
if (!mEthConnected) {
welcome(ETH.localIP().toString(), F(" (Station)"));
mEthConnected = true;
mOnNetworkCB(true);
}
if (!MDNS.begin(mConfig->sys.deviceName)) {
DPRINTLN(DBG_ERROR, F("Error setting up MDNS responder!"));
} else {
DBGPRINT(F("mDNS established: "));
DBGPRINT(mConfig->sys.deviceName);
DBGPRINTLN(F(".local"));
}
break;
case ARDUINO_EVENT_ETH_DISCONNECTED:
DPRINTLN(DBG_INFO, F("ETH Disconnected"));
mEthConnected = false;
mUdp.close();
mOnNetworkCB(false);
break;
case ARDUINO_EVENT_ETH_STOP:
DPRINTLN(DBG_INFO, F("ETH Stopped"));
mEthConnected = false;
mUdp.close();
mOnNetworkCB(false);
break;
default:
break;
}*/
};
#endif /*__AHOY_ETHERNET_H__*/

8
src/eth/ethSpi.h → src/network/AhoyEthernetSpi.h

@ -1,6 +1,6 @@
//-----------------------------------------------------------------------------
// 2024 Ahoy, https://www.mikrocontroller.net/topic/525778
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
// 2024 Ahoy, https://ahoydtu.de
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//-----------------------------------------------------------------------------
#if defined(ETHERNET)
@ -18,10 +18,10 @@
void tcpipInit();
void add_esp_interface_netif(esp_interface_t interface, esp_netif_t* esp_netif);
class EthSpi {
class AhoyEthernetSpi {
public:
EthSpi() :
AhoyEthernetSpi() :
eth_handle(nullptr),
eth_netif(nullptr) {}

194
src/network/AhoyNetwork.h

@ -0,0 +1,194 @@
//-----------------------------------------------------------------------------
// 2024 Ahoy, https://ahoydtu.de
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//-----------------------------------------------------------------------------
#ifndef __AHOY_NETWORK_H__
#define __AHOY_NETWORK_H__
#include "AhoyNetworkHelper.h"
#include <WiFiUdp.h>
#include "../config/settings.h"
#include "../utils/helper.h"
#if defined(ESP32)
#include <ESPmDNS.h>
#else
#include <ESP8266mDNS.h>
#endif
#define NTP_PACKET_SIZE 48
class AhoyNetwork {
public:
typedef std::function<void(bool)> OnNetworkCB;
typedef std::function<void(bool)> OnTimeCB;
public:
void setup(settings_t *config, uint32_t *utcTimestamp, OnNetworkCB onNetworkCB, OnTimeCB onTimeCB) {
mConfig = config;
mUtcTimestamp = utcTimestamp;
mOnNetworkCB = onNetworkCB;
mOnTimeCB = onTimeCB;
#if defined(ESP32)
WiFi.onEvent([this](WiFiEvent_t event) -> void {
this->OnEvent(event);
});
#else
wifiConnectHandler = WiFi.onStationModeConnected(
[this](const WiFiEventStationModeConnected& event) -> void {
OnEvent(SYSTEM_EVENT_STA_CONNECTED);
});
wifiGotIPHandler = WiFi.onStationModeGotIP(
[this](const WiFiEventStationModeGotIP& event) -> void {
OnEvent(SYSTEM_EVENT_STA_GOT_IP);
});
wifiDisconnectHandler = WiFi.onStationModeDisconnected(
[this](const WiFiEventStationModeDisconnected& event) -> void {
OnEvent(SYSTEM_EVENT_STA_DISCONNECTED);
});
#endif
}
bool isConnected() const {
return (mStatus == NetworkState.CONNECTED);
}
bool updateNtpTime(void) {
if(CONNECTED != mStatus)
return;
if (!mUdp.connected()) {
IPAddress timeServer;
if (!WiFi.hostByName(mConfig->ntp.addr, timeServer))
return false;
if (!mUdp.connect(timeServer, mConfig->ntp.port))
return false;
}
mUdp.onPacket([this](AsyncUDPPacket packet) {
this->handleNTPPacket(packet);
});
sendNTPpacket(timeServer);
return true;
}
public:
virtual void begin() = 0;
virtual void tickNetworkLoop() = 0;
virtual void connectionEvent(WiFiStatus_t status) = 0;
protected:
void setupIp(void) {
if(mConfig->sys.ip.ip[0] != 0) {
IPAddress ip(mConfig->sys.ip.ip);
IPAddress mask(mConfig->sys.ip.mask);
IPAddress dns1(mConfig->sys.ip.dns1);
IPAddress dns2(mConfig->sys.ip.dns2);
IPAddress gateway(mConfig->sys.ip.gateway);
if(!ETH.config(ip, gateway, mask, dns1, dns2))
DPRINTLN(DBG_ERROR, F("failed to set static IP!"));
}
}
void OnEvent(WiFiEvent_t event) {
switch(event) {
case SYSTEM_EVENT_STA_CONNECTED:
[[fallthrough]];
case ARDUINO_EVENT_ETH_CONNECTED:
if(NetworkState::CONNECTED != mStatus) {
mStatus = NetworkState::CONNECTED;
DPRINTLN(DBG_INFO, F("Network connected"));
}
break;
case SYSTEM_EVENT_STA_GOT_IP:
[[fallthrough]];
case ARDUINO_EVENT_ETH_GOT_IP:
mStatus = NetworkState::GOT_IP;
break;
case ARDUINO_EVENT_WIFI_STA_LOST_IP:
[[fallthrough]];
case ARDUINO_EVENT_WIFI_STA_STOP:
[[fallthrough]];
case SYSTEM_EVENT_STA_DISCONNECTED:
[[fallthrough]];
case ARDUINO_EVENT_ETH_STOP:
[[fallthrough]];
case ARDUINO_EVENT_ETH_DISCONNECTED:
mStatus = NetworkState::DISCONNECTED;
break;
default:
break;
}
}
private:
void sendNTPpacket(IPAddress& address) {
//DPRINTLN(DBG_VERBOSE, F("wifi::sendNTPpacket"));
uint8_t buf[NTP_PACKET_SIZE];
memset(buf, 0, NTP_PACKET_SIZE);
buf[0] = 0b11100011; // LI, Version, Mode
buf[1] = 0; // Stratum
buf[2] = 6; // Max Interval between messages in seconds
buf[3] = 0xEC; // Clock Precision
// bytes 4 - 11 are for Root Delay and Dispersion and were set to 0 by memset
buf[12] = 49; // four-byte reference ID identifying
buf[13] = 0x4E;
buf[14] = 49;
buf[15] = 52;
//mUdp.beginPacket(address, 123); // NTP request, port 123
mUdp.write(buf, NTP_PACKET_SIZE);
//mUdp.endPacket();
}
void handleNTPPacket(AsyncUDPPacket packet) {
char buf[80];
memcpy(buf, packet.data(), sizeof(buf));
unsigned long highWord = word(buf[40], buf[41]);
unsigned long lowWord = word(buf[42], buf[43]);
// combine the four bytes (two words) into a long integer
// this is NTP time (seconds since Jan 1 1900):
unsigned long secsSince1900 = highWord << 16 | lowWord;
*mUtcTimestamp = secsSince1900 - 2208988800UL; // UTC time
DPRINTLN(DBG_INFO, "[NTP]: " + ah::getDateTimeStr(*mUtcTimestamp) + " UTC");
mOnTimeCB(true);
mUdp.close();
}
protected:
enum class NetworkState : uint8_t {
DISCONNECTED,
CONNECTING,
CONNECTED,
IN_AP_MODE,
GOT_IP,
IN_STA_MODE,
RESET,
SCAN_READY
};
protected:
settings_t *mConfig = nullptr;
uint32_t *mUtcTimestamp = nullptr;
OnNetworkCB mOnNetworkCB;
OnTimeCB mOnTimeCB;
NetworkState mStatus = NetworkState.DISCONNECTED;
WiFiUDP mUdp; // for time server
DNSServer mDns;
};
#endif /*__AHOY_NETWORK_H__*/

29
src/network/AhoyNetworkHelper.h

@ -0,0 +1,29 @@
//-----------------------------------------------------------------------------
// 2024 Ahoy, https://ahoydtu.de
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//-----------------------------------------------------------------------------
#ifndef __AHOY_NETWORK_HELPER_H__
#define __AHOY_NETWORK_HELPER_H__
#include "../utils/dbg.h"
#include <Arduino.h>
#include <WiFiType.h>
#include <WiFi.h>
#include <DNSServer.h>
namespace ah {
void welcome(String ip, String info) {
DBGPRINTLN(F("\n\n-------------------"));
DBGPRINTLN(F("Welcome to AHOY!"));
DBGPRINT(F("\npoint your browser to http://"));
DBGPRINT(ip);
DBGPRINT(" (");
DBGPRINT(info);
DBGPRINTLN(")");
DBGPRINTLN(F("to configure your device"));
DBGPRINTLN(F("-------------------\n"));
}
}
#endif /*__AHOY_NETWORK_HELPER_H__*/

70
src/network/AhoyWifiAp.h

@ -0,0 +1,70 @@
//-----------------------------------------------------------------------------
// 2024 Ahoy, https://ahoydtu.de
// Creative Commons - https://creativecommons.org/licenses/by-nc-sa/4.0/deed
//-----------------------------------------------------------------------------
#ifndef __AHOY_WIFI_AP_H__
#define __AHOY_WIFI_AP_H__
#include "../utils/dbg.h"
#include <Arduino.h>
#include "../config/settings.h"
#include "AhoyNetworkHelper.h"
class AhoyWifiAp {
public:
AhoyWifiAp() : mIp(192, 168, 4, 1) {}
void setup(cfgSys_t *cfg) {
mCfg = cfg;
}
void tickLoop() {
if(mEnabled)
mDns.processNextRequest();
}
void enable() {
ah::welcome(mIp.toString(), String(F("Password: ") + String(mCfg->apPwd)));
if('\0' == mCfg->deviceName[0])
snprintf(mCfg->deviceName, DEVNAME_LEN, "%s", DEF_DEVICE_NAME);
WiFi.hostname(mCfg->deviceName);
#if defined(ETHERNET)
WiFi.mode(WIFI_AP);
#else
WiFi.mode(WIFI_AP_STA);
#endif
WiFi.softAPConfig(mIp, mIp, IPAddress(255, 255, 255, 0));
WiFi.softAP(WIFI_AP_SSID, mCfg->apPwd);
mDns.start(53, "*", mIp);
mEnabled = true;
tickLoop();
}
void disable() {
mDns.stop();
WiFi.softAPdisconnect();
#if defined(ETHERNET)
WiFi.mode(WIFI_OFF);
#else
WiFi.mode(WIFI_STA);
#endif
mEnabled = false;
}
bool getEnable() const {
return mEnabled;
}
private:
cfgSys_t *mCfg = nullptr;
DNSServer mDns;
IPAddress mIp;
bool mEnabled = false;
};
#endif /*__AHOY_WIFI_AP_H__*/

14
src/web/RestApi.h

@ -381,6 +381,8 @@ class RestApi {
obj[F("hidd")] = mConfig->sys.isHidden;
obj[F("mac")] = WiFi.macAddress();
obj[F("wifi_channel")] = WiFi.channel();
#else
getEthernet(obj.createNestedObject(F("eth")));
#endif /* !defined(ETHERNET) */
obj[F("device_name")] = mConfig->sys.deviceName;
obj[F("dark_mode")] = (bool)mConfig->sys.darkMode;
@ -762,6 +764,18 @@ class RestApi {
}
#endif
#if defined(ETHERNET)
void getEthernet(JsonObject obj) {
obj[F("en")] = mConfig->sys.eth.enabled;
obj[F("cs")] = mConfig->sys.eth.pinCs;
obj[F("sclk")] = mConfig->sys.eth.pinSclk;
obj[F("miso")] = mConfig->sys.eth.pinMiso;
obj[F("mosi")] = mConfig->sys.eth.pinMosi;
obj[F("irq")] = mConfig->sys.eth.pinIrq;
obj[F("reset")] = mConfig->sys.eth.pinRst;
}
#endif
void getRadioNrf(JsonObject obj) {
obj[F("en")] = (bool) mConfig->nrf.enabled;
if(mConfig->nrf.enabled) {

64
src/web/html/setup.html

@ -245,7 +245,7 @@
<p class="des">{#MQTT_NOTE}</p>
<div class="row mb-3">
<div class="col-12 col-sm-3 my-2">{#INTERVAL}</div>
<div class="col-12 col-sm-9"><input type="number" name="mqttInterval" title="Invalid input" /></div>
<div class="col-12 col-sm-9"><input tyCMT2300Ape="number" name="mqttInterval" title="Invalid input" /></div>
</div>
<div class="row mb-3">
<div class="col-12 col-sm-3 my-2">Discovery Config (homeassistant)</div>
@ -270,6 +270,10 @@
<p class="des">{#RADIO} (CMT2300A)</p>
<div id="cmt"></div>
<!--ENDIF_ESP32-->
<!--IF_ETHERNET-->
<p class="des">Ethernet</p>
<div id="eth"></div>
<!--ENDIF_ETHERNET-->
</fieldset>
</div>
<!--IF_PLUGIN_DISPLAY-->
@ -986,7 +990,7 @@
)
}
function parseNrfRadio(obj, objPin, type, system) {
function parseNrfRadio(obj, objPin) {
var e = document.getElementById("rf24");
var en = inp("nrfEnable", null, null, ["cb"], "nrfEnable", "checkbox");
en.checked = obj["en"];
@ -1013,11 +1017,11 @@
])
);
if ("ESP8266" == type) {
pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq']];
} else {
pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq'], ['sclk', 'pinSclk'], ['mosi', 'pinMosi'], ['miso', 'pinMiso']];
}
/*IF_ESP32*/
var pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq'], ['sclk', 'pinSclk'], ['mosi', 'pinMosi'], ['miso', 'pinMiso']];
/*ELSE*/
var pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq']];
/*ENDIF_ESP32*/
for(p of pins) {
e.append(
ml("div", {class: "row mb-3"}, [
@ -1031,7 +1035,7 @@
}
/*IF_ESP32*/
function parseCmtRadio(obj, type, system) {
function parseCmtRadio(obj) {
var e = document.getElementById("cmt");
var en = inp("cmtEnable", null, null, ["cb"], "cmtEnable", "checkbox");
var pinList = esp32pins;
@ -1046,7 +1050,6 @@
/*ENDIF_ESP32-C3*/
en.checked = obj["en"];
e.replaceChildren (
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-8 col-sm-3 my-2"}, "{#CMT_ENABLE}"),
@ -1073,6 +1076,42 @@
}
/*ENDIF_ESP32*/
/*IF_ETHERNET*/
function parseEth(obj) {
var e = document.getElementById("eth");
var en = inp("ethEn", null, null, ["cb"], "ethEn", "checkbox");
var pinList = esp32pins;
/*IF_ESP32-S2*/
pinList = esp32sXpins;
/*ENDIF_ESP32-S2*/
/*IF_ESP32-S3*/
pinList = esp32sXpins;
/*ENDIF_ESP32-S3*/
/*IF_ESP32-C3*/
pinList = esp32c3pins;
/*ENDIF_ESP32-C3*/
en.checked = obj["en"];
e.replaceChildren (
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-8 col-sm-3 my-2"}, "{#ETH_ENABLE}"),
ml("div", {class: "col-4 col-sm-9"}, en)
])
);
pins = [['cs', 'ethCs'], ['sclk', 'ethSclk'], ['miso', 'ethMiso'], ['mosi', 'ethMosi'], ['irq', 'ethIrq'], ['reset', 'ethRst']];
for(p of pins) {
e.append(
ml("div", {class: "row mb-3"}, [
ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()),
ml("div", {class: "col-12 col-sm-9"},
sel(p[1], pinList, obj[p[0]])
)
])
);
}
}
/*ENDIF_ETHERNET*/
function parseSerial(obj) {
var e = document.getElementById("serialCb")
var l = [["serEn", "show_live_data", "{#LOG_PRINT_INVERTER_DATA}"], ["serDbg", "debug", "{#LOG_SERIAL_DEBUG}"], ["priv", "priv", "{#LOG_PRIVACY_MODE}"], ["wholeTrace", "wholeTrace", "{#LOG_PRINT_TRACES}"], ["log2mqtt", "log2mqtt", "{#LOG_TO_MQTT}"]]
@ -1253,10 +1292,13 @@
parseNtp(root["ntp"]);
parseSun(root["sun"]);
parsePinout(root["pinout"], root["system"]["esp_type"], root["system"]);
parseNrfRadio(root["radioNrf"], root["pinout"], root["system"]["esp_type"], root["system"]);
parseNrfRadio(root["radioNrf"], root["pinout"]);
/*IF_ESP32*/
parseCmtRadio(root["radioCmt"], root["system"]["esp_type"], root["system"]);
parseCmtRadio(root["radioCmt"]);
/*ENDIF_ESP32*/
/*IF_ETHERNET*/
parseEth(root.system.eth)
/*ENDIF_ETHERNET*/
parseSerial(root["serial"]);
/*IF_PLUGIN_DISPLAY*/
parseDisplay(root["display"], root["system"]["esp_type"], root["system"]);

5
src/web/lang.json

@ -723,6 +723,11 @@
"en": "CMT2300A radio enable",
"de": "CMT2300A Funkmodul aktivieren"
},
{
"token": "ETH_ENABLE",
"en": "Ethernet enable",
"de": "Ethernet aktivieren"
},
{
"token": "DISP_NONE",
"en": "None",

47
src/web/web.h

@ -37,14 +37,19 @@
#define WEB_SERIAL_BUF_SIZE 2048
const char* const pinArgNames[] = {"pinCs", "pinCe", "pinIrq", "pinSclk", "pinMosi", "pinMiso", "pinLed0", "pinLed1", "pinLed2", "pinLedHighActive", "pinLedLum", "pinCmtSclk", "pinSdio", "pinCsb", "pinFcsb", "pinGpio3"};
const char* const pinArgNames[] = {
"pinCs", "pinCe", "pinIrq", "pinSclk", "pinMosi", "pinMiso", "pinLed0",
"pinLed1", "pinLed2", "pinLedHighActive", "pinLedLum", "pinCmtSclk",
"pinSdio", "pinCsb", "pinFcsb", "pinGpio3"
#if defined (ETHERNET)
, "ethCs", "ethSclk", "ethMiso", "ethMosi", "ethIrq", "ethRst"
#endif
};
template <class HMSYSTEM>
class Web {
public:
Web(void) : mWeb(80), mEvts("/events") {
memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE);
}
Web(void) : mWeb(80), mEvts("/events") {}
void setup(IApp *app, HMSYSTEM *sys, settings_t *config) {
mApp = app;
@ -101,11 +106,17 @@ class Web {
void tickSecond() {
if (mSerialClientConnnected) {
if(nullptr == mSerialBuf)
return;
if (mSerialBufFill > 0) {
mEvts.send(mSerialBuf, "serial", millis());
memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE);
mSerialBufFill = 0;
}
} else if(nullptr != mSerialBuf) {
delete[] mSerialBuf;
mSerialBuf = nullptr;
}
}
@ -177,6 +188,9 @@ class Web {
if (!mSerialClientConnnected)
return;
if(nullptr == mSerialBuf)
return;
msg.replace("\r\n", "<rn>");
if (mSerialAddTime) {
if ((13 + mSerialBufFill) < WEB_SERIAL_BUF_SIZE) {
@ -293,6 +307,10 @@ class Web {
void onConnect(AsyncEventSourceClient *client) {
DPRINTLN(DBG_VERBOSE, "onConnect");
if(nullptr == mSerialBuf) {
mSerialBuf = new char[WEB_SERIAL_BUF_SIZE];
memset(mSerialBuf, 0, WEB_SERIAL_BUF_SIZE);
}
mSerialClientConnnected = true;
if (client->lastId())
@ -482,7 +500,12 @@ class Web {
// pinout
for (uint8_t i = 0; i < 16; i++) {
#if defined(ETHERNET)
for (uint8_t i = 0; i < 22; i++)
#else
for (uint8_t i = 0; i < 16; i++)
#endif
{
uint8_t pin = request->arg(String(pinArgNames[i])).toInt();
switch(i) {
case 0: mConfig->nrf.pinCs = ((pin != 0xff) ? pin : DEF_NRF_CS_PIN); break;
@ -501,11 +524,23 @@ class Web {
case 13: mConfig->cmt.pinCsb = pin; break;
case 14: mConfig->cmt.pinFcsb = pin; break;
case 15: mConfig->cmt.pinIrq = pin; break;
#if defined(ETHERNET)
case 16: mConfig->sys.eth.pinCs = pin; break;
case 17: mConfig->sys.eth.pinSclk = pin; break;
case 18: mConfig->sys.eth.pinMiso = pin; break;
case 19: mConfig->sys.eth.pinMosi = pin; break;
case 20: mConfig->sys.eth.pinIrq = pin; break;
case 21: mConfig->sys.eth.pinRst = pin; break;
#endif
}
}
mConfig->nrf.enabled = (request->arg("nrfEnable") == "on");
mConfig->cmt.enabled = (request->arg("cmtEnable") == "on");
#if defined(ETHERNET)
mConfig->sys.eth.enabled = (request->arg("ethEn") == "on");
#endif
// ntp
if (request->arg("ntpAddr") != "") {
@ -906,7 +941,7 @@ class Web {
settings_t *mConfig = nullptr;
bool mSerialAddTime = true;
char mSerialBuf[WEB_SERIAL_BUF_SIZE];
char *mSerialBuf = nullptr;
uint16_t mSerialBufFill = 0;
bool mSerialClientConnnected = false;

2
src/wifi/ahoywifi.h

@ -63,7 +63,7 @@ class ahoywifi {
void connectionEvent(WiFiStatus_t status);
bool isTimeout(uint8_t timeout) { return (mCnt % timeout) == 0; }
#if defined(ESP8266)
#if defined(ESP8266)
void onConnect(const WiFiEventStationModeConnected& event);
void onGotIP(const WiFiEventStationModeGotIP& event);
void onDisconnect(const WiFiEventStationModeDisconnected& event);

Loading…
Cancel
Save