mirror of
https://github.com/lumapu/ahoy.git
synced 2025-07-24 19:57:18 +02:00
* made ethernet pinout configurable
* combined common network functions into class * seperated wifi station from AP mode
This commit is contained in:
parent
4fc61dc01f
commit
a44a5833ca
12 changed files with 540 additions and 25 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
Normal file
82
src/network/AhoyEthernet.h
Normal file
|
@ -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__*/
|
|
@ -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
Normal file
194
src/network/AhoyNetwork.h
Normal file
|
@ -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
Normal file
29
src/network/AhoyNetworkHelper.h
Normal file
|
@ -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
Normal file
70
src/network/AhoyWifiAp.h
Normal file
|
@ -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__*/
|
|
@ -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) {
|
||||
|
|
|
@ -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"]);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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…
Add table
Add a link
Reference in a new issue