mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
static ip CLI command/EEPROM saving; reconnection logic refined; new ETHERNET2 lib required
This commit is contained in:
@@ -129,12 +129,12 @@ int Item::getArg(short n) //Return arg int or first array element if Arg is arra
|
||||
/*
|
||||
int Item::getVal(short n) //Return Val from Value array
|
||||
{ if (!itemVal) return -1;
|
||||
else if (itemVal->type==aJson_Array)
|
||||
else if (itemVal->type==aJson_Array)
|
||||
{
|
||||
aJsonObject *t = aJson.getArrayItem(itemVal,n);
|
||||
aJsonObject *t = aJson.getArrayItem(itemVal,n);
|
||||
if (t) return t->valueint;
|
||||
else return -3;
|
||||
}
|
||||
}
|
||||
else return -2;
|
||||
}
|
||||
*/
|
||||
@@ -156,9 +156,9 @@ void Item::setVal(short n, int par) // Only store if VAL is array defined in c
|
||||
if (!itemVal || itemVal->type!=aJson_Array) return;
|
||||
Serial.print(F(" Store p="));Serial.print(n);Serial.print(F(" Val="));Serial.println(par);
|
||||
for (int i=aJson.getArraySize(itemVal);i<=n;i++) aJson.addItemToArray(itemVal,aJson.createItem(int(0))); //Enlarge array of Values
|
||||
|
||||
|
||||
aJsonObject *t = aJson.getArrayItem(itemVal,n);
|
||||
if (t) t->valueint=par;
|
||||
if (t) t->valueint=par;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -182,7 +182,7 @@ boolean Item::isValid() {
|
||||
void Item::copyPar (aJsonObject *itemV)
|
||||
{ int n=aJson.getArraySize(itemV);
|
||||
//for (int i=aJson.getArraySize(itemVal);i<n;i++) aJson.addItemToArray(itemVal,aJson.createItem(int(0))); //Enlarge array of Values
|
||||
for (int i=0;i<n;i++) setPar(i,aJson.getArrayItem(itemV,i)->valueint);
|
||||
for (int i=0;i<n;i++) setPar(i,aJson.getArrayItem(itemV,i)->valueint);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -201,11 +201,11 @@ boolean Item::getEnableCMD(int delta) {
|
||||
#define MAXCTRLPAR 3
|
||||
int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
|
||||
|
||||
|
||||
Serial.print(F("Cmd="));Serial.print(cmd);Serial.print(F(" MEM="));Serial.println(freeRam());
|
||||
|
||||
int Par[MAXCTRLPAR] = {0, 0, 0};
|
||||
if (Parameters)
|
||||
if (Parameters)
|
||||
for (short i=0;i<n && i<MAXCTRLPAR;i++) Par[i] = Parameters[i];
|
||||
|
||||
int iaddr = getArg();
|
||||
@@ -254,7 +254,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
case CH_MODBUS:
|
||||
case CH_VCTEMP:
|
||||
if (send) SendStatus(0, 1, Par,true); // Send back parameter for channel above this line
|
||||
case CH_THERMO:
|
||||
case CH_THERMO:
|
||||
setVal(Par[0]); // Store value
|
||||
|
||||
}//itemtype
|
||||
@@ -265,7 +265,23 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
break;
|
||||
|
||||
case CMD_ON:
|
||||
if (itemType!=CH_RGBW || getCmd() != CMD_ON) {
|
||||
if (itemType==CH_RGBW && getCmd() == CMD_ON && getEnableCMD(500)) {
|
||||
Serial.println(F("Force White"));
|
||||
itemType = CH_WHITE;
|
||||
Par[1] = 0; //Zero saturation
|
||||
Par[2] = 100; //Full power
|
||||
// Store
|
||||
st.h = Par[0];
|
||||
st.s = Par[1];
|
||||
st.v = Par[2];
|
||||
setVal(st.aslong);
|
||||
//Send to OH
|
||||
if (send) SendStatus(0, 3, Par);
|
||||
break;
|
||||
} // if forcewhite
|
||||
|
||||
// if (itemType!=CH_RGBW || getCmd() != CMD_ON) {
|
||||
{
|
||||
short params = 0;
|
||||
setCmd(cmd);
|
||||
//retrive stored values
|
||||
@@ -290,7 +306,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
case CH_DIMMER: //Everywhere, in flat VAL
|
||||
case CH_MODBUS:
|
||||
case CH_VC:
|
||||
|
||||
|
||||
|
||||
Par[0] = st.aslong;
|
||||
params = 1;
|
||||
@@ -303,8 +319,8 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
break;
|
||||
default:
|
||||
if (send) SendStatus(cmd); // Just send ON
|
||||
}//itemtype
|
||||
else {// Default settings
|
||||
}//itemtype switch
|
||||
else {// Default settings, values not stored yet
|
||||
Serial.print(st.aslong);
|
||||
Serial.println(F(": No stored values - default"));
|
||||
|
||||
@@ -314,7 +330,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
Par[0] = 20; //20 degrees celsium - safe temperature
|
||||
params = 1;
|
||||
SendStatus(0, params, Par);
|
||||
break;
|
||||
break;
|
||||
case CH_RGBW:
|
||||
case CH_RGB:
|
||||
Par[0] = 100;
|
||||
@@ -323,18 +339,24 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
params = 3;
|
||||
SendStatus(0, params, Par,true);
|
||||
break;
|
||||
default:
|
||||
case CH_RELAY:
|
||||
Par[0] = 100;
|
||||
params = 1;
|
||||
if (send) SendStatus(CMD_ON);
|
||||
break;
|
||||
default:
|
||||
Par[0] = 100;
|
||||
params = 1;
|
||||
SendStatus(0, params, Par);
|
||||
}
|
||||
}
|
||||
} // default handler
|
||||
for (short i = 0; i < params; i++) {
|
||||
Serial.print(F("Restored: "));
|
||||
Serial.print(i);
|
||||
Serial.print(F("="));
|
||||
Serial.println(Par[i]);
|
||||
}
|
||||
/*
|
||||
} else { //Double ON - apply special preset - clean white full power
|
||||
if (getEnableCMD(500)) switch (itemType) {
|
||||
case CH_RGBW:
|
||||
@@ -354,10 +376,10 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
break;
|
||||
} //itemtype
|
||||
} //else
|
||||
|
||||
*/
|
||||
//Serial.print("Sa:");Serial.println(Par[1]);
|
||||
if ((itemType == CH_RGBW) && (Par[1] == 0)) itemType = CH_WHITE;
|
||||
|
||||
}
|
||||
|
||||
break; //CMD_ON
|
||||
|
||||
@@ -368,7 +390,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
Par[1] = 0;
|
||||
Par[2] = 0;
|
||||
setCmd(cmd);
|
||||
if (send) SendStatus(cmd);
|
||||
if (send) SendStatus(cmd);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -453,7 +475,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send) {
|
||||
aJsonObject *i = itemArg->child;
|
||||
while (i) {
|
||||
Item it(i->valuestring);
|
||||
// it.copyPar(itemVal);
|
||||
// it.copyPar(itemVal);
|
||||
it.Ctrl(cmd, n, Par, send); //// was true
|
||||
i = i->next;
|
||||
} //while
|
||||
@@ -600,20 +622,20 @@ int Item::isActive() {
|
||||
|
||||
short thermoSet(char * name, short cmd, short t)
|
||||
{
|
||||
|
||||
|
||||
if (items)
|
||||
{
|
||||
aJsonObject *item= aJson.getObjectItem(items, name);
|
||||
if (item && (item->type==aJson_Array) && (aJson.getArrayItem(item, I_TYPE)->valueint==CH_THERMO))
|
||||
{
|
||||
{
|
||||
|
||||
for (int i=aJson.getArraySize(item);i<4;i++) aJson.addItemToArray(item,aJson.createItem(int(0))); //Enlarge item to 4 elements
|
||||
if (!cmd) aJson.getArrayItem(item, I_VAL)->valueint=t;
|
||||
aJson.getArrayItem(item, I_CMD)->valueint=cmd;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -623,8 +645,8 @@ if (PoolingInterval)
|
||||
{
|
||||
Pool();
|
||||
next=millis()+PoolingInterval;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -635,31 +657,31 @@ addr 10d
|
||||
Снять аварию 42001 (2001=7d1) =>4
|
||||
|
||||
[22:20:33] Write task has completed successfully
|
||||
[22:20:33] <= Response: 0A 06 07 D0 00 04 89 FF
|
||||
[22:20:32] => Poll: 0A 06 07 D0 00 04 89 FF
|
||||
[22:20:33] <= Response: 0A 06 07 D0 00 04 89 FF
|
||||
[22:20:32] => Poll: 0A 06 07 D0 00 04 89 FF
|
||||
|
||||
100%
|
||||
2003-> 10000
|
||||
[22:24:05] Write task has completed successfully
|
||||
[22:24:05] <= Response: 0A 06 07 D2 27 10 33 C0
|
||||
[22:24:05] => Poll: 0A 06 07 D2 27 10 33 C0
|
||||
[22:24:05] <= Response: 0A 06 07 D2 27 10 33 C0
|
||||
[22:24:05] => Poll: 0A 06 07 D2 27 10 33 C0
|
||||
|
||||
ON
|
||||
2001->1
|
||||
[22:24:50] Write task has completed successfully
|
||||
[22:24:50] <= Response: 0A 06 07 D0 00 01 49 FC
|
||||
[22:24:50] => Poll: 0A 06 07 D0 00 01 49 FC
|
||||
[22:24:50] <= Response: 0A 06 07 D0 00 01 49 FC
|
||||
[22:24:50] => Poll: 0A 06 07 D0 00 01 49 FC
|
||||
|
||||
OFF
|
||||
OFF
|
||||
2001->0
|
||||
[22:25:35] Write task has completed successfully
|
||||
[22:25:35] <= Response: 0A 06 07 D0 00 00 88 3C
|
||||
[22:25:34] => Poll: 0A 06 07 D0 00 00 88 3C
|
||||
[22:25:35] <= Response: 0A 06 07 D0 00 00 88 3C
|
||||
[22:25:34] => Poll: 0A 06 07 D0 00 00 88 3C
|
||||
|
||||
|
||||
POLL 2101x10
|
||||
[22:27:29] <= Response: 0A 03 14 00 23 00 00 27 10 13 88 0B 9C 00 32 00 F8 00 F2 06 FA 01 3F AD D0
|
||||
[22:27:29] => Poll: 0A 03 08 34 00 0A 87 18
|
||||
[22:27:29] <= Response: 0A 03 14 00 23 00 00 27 10 13 88 0B 9C 00 32 00 F8 00 F2 06 FA 01 3F AD D0
|
||||
[22:27:29] => Poll: 0A 03 08 34 00 0A 87 18
|
||||
|
||||
*/
|
||||
|
||||
@@ -749,7 +771,7 @@ int Item::SendStatus(short cmd, short n, int *Par, boolean deffered) {
|
||||
if (deffered) {
|
||||
setCmd(cmd | CMD_REPORT);
|
||||
Serial.println(F("Status deffered"));
|
||||
// mqttClient.publish("/push", "1");
|
||||
// mqttClient.publish("/push", "1");
|
||||
return 0;
|
||||
// Todo: Parameters? Now expected that parameters already stored by setVal()
|
||||
}
|
||||
@@ -759,7 +781,7 @@ int Item::SendStatus(short cmd, short n, int *Par, boolean deffered) {
|
||||
char valstr[16] = "";
|
||||
|
||||
strcpy_P(addrstr, outprefix);
|
||||
strncat(addrstr, itemArr->name, sizeof(addrstr));
|
||||
strncat(addrstr, itemArr->name, sizeof(addrstr));
|
||||
|
||||
|
||||
switch (cmd) {
|
||||
@@ -802,7 +824,7 @@ int Item::modbusDimmerSet(int addr, uint16_t _reg, int _mask, uint16_t value) {
|
||||
|
||||
if (modbusBusy) {
|
||||
mb_fail(3, addr, value, 0);
|
||||
|
||||
|
||||
return -1;
|
||||
};
|
||||
modbusBusy = 1;
|
||||
@@ -876,13 +898,13 @@ int Item::checkFM() {
|
||||
// aJson.addNumberToObject(out,"U", (int) node.getResponseBuffer(8)/10.);
|
||||
// aJson.addNumberToObject(out,"Ui", (int) node.getResponseBuffer(9));
|
||||
aJson.addNumberToObject(out, "sw", (int) node.getResponseBuffer(0));
|
||||
|
||||
|
||||
if (RPM && itemArg->type == aJson_Array)
|
||||
{ aJsonObject *airGateObj = aJson.getArrayItem(itemArg, 1);
|
||||
if (airGateObj) {
|
||||
int val = 100;
|
||||
Item item(airGateObj->valuestring);
|
||||
if (item.isValid()) item.Ctrl(0,1,&val);
|
||||
if (item.isValid()) item.Ctrl(0,1,&val);
|
||||
}
|
||||
}
|
||||
Serial.println();
|
||||
@@ -918,11 +940,11 @@ int Item::checkFM() {
|
||||
// aJson.addNumberToObject(out,"d", (int) node.getResponseBuffer(2)*a+b);
|
||||
int pwr = node.getResponseBuffer(3);
|
||||
if (pwr > 0) aJson.addNumberToObject(out, "pwr", pwr / 10.); else aJson.addNumberToObject(out, "pwr", 0);
|
||||
|
||||
if (ftemp>FM_OVERHEAT_CELSIUS && set)
|
||||
|
||||
if (ftemp>FM_OVERHEAT_CELSIUS && set)
|
||||
{
|
||||
mqttClient.publish("/alarm/ovrht", itemArr->name);
|
||||
Ctrl(CMD_OFF); //Shut down
|
||||
mqttClient.publish("/alarm/ovrht", itemArr->name);
|
||||
Ctrl(CMD_OFF); //Shut down
|
||||
}
|
||||
Serial.println();
|
||||
} else {
|
||||
@@ -942,12 +964,12 @@ int Item::checkFM() {
|
||||
boolean Item::checkModbusRetry() {
|
||||
int cmd = getCmd();
|
||||
if (cmd & CMD_RETRY) { // if last sending attempt of command was failed
|
||||
int val = getVal();
|
||||
int val = getVal();
|
||||
Serial.println(F("Retrying CMD"));
|
||||
cmd &= ~CMD_RETRY; // Clean retry flag
|
||||
Ctrl(cmd,1,&val); // Execute command again
|
||||
Ctrl(cmd,1,&val); // Execute command again
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1026,28 +1048,28 @@ int Item::Poll() {
|
||||
switch (itemType) {
|
||||
case CH_MODBUS:
|
||||
checkModbusDimmer();
|
||||
sendDelayedStatus();
|
||||
sendDelayedStatus();
|
||||
return INTERVAL_CHECK_MODBUS;
|
||||
break;
|
||||
case CH_VC:
|
||||
checkFM();
|
||||
sendDelayedStatus();
|
||||
sendDelayedStatus();
|
||||
return INTERVAL_CHECK_MODBUS;
|
||||
break;
|
||||
case CH_RGB: //All channels with slider generate too many updates
|
||||
case CH_RGBW:
|
||||
case CH_DIMMER:
|
||||
case CH_PWM:
|
||||
case CH_PWM:
|
||||
case CH_VCTEMP:
|
||||
case CH_THERMO:
|
||||
sendDelayedStatus();
|
||||
case CH_THERMO:
|
||||
sendDelayedStatus();
|
||||
}
|
||||
return INTERVAL_POLLING;
|
||||
}
|
||||
|
||||
void Item::sendDelayedStatus(){
|
||||
HSVstore st;
|
||||
int cmd=getCmd();
|
||||
int cmd=getCmd();
|
||||
short params = 0;
|
||||
int Par[3];
|
||||
if (cmd & CMD_REPORT)
|
||||
@@ -1062,7 +1084,7 @@ void Item::sendDelayedStatus(){
|
||||
Par[1] = st.s;
|
||||
Par[2] = st.v;
|
||||
params = 3;
|
||||
SendStatus(0, params, Par); // Send restored triplet.
|
||||
SendStatus(0, params, Par); // Send restored triplet.
|
||||
break;
|
||||
|
||||
case CH_VCTEMP:
|
||||
@@ -1071,17 +1093,16 @@ void Item::sendDelayedStatus(){
|
||||
case CH_MODBUS:
|
||||
case CH_VC:
|
||||
case CH_THERMO:
|
||||
|
||||
|
||||
|
||||
Par[0] = st.aslong;
|
||||
params = 1;
|
||||
SendStatus(0, params, Par); // Send restored parameter
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
SendStatus(cmd); // Just send CMD
|
||||
}//itemtype
|
||||
cmd &= ~CMD_REPORT; // Clean report flag
|
||||
setCmd(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Copyright © 2017-2018 Andrey Klimov. All rights reserved.
|
||||
*
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -71,7 +66,7 @@ PWM Out
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "main.h"
|
||||
#include "options.h"
|
||||
|
||||
@@ -86,6 +81,8 @@ EthernetClient ethClient;
|
||||
|
||||
const char outprefix[] PROGMEM = OUTTOPIC;
|
||||
const char inprefix[] PROGMEM = INTOPIC;
|
||||
const char configserver[] PROGMEM = CONFIG_SERVER;
|
||||
|
||||
|
||||
aJsonObject *root = NULL;
|
||||
aJsonObject *items = NULL;
|
||||
@@ -104,6 +101,7 @@ unsigned long nextThermostatCheck = 0;
|
||||
aJsonObject *pollingItem = NULL;
|
||||
|
||||
bool owReady = false;
|
||||
bool configOk = false;
|
||||
int lanStatus = 0;
|
||||
|
||||
#ifdef _modbus
|
||||
@@ -118,15 +116,17 @@ PubSubClient mqttClient(ethClient);
|
||||
|
||||
void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init for DUE
|
||||
|
||||
|
||||
// MQTT Callback routine
|
||||
#define MQTT_SUBJECT_LENGTH 20
|
||||
#define MQTT_TOPIC_LENGTH 20
|
||||
|
||||
|
||||
void mqttCallback(char *topic, byte *payload, unsigned int length) {
|
||||
payload[length] = 0;
|
||||
|
||||
Serial.print(F("\n["));
|
||||
Serial.print(topic);
|
||||
Serial.print(F("] "));
|
||||
if (!payload) return;
|
||||
payload[length] = 0;
|
||||
|
||||
int fr = freeRam();
|
||||
if (fr < 250) {
|
||||
@@ -266,15 +266,30 @@ int lanLoop() {
|
||||
switch (lanStatus) {
|
||||
//Initial state
|
||||
case 0: //Ethernet.begin(mac,ip);
|
||||
|
||||
{
|
||||
#ifdef __ESP__
|
||||
//WiFi.mode(WIFI_STA);
|
||||
//wifiMulti.addAP("Smartbox", "");
|
||||
if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
#else
|
||||
IPAddress ip;
|
||||
IPAddress dns;
|
||||
IPAddress gw;
|
||||
IPAddress mask;
|
||||
int res = 1;
|
||||
Serial.println(F("Starting lan"));
|
||||
if (loadFlash(OFFSET_IP,ip))
|
||||
if (loadFlash(OFFSET_DNS,dns))
|
||||
if (loadFlash(OFFSET_GW,gw))
|
||||
if (loadFlash(OFFSET_MASK,mask)) Ethernet.begin(mac,ip,dns,gw,mask);
|
||||
else Ethernet.begin(mac,ip,dns,gw);
|
||||
else Ethernet.begin(mac,ip,dns);
|
||||
else Ethernet.begin(mac,ip);
|
||||
else res = Ethernet.begin(mac, 12000);
|
||||
|
||||
|
||||
wdt_dis();
|
||||
if (Ethernet.begin(mac, 12000) == 0) {
|
||||
if (res == 0) {
|
||||
Serial.println(F("Failed to configure Ethernet using DHCP"));
|
||||
lanStatus = -10;
|
||||
lanCheck = millis() + 60000;
|
||||
@@ -284,12 +299,15 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
}
|
||||
wdt_en();
|
||||
wdt_res();
|
||||
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
//Have IP address
|
||||
case 1:
|
||||
|
||||
lanStatus = getConfig(0, NULL); //got config from server or load from NVRAM
|
||||
if (!configOk)
|
||||
lanStatus = getConfig(0, NULL); //got config from server or load from NVRAM
|
||||
else lanStatus = 2;
|
||||
#ifdef _artnet
|
||||
if (artnet) artnet->begin();
|
||||
#endif
|
||||
@@ -313,6 +331,7 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
if (n >= 5) password = aJson.getArrayItem(mqttArr, 4)->valuestring;
|
||||
|
||||
mqttClient.setServer(servername, port);
|
||||
mqttClient.setCallback(mqttCallback);
|
||||
|
||||
Serial.print(F("Attempting MQTT connection to "));
|
||||
Serial.print(servername);
|
||||
@@ -322,11 +341,12 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
Serial.print(user);
|
||||
Serial.print(F(" ..."));
|
||||
|
||||
wdt_dis(); //potential unsafe for ethernetIdle(), but needed to avoid cyclic reboot if mosquitto out of order
|
||||
if (mqttClient.connect(client_id, user, password)) {
|
||||
Serial.print(F("connected as "));
|
||||
Serial.println(client_id);
|
||||
|
||||
|
||||
wdt_en();
|
||||
configOk=true;
|
||||
// ... Temporary subscribe to status topic
|
||||
char buf[MQTT_TOPIC_LENGTH];
|
||||
|
||||
@@ -349,7 +369,7 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
Serial.print(mqttClient.state());
|
||||
Serial.println(F(" try again in 5 seconds"));
|
||||
lanCheck = millis() + 5000;
|
||||
lanStatus = -12;
|
||||
lanStatus = 12;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -379,7 +399,7 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
lanStatus = 0;
|
||||
break;
|
||||
//Reconnect
|
||||
case -12:
|
||||
case 12:
|
||||
if (millis() > lanCheck)
|
||||
|
||||
lanStatus = 2;
|
||||
@@ -403,9 +423,15 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
wdt_dis();
|
||||
if (lanStatus > 0)
|
||||
switch (Ethernet.maintain()) {
|
||||
case NO_LINK:
|
||||
Serial.println(F("No link"));
|
||||
if (mqttClient.connected()) mqttClient.disconnect();
|
||||
lanStatus = -10;
|
||||
break;
|
||||
case DHCP_CHECK_RENEW_FAIL:
|
||||
//renewed fail
|
||||
Serial.println(F("Error: renewed fail"));
|
||||
if (mqttClient.connected()) mqttClient.disconnect();
|
||||
lanStatus = -10;
|
||||
break;
|
||||
|
||||
@@ -416,6 +442,7 @@ if((wifiMulti.run() == WL_CONNECTED)) lanStatus=1;
|
||||
|
||||
case DHCP_CHECK_REBIND_FAIL:
|
||||
Serial.println(F("Error: rebind fail"));
|
||||
if (mqttClient.connected()) mqttClient.disconnect();
|
||||
lanStatus = -10;
|
||||
break;
|
||||
|
||||
@@ -530,21 +557,23 @@ void cmdFunctionHelp(int arg_cnt, char **args)
|
||||
{
|
||||
printFirmwareVersionAndBuildOptions();
|
||||
Serial.println(F("Use the commands: 'help' - this text\n"
|
||||
"'set de:ad:be:ef:fe:00' set and store MAC-address in EEPROM\n"
|
||||
"'mac de:ad:be:ef:fe:00' set and store MAC-address in EEPROM\n"
|
||||
"'ip [ip[,dns[,gw[,subnet]]]]'\n"
|
||||
"'save' - save config in NVRAM\n"
|
||||
"'get' - get config from pre-configured URL\n"
|
||||
"'get' [config addr]' - get config from pre-configured URL\n"
|
||||
"'load' - load config from NVRAM\n"
|
||||
"'kill' - test watchdog"));
|
||||
}
|
||||
|
||||
void cmdFunctionKill(int arg_cnt, char **args) {
|
||||
for (short i = 17; i > 0; i--) {
|
||||
for (short i = 1; i < 20; i++) {
|
||||
delay(1000);
|
||||
Serial.println(i);
|
||||
};
|
||||
}
|
||||
|
||||
void applyConfig() {
|
||||
if (!root) return;
|
||||
#ifdef _dmxout
|
||||
int maxChannels;
|
||||
aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx");
|
||||
@@ -591,17 +620,19 @@ void applyConfig() {
|
||||
items = aJson.getObjectItem(root, "items");
|
||||
|
||||
// Digital output related Items initialization
|
||||
{
|
||||
pollingItem=NULL;
|
||||
if (items) {
|
||||
aJsonObject * item = items->child;
|
||||
while (items && item)
|
||||
if (item->type == aJson_Array && aJson.getArraySize(item)>1) {
|
||||
int cmd = CMD_OFF;
|
||||
int pin = aJson.getArrayItem(item, I_ARG)->valueint;
|
||||
if (aJson.getArraySize(item) > I_CMD) cmd = aJson.getArrayItem(item, I_CMD)->valueint;
|
||||
|
||||
switch (aJson.getArrayItem(item, I_TYPE)->valueint) {
|
||||
case CH_RELAY:
|
||||
Item it(item);
|
||||
if (it.isValid()) {
|
||||
int pin=it.getArg();
|
||||
int cmd = it.getCmd();
|
||||
switch (it.itemType) {
|
||||
case CH_THERMO:
|
||||
if (cmd<1) it.setCmd(CMD_OFF);
|
||||
case CH_RELAY:
|
||||
{
|
||||
int k;
|
||||
pinMode(pin, OUTPUT);
|
||||
@@ -613,11 +644,11 @@ while (items && item)
|
||||
}
|
||||
break;
|
||||
} //switch
|
||||
} //isValid
|
||||
item = item->next;
|
||||
} //if
|
||||
|
||||
}
|
||||
pollingItem = items->child;
|
||||
}
|
||||
inputs = aJson.getObjectItem(root, "in");
|
||||
mqttArr = aJson.getObjectItem(root, "mqtt");
|
||||
printConfigSummary();
|
||||
@@ -660,6 +691,7 @@ int loadConfigFromEEPROM(int arg_cnt, char **args)
|
||||
}
|
||||
Serial.println(F("Loaded"));
|
||||
applyConfig();
|
||||
ethClient.stop(); //Refresh MQTT connect to get retained info
|
||||
return 1;
|
||||
} else {
|
||||
Serial.println(F("No stored config"));
|
||||
@@ -719,6 +751,23 @@ void cmdFunctionSave(int arg_cnt, char **args)
|
||||
Serial.println(F("Saved to EEPROM"));
|
||||
}
|
||||
|
||||
void cmdFunctionIp(int arg_cnt, char **args)
|
||||
//(char* tokens)
|
||||
{ IPAddress ip0 (0,0,0,0);
|
||||
IPAddress ip;
|
||||
DNSClient dns;
|
||||
switch (arg_cnt) {
|
||||
case 5: if (dns.inet_aton(args[4],ip)) saveFlash(OFFSET_MASK,ip); else saveFlash(OFFSET_MASK,ip0);
|
||||
case 4: if (dns.inet_aton(args[3],ip)) saveFlash(OFFSET_GW,ip); else saveFlash(OFFSET_GW,ip0);
|
||||
case 3: if (dns.inet_aton(args[2],ip)) saveFlash(OFFSET_DNS,ip); else saveFlash(OFFSET_DNS,ip0);
|
||||
case 2: if (dns.inet_aton(args[1],ip)) saveFlash(OFFSET_IP,ip); else saveFlash(OFFSET_IP,ip0);
|
||||
break;
|
||||
case 1: //dynamic IP
|
||||
saveFlash(OFFSET_IP,ip0);
|
||||
}
|
||||
Serial.println(F("Saved"));
|
||||
}
|
||||
|
||||
|
||||
void cmdFunctionSetMac(int arg_cnt, char **args) {
|
||||
|
||||
@@ -741,22 +790,40 @@ void cmdFunctionSetMac(int arg_cnt, char **args) {
|
||||
}
|
||||
|
||||
void cmdFunctionGet(int arg_cnt, char **args) {
|
||||
getConfig(arg_cnt, args);
|
||||
restoreState();
|
||||
lanStatus=getConfig(arg_cnt, args);
|
||||
ethClient.stop(); //Refresh MQTT connect to get retained info
|
||||
//restoreState();
|
||||
}
|
||||
|
||||
void printBool(bool arg) { (arg) ? Serial.println(F("on")) : Serial.println(F("off")); }
|
||||
|
||||
|
||||
void saveFlash(short n, char *str) {}
|
||||
void saveFlash(short n, char *str) {
|
||||
short i;
|
||||
short len=strlen(str);
|
||||
if (len>31) len=31;
|
||||
for(int i=0;i<len;i++) EEPROM.write(n+i,str[i]);
|
||||
EEPROM.write(n+len,0);
|
||||
}
|
||||
|
||||
void loadFlash(short n, char *str) {}
|
||||
int loadFlash(short n, char *str, short l) {
|
||||
short i;
|
||||
uint8_t ch = EEPROM.read(n);
|
||||
if (!ch || (ch == 0xff)) return 0;
|
||||
for (i=0;i<l-1 && (str[i] = EEPROM.read(n++));i++);
|
||||
str[i]=0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef MY_CONFIG_SERVER
|
||||
#define CONFIG_SERVER "lazyhome.ru"
|
||||
#else
|
||||
#define CONFIG_SERVER QUOTE(MY_CONFIG_SERVER)
|
||||
#endif
|
||||
void saveFlash(short n, IPAddress& ip) {
|
||||
for(int i=0;i<4;i++) EEPROM.write(n++,ip[i]);
|
||||
}
|
||||
|
||||
int loadFlash(short n, IPAddress& ip) {
|
||||
for(int i=0;i<4;i++) ip[i]=EEPROM.read(n++);
|
||||
if (ip[0] && (ip[0] != 0xff)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getConfig(int arg_cnt, char **args)
|
||||
//(char *tokens)
|
||||
@@ -766,11 +833,12 @@ int getConfig(int arg_cnt, char **args)
|
||||
int responseStatusCode = 0;
|
||||
char ch;
|
||||
char URI[40];
|
||||
char configServer[32] = CONFIG_SERVER;
|
||||
if (arg_cnt > 0) {
|
||||
char configServer[32]="";
|
||||
if (arg_cnt > 1) {
|
||||
strncpy(configServer, args[1], sizeof(configServer) - 1);
|
||||
saveFlash(0, configServer);
|
||||
} else loadFlash(0, configServer);
|
||||
saveFlash(OFFSET_CONFIGSERVER, configServer);
|
||||
} else if (!loadFlash(OFFSET_CONFIGSERVER, configServer))
|
||||
strncpy_P(configServer,configserver,sizeof(configServer));
|
||||
|
||||
snprintf(URI, sizeof(URI), "/%02x-%02x-%02x-%02x-%02x-%02x.config.json", mac[0], mac[1], mac[2], mac[3], mac[4],
|
||||
mac[5]);
|
||||
@@ -794,8 +862,11 @@ int getConfig(int arg_cnt, char **args)
|
||||
|
||||
Serial.println(F("got Config"));
|
||||
aJsonFileStream as = aJsonFileStream(result);
|
||||
noInterrupts();
|
||||
aJson.deleteItem(root);
|
||||
root = aJson.parse(&as);
|
||||
interrupts();
|
||||
// Serial.println(F("Parsed."));
|
||||
hclient.closeStream(result); // this is very important -- be sure to close the STREAM
|
||||
|
||||
if (!root) {
|
||||
@@ -806,7 +877,7 @@ int getConfig(int arg_cnt, char **args)
|
||||
// char *outstr = aJson.print(root);
|
||||
// Serial.println(outstr);
|
||||
// free(outstr);
|
||||
|
||||
Serial.println(F("Applying."));
|
||||
applyConfig();
|
||||
|
||||
|
||||
@@ -829,11 +900,12 @@ int getConfig(int arg_cnt, char **args)
|
||||
#else
|
||||
//Non AVR code
|
||||
String response;
|
||||
|
||||
HttpClient htclient = HttpClient(ethClient, configServer, 80);
|
||||
EthernetClient configEthClient;
|
||||
HttpClient htclient = HttpClient(configEthClient, configServer, 80);
|
||||
//htclient.stop(); //_socket =MAX
|
||||
htclient.setHttpResponseTimeout(4000);
|
||||
wdt_res();
|
||||
//Serial.println("making GET request");
|
||||
//Serial.println("making GET request");get
|
||||
htclient.beginRequest();
|
||||
htclient.get(URI);
|
||||
htclient.endRequest();
|
||||
@@ -1013,9 +1085,10 @@ void setupCmdArduino() {
|
||||
cmdAdd("save", cmdFunctionSave);
|
||||
cmdAdd("load", cmdFunctionLoad);
|
||||
cmdAdd("get", cmdFunctionGet);
|
||||
cmdAdd("set", cmdFunctionSetMac);
|
||||
cmdAdd("mac", cmdFunctionSetMac);
|
||||
cmdAdd("kill", cmdFunctionKill);
|
||||
cmdAdd("req", cmdFunctionReq);
|
||||
cmdAdd("ip", cmdFunctionIp);
|
||||
}
|
||||
|
||||
void loop_main() {
|
||||
@@ -1046,7 +1119,7 @@ void loop_main() {
|
||||
}
|
||||
|
||||
|
||||
if (inputs) inputLoop();
|
||||
inputLoop();
|
||||
|
||||
#if defined (_espdmx)
|
||||
dmxout.update();
|
||||
@@ -1072,6 +1145,11 @@ void owIdle(void) {
|
||||
dmxout.update();
|
||||
#endif
|
||||
}
|
||||
void ethernetIdle(void){
|
||||
wdt_res();
|
||||
inputLoop();
|
||||
// Serial.print(".");
|
||||
};
|
||||
|
||||
void modbusIdle(void) {
|
||||
wdt_res();
|
||||
@@ -1080,8 +1158,10 @@ void modbusIdle(void) {
|
||||
#ifdef _artnet
|
||||
if (artnet) artnet->read();
|
||||
#endif
|
||||
inputLoop();
|
||||
}
|
||||
|
||||
|
||||
#ifdef _dmxin
|
||||
DMXCheck();
|
||||
#endif
|
||||
@@ -1092,6 +1172,7 @@ void modbusIdle(void) {
|
||||
}
|
||||
|
||||
void inputLoop(void) {
|
||||
if (!inputs) return;
|
||||
if (millis() > nextInputCheck) {
|
||||
aJsonObject *input = inputs->child;
|
||||
while (input) {
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "item.h"
|
||||
#include "inputs.h"
|
||||
#include "FastLED.h"
|
||||
#include "Dns.h"
|
||||
//#include "hsv2rgb.h"
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
@@ -95,7 +96,7 @@
|
||||
extern Artnet *artnet;
|
||||
#endif
|
||||
|
||||
void watchdogSetup(void);
|
||||
//void watchdogSetup(void);
|
||||
|
||||
void mqttCallback(char *topic, byte *payload, unsigned int length);
|
||||
|
||||
@@ -141,9 +142,13 @@ void printBool(bool arg);
|
||||
|
||||
void saveFlash(short n, char *str);
|
||||
|
||||
void loadFlash(short n, char *str);
|
||||
int loadFlash(short n, char *str, short l=32);
|
||||
|
||||
int getConfig(int arg_cnt, char **args);
|
||||
void saveFlash(short n, IPAddress& ip);
|
||||
|
||||
int loadFlash(short n, IPAddress& ip);
|
||||
|
||||
int getConfig(int arg_cnt=0, char **args=NULL);
|
||||
|
||||
void preTransmission();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Configuration of drivers enabled
|
||||
#ifndef PIO_SRC_REV
|
||||
#define PIO_SRC_REV v0.996
|
||||
#define PIO_SRC_REV v0.997
|
||||
#endif
|
||||
|
||||
#define TXEnablePin 13
|
||||
@@ -13,9 +13,16 @@
|
||||
#define THERMO_OVERHEAT_CELSIUS 38
|
||||
#define FM_OVERHEAT_CELSIUS 40.
|
||||
|
||||
#define EEPROM_offset 32+6
|
||||
|
||||
#define INTERVAL_CHECK_INPUT 50
|
||||
#define OFFSET_MAC 0
|
||||
#define OFFSET_IP OFFSET_MAC+6
|
||||
#define OFFSET_DNS OFFSET_IP+4
|
||||
#define OFFSET_GW OFFSET_DNS+4
|
||||
#define OFFSET_MASK OFFSET_GW+4
|
||||
#define OFFSET_CONFIGSERVER OFFSET_MASK+4
|
||||
#define EEPROM_offset OFFSET_CONFIGSERVER+32
|
||||
|
||||
#define INTERVAL_CHECK_INPUT 50
|
||||
#define INTERVAL_CHECK_MODBUS 2000
|
||||
#define INTERVAL_POLLING 100
|
||||
#define THERMOSTAT_CHECK_PERIOD 5000
|
||||
@@ -32,15 +39,23 @@
|
||||
#define DEFAULT_FIRMWARE_MAC {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0}
|
||||
#endif
|
||||
|
||||
#ifndef MY_CONFIG_SERVER
|
||||
#define CONFIG_SERVER "lazyhome.ru"
|
||||
#else
|
||||
#define CONFIG_SERVER QUOTE(MY_CONFIG_SERVER)
|
||||
#endif
|
||||
|
||||
#ifndef OUTTOPIC
|
||||
#define OUTTOPIC "/myhome/s_out/"
|
||||
#define OUTTOPIC "/myhome/s_out1/"
|
||||
#endif
|
||||
|
||||
#ifndef INTOPIC
|
||||
#define INTOPIC "/myhome/in/"
|
||||
#define INTOPIC "/myhome/in1/"
|
||||
#endif
|
||||
|
||||
#define MQTT_SUBJECT_LENGTH 20
|
||||
#define MQTT_TOPIC_LENGTH 20
|
||||
|
||||
#ifndef DMX_DISABLE
|
||||
#define _dmxin
|
||||
#define _dmxout
|
||||
@@ -66,12 +81,12 @@
|
||||
//All options available
|
||||
#define modbusSerial Serial2
|
||||
#define dmxin DMXSerial
|
||||
#define dmxout DmxSimple
|
||||
#define dmxout DmxSimple
|
||||
#endif
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
#define modbusSerial Serial2
|
||||
#define dmxout DmxDue1
|
||||
#define dmxout DmxDue1
|
||||
#define dmxin DmxDue1
|
||||
#endif
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ lib_deps =
|
||||
https://github.com/anklimov/Arduino-Temperature-Control-Library.git
|
||||
https://github.com/anklimov/DS2482_OneWire
|
||||
https://github.com/anklimov/DmxDue
|
||||
https://github.com/arduino-libraries/ArduinoHttpClient
|
||||
https://github.com/anklimov/ArduinoHttpClient
|
||||
https://github.com/anklimov/aJson
|
||||
https://github.com/anklimov/CmdArduino
|
||||
https://github.com/anklimov/ModbusMaster
|
||||
@@ -75,7 +75,7 @@ lib_deps =
|
||||
https://github.com/anklimov/Arduino-Temperature-Control-Library.git
|
||||
https://github.com/anklimov/DS2482_OneWire
|
||||
https://github.com/anklimov/DmxDue
|
||||
https://github.com/arduino-libraries/ArduinoHttpClient
|
||||
https://github.com/anklimov/ArduinoHttpClient
|
||||
https://github.com/anklimov/aJson
|
||||
https://github.com/anklimov/CmdArduino
|
||||
https://github.com/anklimov/ModbusMaster
|
||||
|
||||
Reference in New Issue
Block a user