some Cleanup

Mbus logging fix
Rotary Encoder input (1-st success^ to be continued)
new JSON routines
Multivent to Multi AC - interim, to be continued
This commit is contained in:
2025-04-14 00:45:38 +03:00
parent e803d1ae51
commit 2b5b780586
16 changed files with 311 additions and 8146 deletions

View File

@@ -1,27 +0,0 @@
#! /bin/bash
# usage:
# first make your own copy of template
# cp build_flags_template.sh my_build_flags.sh
# then edit, change or comment something
# nano my_build_flags.sh
# and source it
# source my_build_flags.sh
echo "==============================================Custom build flags are:====================================================="
export FLAGS="-DMY_CONFIG_SERVER=lazyhome.ru"
export FLAGS="$FLAGS -DWATCH_DOG_TICKER_DISABLE"
export FLAGS="$FLAGS -DUSE_1W_PIN=12"
export FLAGS="$FLAGS -DSD_CARD_INSERTED"
export FLAGS="$FLAGS -DSERIAL_BAUD=115200"
export FLAGS="$FLAGS -DWiz5500"
export FLAGS="$FLAGS -DDISABLE_FREERAM_PRINT"
export FLAGS="$FLAGS -DCUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:00"
export FLAGS="$FLAGS -DDMX_DISABLE"
export FLAGS="$FLAGS -DMODBUS_DISABLE"
export FLAGS="$FLAGS -DOWIRE_DISABLE"
export FLAGS="$FLAGS -DAVR_DMXOUT_PIN=18"
export FLAGS="$FLAGS -DLAN_INIT_DELAY=2000"
export FLAGS="$FLAGS -DCONTROLLINO"
export PLATFORMIO_BUILD_FLAGS="$FLAGS"
echo PLATFORMIO_BUILD_FLAGS=$PLATFORMIO_BUILD_FLAGS
echo "==============================================Custom build flags END====================================================="
unset FLAGS

View File

@@ -1,4 +1,4 @@
/* Copyright © 2017-2018 Andrey Klimov. All rights reserved.
/* Copyright © 2017-2025 Andrey Klimov. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -139,13 +139,15 @@ void Input::Parse(aJsonObject * configObj)
{
pin = static_cast<uint8_t>(itemBuffer->child->valueint);
if ((itemBuffer->child->child) && (itemBuffer->child->child->type == aJson_Int))
pin = static_cast<uint8_t>(itemBuffer->child->child->valueint);
pin2 = static_cast<uint8_t>(itemBuffer->child->child->valueint);
}
} //switch
else pin = static_cast<uint8_t>(atoi(configObj->name));
store = (inStore *) &configObj->valueint;
}
/*
// Persistant storage
itemBuffer = aJson.getObjectItem(inputObj, "@S");
if (!itemBuffer) {
@@ -154,8 +156,21 @@ void Input::Parse(aJsonObject * configObj)
itemBuffer = aJson.getObjectItem(inputObj, "@S");
}
if (itemBuffer) store = (inStore *) &itemBuffer->valueint;
*/
}
void Input::stop()
{
aJsonObject *itemBuffer;
if (!inputObj || !root || inputObj->type != aJson_Object) return;
itemBuffer = aJson.getObjectItem(inputObj, "#");
if (inType == IN_RE && itemBuffer && itemBuffer->valuestring && itemBuffer->type == aJson_Array)
{
delete (RotaryEncoder *) itemBuffer->valuestring;
itemBuffer->valuestring = NULL;
debugSerial<<F("RE: deleted")<<endl;
}
}
void cleanStore(aJsonObject * input)
{
@@ -164,7 +179,7 @@ if (input && (input->type == aJson_Object)) {
Input in(input);
in.store->aslong = 0;
aJsonObject * inputArray = aJson.getObjectItem(input, "act");
if (inputArray && (inputArray->type == aJson_Array))
if (inputArray && (inputArray->type == aJson_Array || inputArray->type == aJson_Object))
{
aJsonObject *inputObj = inputArray->child;
@@ -185,15 +200,35 @@ if (input && (input->type == aJson_Object)) {
}
}
void Input::setupRotaryEncoder()
{
aJsonObject *itemBuffer;
if (!inputObj || !root || inputObj->type != aJson_Object) return;
itemBuffer = aJson.getObjectItem(inputObj, "#");
if (itemBuffer && !itemBuffer->valuestring && itemBuffer->type == aJson_Array)
{
int pin1 = getIntFromJson(itemBuffer,1,-1);
int pin2 = getIntFromJson(itemBuffer,2,-1);
int mode = getIntFromJson(itemBuffer,3,(int)RotaryEncoder::LatchMode::FOUR3);
if (pin1>=0 && pin2>=0)
{
itemBuffer->valuestring = ( char *) new RotaryEncoder(pin1, pin2, (RotaryEncoder::LatchMode)mode);
debugSerial<<F("RE: configured on pins ")<<pin1<<","<<pin2<< F(" Mode:")<<mode <<endl;
}
}
}
void Input::setup()
{
if (!isValid() || (!root)) return;
cleanStore(inputObj);
debugSerial<<F("In: ")<<pin<<F("/")<<inType<<endl;
store->aslong=0;
uint8_t inputPinMode = INPUT; //if IN_ACTIVE_HIGH
switch (inType)
{
case IN_RE:
setupRotaryEncoder();
case IN_PUSH_ON:
case IN_PUSH_TOGGLE :
inputPinMode = INPUT_PULLUP;
@@ -256,7 +291,7 @@ switch (inType)
}
int Input::Poll(short cause) {
aJsonObject * itemBuffer;
if (!isValid()) return -1;
#ifndef CSSHDC_DISABLE
in_ccs811 _ccs811(this);
@@ -290,6 +325,13 @@ switch (cause) {
case IN_CCS811:
case IN_HDC1080:
break;
case IN_RE:
itemBuffer = aJson.getObjectItem(inputObj, "#");
if (inputObj && inputObj->type == aJson_Object && itemBuffer && itemBuffer->type == aJson_Array && itemBuffer->valuestring)
{
((RotaryEncoder *) itemBuffer->valuestring) ->tick();
contactPoll(cause, ((RotaryEncoder *) itemBuffer->valuestring));
}
}
break;
case CHECK_ULTRASONIC:
@@ -699,7 +741,7 @@ if (newState!=store->state && cause!=CHECK_INTERRUPT) debugSerial<<F("#")<<pin<<
static volatile uint8_t contactPollBusy = 0;
void Input::contactPoll(short cause) {
void Input::contactPoll(short cause, RotaryEncoder * re) {
bool currentInputState;
if (!store /*|| contactPollBusy*/) return;
@@ -730,7 +772,9 @@ else
}
else currentInputState = (digitalRead(pin) == inputOnLevel);
if (cause != CHECK_INTERRUPT) switch (store->state) //Timer based transitions
if (cause != CHECK_INTERRUPT)
{
switch (store->state) //Timer based transitions
{
case IS_PRESSED:
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_LONG,0xFFFF))
@@ -815,8 +859,24 @@ if (cause != CHECK_INTERRUPT) switch (store->state) //Timer based transitions
if (isTimeOver(store->timestamp16,millis() & 0xFFFF,T_IDLE,0xFFFF)) changeState(IS_IDLE, cause);
break;
} //switch
if (re)
{
aJsonObject * bufferItem;
switch (re->getDirection())
{
case RotaryEncoder::Direction::CLOCKWISE:
if (bufferItem=aJson.getObjectItem(inputObj, "+-")) executeCommand(bufferItem,0);
if (bufferItem=aJson.getObjectItem(inputObj, "+")) executeCommand(bufferItem);
break;
case RotaryEncoder::Direction::COUNTERCLOCKWISE:
if (bufferItem=aJson.getObjectItem(inputObj, "+-")) executeCommand(bufferItem,1);
if (bufferItem=aJson.getObjectItem(inputObj, "-")) executeCommand(bufferItem);
}
}
} //if not INTERRUPT
if (currentInputState != store->lastValue) // value changed
{
if (store->bounce) store->bounce = store->bounce - 1;

View File

@@ -21,6 +21,7 @@ e-mail anklimov@gmail.com
#include <aJSON.h>
#include "modules/in_ccs811_hdc1080.h"
#include "itemCmd.h"
#include "RotaryEncoder.h"
#define IN_ACTIVE_HIGH 2 // High level = PUSHED/ CLOSED/ ON othervise :Low Level. Use INPUT mode instead of INPUT_PULLUP for digital pin
#define IN_ANALOG 64 // Analog input
@@ -149,6 +150,7 @@ public:
int Poll(short cause);
void setup();
void stop();
static void inline onCounterChanged(int i);
static void onCounterChanged0();
@@ -163,7 +165,7 @@ public:
protected:
void Parse(aJsonObject * configObj = NULL);
void contactPoll(short cause);
void contactPoll(short cause, RotaryEncoder * re = NULL);
void analogPoll(short cause);
void dht22Poll();
@@ -183,6 +185,7 @@ protected:
char* getIdxField();
bool changeState(uint8_t newState, short cause);
void setupRotaryEncoder();
//bool executeCommand(aJsonObject* cmd, int8_t toggle = -1, char* defCmd = NULL);
};

View File

@@ -1030,7 +1030,7 @@ itemCmd itemCmd::Int(int32_t i)
return *this;
}
itemCmd itemCmd::Int(uint32_t i)
itemCmd itemCmd::uInt(uint32_t i)
{
cmd.itemArgType=ST_UINT32;
param.asUint32=i;
@@ -1163,7 +1163,7 @@ bool itemCmd::loadItem(Item * item, uint16_t optionsFlag)
{
case aJson_Int:
Int((int32_t)item->itemVal->valueint);
Int(item->itemVal->valueint);
//debugSerial<<F("Loaded Int:");
//debugOut();
return true;
@@ -1351,13 +1351,13 @@ return false;
return itemCmd().Int((uint32_t)2);
*/
case CMD_OFF:
return itemCmd().Int((uint32_t)0);
return itemCmd().Int(0);
case CMD_LOW:
return itemCmd().Int((uint32_t)20);
return itemCmd().Int(20);
case CMD_MED:
return itemCmd().Int((uint32_t)128);
return itemCmd().Int(128);
case CMD_HIGH:
return itemCmd().Int((uint32_t)255);
return itemCmd().Int(255);
default:
return *this;
@@ -1368,7 +1368,7 @@ return false;
if (matchedCmd && matchedCmd->type != aJson_NULL)
{
traceSerial<<F("MAP: cmd mapped to ")<<matchedCmd->valueint<<endl;
return itemCmd().Int((uint32_t)matchedCmd->valueint);
return itemCmd().Int(matchedCmd->valueint);
}
aJsonObject *valMapping = aJson.getObjectItem(mappingData, "val");
@@ -1399,7 +1399,7 @@ if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArray
aJson.getArrayItem(valMapping,0)->valueint,aJson.getArrayItem(valMapping,1)->valueint,
aJson.getArrayItem(valMapping,2)->valueint,aJson.getArrayItem(valMapping,3)->valueint);
traceSerial<<F("MAP: val mapped to ")<<res<<endl;
return itemCmd().Int((uint32_t) res);
return itemCmd().Int(res);
}
else if (valMapping && valMapping->type == aJson_NULL) return itemCmd(ST_VOID,CMD_VOID);

View File

@@ -231,7 +231,7 @@ public:
bool saveItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
itemCmd Int(int32_t i);
itemCmd Int(uint32_t i);
itemCmd uInt(uint32_t i);
itemCmd Float(float f);
itemCmd Tens(int32_t i);
itemCmd Tens_raw(int32_t i);

View File

@@ -192,6 +192,7 @@ if (configLocked>locksAlowed)
}
debugSerial<<F("Stopping channels ...")<<endl;
timerHandlerBusy++;
inputStop();
//Stoping the channels
if (items)
{
@@ -3039,7 +3040,7 @@ configLocked++;
// Check for nested inputs
aJsonObject * inputArray = aJson.getObjectItem(input, "act");
if (inputArray && (inputArray->type == aJson_Array))
if (inputArray && (inputArray->type == aJson_Array || inputArray->type == aJson_Object))
{
aJsonObject *inputObj = inputArray->child;
@@ -3121,6 +3122,28 @@ configLocked++;
configLocked--;
}
void inputStop(void) {
infoSerial<<F("Stopping Inputs")<<endl;
if (!inputs) return;
configLocked++;
aJsonObject *input = inputs->child;
while (input) {
if ((input->type == aJson_Object)) {
Input in(input);
in.stop();
}
yield();
input = input->next;
}
#if defined(__SAM3X8E__) && defined (TIMER_INT)
// Interval in microsecs
//detachTimer(TIMER_CHECK_INPUT * 1000, TimerHandler, "ITimer");
//detachMaturaTimer();
#endif
configLocked--;
}
// POLLINT_FAST - as often AS possible every item
// POLLING_1S - once per second every item
// POLLING_SLOW - just one item every 1S (Note: item::Poll() should return true if some action done - it will postpone next SLOW POLLING)

View File

@@ -314,6 +314,7 @@ void inputLoop(short);
void inputSensorsLoop();
void inputSetup(void);
void inputStop(void);
void pollingLoop(void);

View File

@@ -856,7 +856,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
do
{
savedValue = outValue->valueint;
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<"/"<<execObj->name<<"="<<outValue<<endl;
sendRes = sendModbus(execObj->name,outValue);
needResend = (savedValue != outValue->valueint);
while(needResend && mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),200)) modbusIdle();
@@ -874,18 +874,18 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
break;
case 0: //fault
execObj->subtype |= MB_SEND_ERROR;
errorSerial<<F("MBUS: ")<<execObj->name<<F(" send error. ");
errorSerial<<F("MBUS: ")<<item->itemArr->name<<"/"<<execObj->name<<F(" send error. ");
if ((execObj->subtype & 3) != MB_SEND_ATTEMPTS) execObj->subtype++;
errorSerial<<"Attempt: "<< (execObj->subtype & 3) <<endl;
errorSerial<<F("MBUS: ")<<item->itemArr->name<<"/"<<execObj->name<<" Attempt: "<< (execObj->subtype & 3) <<endl;
break;
case -3:
errorSerial<<F("MBUS: param ")<<execObj->name<<F(" sending cancelled")<<endl;
errorSerial<<F("MBUS: param ")<<item->itemArr->name<<"/"<<execObj->name<<F(" sending cancelled")<<endl;
//outValue->valueint=
//execObj->subtype&=~ MB_NEED_SEND;
execObj->subtype = 0;
break;
default: //param not found
errorSerial<<F("MBUS: param ")<<execObj->name<<F(" not found")<<endl;
errorSerial<<F("MBUS: param ")<<item->itemArr->name<<"/"<<execObj->name<<F(" not found")<<endl;
execObj->subtype&=~ MB_NEED_SEND;
}
}

View File

@@ -31,58 +31,69 @@ if (gatesObj)
{
if (i->name && *i->name)
{
aJsonObject * fanObj = aJson.getObjectItem(i, "fan");
if (!fanObj) {aJson.addNumberToObject(i, "fan", (long int) -1);fanObj = aJson.getObjectItem(i, "fan");}
// aJsonObject * fanObj = aJson.getObjectItem(i, "fan");
// if (!fanObj) {aJson.addNumberToObject(i, "fan", (long int) -1);fanObj = aJson.getObjectItem(i, "fan");}
aJsonObject * fanObj = getCreateObject(i,"fan",-1L);
aJsonObject * cmdObj = aJson.getObjectItem(i, "cmd");
if (!cmdObj) {aJson.addNumberToObject(i, "cmd", (long int) -1);cmdObj = aJson.getObjectItem(i, "cmd");}
// aJsonObject * cmdObj = aJson.getObjectItem(i, "cmd");
// if (!cmdObj) {aJson.addNumberToObject(i, "cmd", (long int) -1);cmdObj = aJson.getObjectItem(i, "cmd");}
aJsonObject * cmdObj = getCreateObject(i,"cmd",(long) CMD_OFF);
aJsonObject * outObj = aJson.getObjectItem(i, "out");
if (!outObj) {aJson.addNumberToObject(i, "out", (long int) -1);outObj = aJson.getObjectItem(i, "out");}
//aJsonObject * outObj = aJson.getObjectItem(i, "out");
//if (!outObj) {aJson.addNumberToObject(i, "out", (long int) -1);outObj = aJson.getObjectItem(i, "out");}
aJsonObject * outObj = getCreateObject(i,"out",-1L);
aJsonObject * pidObj = aJson.getObjectItem(i, "pid");
if (pidObj && pidObj->type == aJson_Array && aJson.getArraySize(pidObj)>=3)
{
aJsonObject * setObj = aJson.getObjectItem(i, "set");
if (!setObj) {aJson.addNumberToObject(i, "set", (float) 20.1);setObj = aJson.getObjectItem(i, "set");}
else if (setObj->type != aJson_Float) {setObj->valuefloat = 20.0;setObj->type= aJson_Float;}
//aJsonObject * setObj = aJson.getObjectItem(i, "set");
//if (!setObj) {aJson.addNumberToObject(i, "set", (float) 20.1);setObj = aJson.getObjectItem(i, "set");}
// else if (setObj->type != aJson_Float) {setObj->valuefloat = 20.0;setObj->type= aJson_Float;}
aJsonObject * setObj = getCreateObject(i,"set",(float) 20.0);
aJsonObject * valObj = aJson.getObjectItem(i, "val");
if (!valObj) {aJson.addNumberToObject(i, "val", (float) 20.1);valObj = aJson.getObjectItem(i, "val");}
else if (valObj->type != aJson_Float) {valObj->valuefloat = 20.0;valObj->type= aJson_Float;}
//aJsonObject * valObj = aJson.getObjectItem(i, "val");
//if (!valObj) {aJson.addNumberToObject(i, "val", (float) 20.1);valObj = aJson.getObjectItem(i, "val");}
// else if (valObj->type != aJson_Float) {valObj->valuefloat = 20.0;valObj->type= aJson_Float;}
aJsonObject * valObj = getCreateObject(i,"val",(float) 20.0);
aJsonObject * poObj = aJson.getObjectItem(i, "po");
if (!poObj) {aJson.addNumberToObject(i, "po", (float) -1.1);poObj = aJson.getObjectItem(i, "po");}
else if (poObj->type != aJson_Float) {poObj->valuefloat = -2.0;valObj->type= aJson_Float;}
//aJsonObject * poObj = aJson.getObjectItem(i, "po");
//if (!poObj) {aJson.addNumberToObject(i, "po", (float) -1.1);poObj = aJson.getObjectItem(i, "po");}
// else if (poObj->type != aJson_Float) {poObj->valuefloat = -2.0;valObj->type= aJson_Float;}
aJsonObject * poObj = getCreateObject(i,"po", (long) -2);
float kP = 1.0;
float kI = 0.0;
float kD = 0.0;
int direction = DIRECT;
aJsonObject * param = aJson.getArrayItem(pidObj, 0);
if (param->type == aJson_Float) kP=param->valuefloat;
else if (param->type == aJson_Int) kP=param->valueint;
// aJsonObject * param = aJson.getArrayItem(pidObj, 0);
// if (param->type == aJson_Float) kP=param->valuefloat;
// else if (param->type == aJson_Int) kP=param->valueint;
kP=getFloatFromJson(pidObj,0,1.0);
if (kP<0)
{
kP=-kP;
direction=REVERSE;
}
param = aJson.getArrayItem(pidObj, 1);
if (param->type == aJson_Float) kI=param->valuefloat;
else if (param->type == aJson_Int) kI=param->valueint;
//param = aJson.getArrayItem(pidObj, 1);
//if (param->type == aJson_Float) kI=param->valuefloat;
// else if (param->type == aJson_Int) kI=param->valueint;
kI=getFloatFromJson(pidObj,1);
param = aJson.getArrayItem(pidObj, 2);
if (param->type == aJson_Float) kD=param->valuefloat;
else if (param->type == aJson_Int) kD=param->valueint;
//param = aJson.getArrayItem(pidObj, 2);
//if (param->type == aJson_Float) kD=param->valuefloat;
// else if (param->type == aJson_Int) kD=param->valueint;
kD=getFloatFromJson(pidObj,2);
float dT=5.0;
if (aJson.getArraySize(pidObj)==4)
{
param = aJson.getArrayItem(pidObj, 3);
if (param->type == aJson_Float) dT=param->valuefloat;
else if (param->type == aJson_Int) dT=param->valueint;
}
float dT;
//if (aJson.getArraySize(pidObj)==4)
//{
//param = aJson.getArrayItem(pidObj, 3);
//if (param->type == aJson_Float) dT=param->valuefloat;
// else if (param->type == aJson_Int) dT=param->valueint;
//}
dT=getFloatFromJson(pidObj,3,5.0);
debugSerial << "VENT: X:" << (long int) &valObj->valuefloat << "-" << (long int)&poObj->valuefloat <<"="<< (long int)&setObj->valuefloat<<endl;
pidObj->valueint = (long int) new PID (&valObj->valuefloat, &poObj->valuefloat, &setObj->valuefloat, kP, kI, kD, direction);
@@ -259,7 +270,7 @@ while (i)
aJsonObject * cmdObj=aJson.getObjectItem(i, "cmd");
aJsonObject * cascadeObj=aJson.getObjectItem(i, "cas");
aJsonObject * setObj=aJson.getObjectItem(i, "set");
//aJsonObject * setObj=aJson.getObjectItem(i, "set");
aJsonObject * pidObj=aJson.getObjectItem(i, "pid");
if (fanObj && cmdObj && fanObj->type==aJson_Int && cmdObj->type==aJson_Int)
{
@@ -360,19 +371,21 @@ while (i)
case S_SET:
if (cmd.isValue())
{
if (!setObj) {aJson.addNumberToObject(i, "set", (float) cmd.getFloat()); setObj = aJson.getObjectItem(i, "set"); }
else {setObj->valuefloat = cmd.getFloat();setObj->type = aJson_Float;}
//publishTopic(i->name,setObj->valuefloat,"/set");
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
//if (!setObj) {aJson.addNumberToObject(i, "set", (float) cmd.getFloat()); setObj = aJson.getObjectItem(i, "set"); }
// else {setObj->valuefloat = cmd.getFloat();setObj->type = aJson_Float;}
setValToJson(i,"set",cmd.getFloat());
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
}
break;
case S_VAL:
if (cmd.isValue())
{
aJsonObject * valObj = aJson.getObjectItem(i, "val");
if (!valObj) {aJson.addNumberToObject(i, "val", (float) cmd.getFloat()); setObj = aJson.getObjectItem(i, "val");}
else {valObj->valuefloat = cmd.getFloat();valObj->type= aJson_Float;}
//aJsonObject * valObj = aJson.getObjectItem(i, "val");
//if (!valObj) {aJson.addNumberToObject(i, "val", (float) cmd.getFloat()); setObj = aJson.getObjectItem(i, "val");}
// else {valObj->valuefloat = cmd.getFloat();valObj->type= aJson_Float;}
setValToJson(i,"val",cmd.getFloat());
}
return 1;
break;

View File

@@ -162,7 +162,7 @@ itemCmd getNumber(char **chan) {
}
}
if (!fractlen) val.Int((int32_t) atol(*chan));
if (!fractlen) val.Int(atol(*chan));
else if (fractlen<=TENS_FRACT_LEN && intlen+TENS_FRACT_LEN<=9)
{
long intpart = atol(*chan);
@@ -1016,7 +1016,7 @@ if (a->type == aJson_Array)
return NULL;
}
char* getStringFromJson(aJsonObject * a, char * name)
char* getStringFromJson(aJsonObject * a, const char * name)
{
aJsonObject * element = NULL;
if (!a) return NULL;
@@ -1039,7 +1039,7 @@ if (element && element->type == aJson_Float) return element->valuefloat;
return def;
}
long getIntFromJson(aJsonObject * a, char * name, long def)
long getIntFromJson(aJsonObject * a, const char * name, long def)
{
aJsonObject * element = NULL;
if (!a) return def;
@@ -1063,7 +1063,7 @@ if (element && element->type == aJson_Int) return element->valueint;
return def;
}
float getFloatFromJson(aJsonObject * a, char * name, float def)
float getFloatFromJson(aJsonObject * a, const char * name, float def)
{
aJsonObject * element = NULL;
if (!a) return def;
@@ -1071,8 +1071,42 @@ if (a->type == aJson_Object)
element = aJson.getObjectItem(a, name);
if (element && element->type == aJson_Float) return element->valuefloat;
//if (element && element->type == aJson_Int) return element->valueint;
if (element && element->type == aJson_Int) return element->valueint;
return def;
}
aJsonObject * getCreateObject(aJsonObject * a, int n)
{
if (!a) return NULL;
if (a->type == aJson_Array)
{
aJsonObject * element = aJson.getArrayItem(a, n);
if (!element)
{
for (int i = aJson.getArraySize(a); i < n; i++)
aJson.addItemToArray(a, element = aJson.createNull());
}
return element;
}
return NULL;
}
aJsonObject * getCreateObject(aJsonObject * a, const char * name)
{
if (!a) return NULL;
if (a->type == aJson_Object)
{
aJsonObject * element = aJson.getObjectItem(a, name);
if (!element)
{
aJson.addNullToObject(a, name);
element = aJson.getObjectItem(a, name);
return element;
}
}
return NULL;
}
#pragma message(VAR_NAME_VALUE(debugSerial))
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))

View File

@@ -83,11 +83,102 @@ bool checkToken(char * token, char * data);
bool i2cReset();
uint16_t getCRC(aJsonObject * in);
char* getStringFromJson(aJsonObject * a, int i);
char* getStringFromJson(aJsonObject * a, char * name);
char* getStringFromJson(aJsonObject * a, const char * name);
long getIntFromJson(aJsonObject * a, int i, long def = 0);
long getIntFromJson(aJsonObject * a, char * name, long def = 0);
long getIntFromJson(aJsonObject * a, const char * name, long def = 0);
float getFloatFromJson(aJsonObject * a, int i, float def = 0.0);
float getFloatFromJson(aJsonObject * a, char * name, float def = 0.0);
float getFloatFromJson(aJsonObject * a, const char * name, float def = 0.0);
// Get object from array, create if absent and return pointer to object
template<typename Type>
aJsonObject * getCreateObject(aJsonObject * a, int n, Type def); //set num value if created
aJsonObject * getCreateObject(aJsonObject * a, int n); //just create null object if not find
// Get object from object by name, create absent find and return pointer to object
template<typename Type>
aJsonObject * getCreateObject(aJsonObject * a, const char * name, Type def); //set num value if created
aJsonObject * getCreateObject(aJsonObject * a, const char * name); //just create null object if not find
template<typename Type>
aJsonObject * setValToJson(aJsonObject * a, int n, Type val);
template<typename Type>
aJsonObject * setValToJson(aJsonObject * a, const char * name, Type val);
template<typename Type>
aJsonObject * getCreateObject(aJsonObject * a, int n, Type val)
{
if (!a) return NULL;
if (a->type == aJson_Array)
{
aJsonObject * element = aJson.getArrayItem(a, n);
if (!element)
for (int i = aJson.getArraySize(a); i < n; i++)
if (i==n-1)
aJson.addItemToArray(a, element = aJson.createItem(val));
else aJson.addItemToArray(a, element = aJson.createNull());
return element;
}
return NULL;
}
template<typename Type>
aJsonObject * getCreateObject(aJsonObject * a, const char * name, Type def)
{
if (!a) return NULL;
if (a->type == aJson_Object)
{
aJsonObject * element = aJson.getObjectItem(a, name);
if (!element)
{
aJson.addNumberToObject(a, name, def);
element = aJson.getObjectItem(a, name);
return element;
}
}
return NULL;
}
template<typename Type>
aJsonObject * setValToJson(aJsonObject * a, const char * name, Type val)
{
aJsonObject * element = getCreateObject(a,name);
if (element)
switch (element->type)
{
case aJson_Float: element->valuefloat = val;
break;
case aJson_NULL: element->type = aJson_Int;
case aJson_Int: element->valueint = val;
}
return element;
}
template<typename Type>
aJsonObject * setValToJson(aJsonObject * a, int n, Type val)
{
aJsonObject * element = getCreateObject(a,n);
if (element)
switch (element->type)
{
case aJson_Float: element->valuefloat = val;
break;
case aJson_NULL: element->type = aJson_Int;
case aJson_Int: element->valueint =val;
}
return element;
}
#ifdef CANDRV
#include "util/crc16_.h"
class CRCStream : public Stream

View File

@@ -1,27 +0,0 @@
#! /bin/bash
# usage:
# first make your own copy of template
# cp build_flags_template.sh my_build_flags.sh
# then edit, change or comment something
# nano my_build_flags.sh
# and source it
# source my_build_flags.sh
echo "==============================================Custom build flags are:====================================================="
export FLAGS="-DMY_CONFIG_SERVER=lazyhome.ru"
# export FLAGS="$FLAGS -DWATCH_DOG_TICKER_DISABLE"
# export FLAGS="$FLAGS -DUSE_1W_PIN=12"
# export FLAGS="$FLAGS -DSD_CARD_INSERTED"
export FLAGS="$FLAGS -DSERIAL_BAUD=115200"
export FLAGS="$FLAGS -DWiz5500"
# export FLAGS="$FLAGS -DDISABLE_FREERAM_PRINT"
export FLAGS="$FLAGS -DCUSTOM_FIRMWARE_MAC=de:ad:be:ef:fe:00"
# export FLAGS="$FLAGS -DDMX_DISABLE"
# export FLAGS="$FLAGS -DMODBUS_DISABLE"
# export FLAGS="$FLAGS -DOWIRE_DISABLE"
# export FLAGS="$FLAGS -DAVR_DMXOUT_PIN=18"
export FLAGS="$FLAGS -DLAN_INIT_DELAY=500"
# export FLAGS="$FLAGS -DCONTROLLINO"
export PLATFORMIO_BUILD_FLAGS="$FLAGS"
echo PLATFORMIO_BUILD_FLAGS=$PLATFORMIO_BUILD_FLAGS
echo "==============================================Custom build flags END====================================================="
unset FLAGS

View File

@@ -188,6 +188,7 @@ lib_deps =
https://github.com/anklimov/Arduino-PID-Library.git
;ArduinoMDNS
https://github.com/khoih-prog/TimerInterrupt_Generic.git
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
@@ -263,6 +264,7 @@ lib_deps =
;ESPmDNS
https://github.com/khoih-prog/TimerInterrupt_Generic.git
https://github.com/anklimov/arduino-CAN.git
https://github.com/mathertel/RotaryEncoder
[env:due]
;Experimental target with universal Ethernet Library
@@ -333,6 +335,7 @@ lib_deps =
rweather/Crypto
collin80/can_common
collin80/due_can
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
[env:mega2560slim]
@@ -474,6 +477,7 @@ lib_deps =
ArduinoMDNS
https://github.com/khoih-prog/TimerInterrupt_Generic.git
rweather/Crypto
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
@@ -526,12 +530,15 @@ lib_deps =
https://github.com/anklimov/Arduino-PID-Library.git
ArduinoMDNS
https://github.com/khoih-prog/TimerInterrupt_Generic.git
https://github.com/mathertel/RotaryEncoder
[env:esp8266-wifi]
platform = espressif8266
framework = arduino
monitor_filters = esp8266_exception_decoder
build_type = debug
;board = nodemcuv2
;esp12e ESP8266 80MHz 4MB 80KB Espressif ESP8266 ESP-12E
;esp01_1m ESP8266 80MHz 1MB 80KB Espressif Generic ESP8266 ESP-01 1M
@@ -624,6 +631,7 @@ lib_deps =
;ArduinoMDNS
;MDNS
ESP8266mDNS
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
[env:mega2560-5100]
@@ -677,6 +685,7 @@ lib_deps =
https://github.com/anklimov/Arduino-PID-Library.git
ArduinoMDNS
https://github.com/khoih-prog/TimerInterrupt_Generic.git
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
@@ -748,6 +757,7 @@ lib_deps =
rweather/Crypto
https://github.com/collin80/due_can.git
https://github.com/collin80/can_common.git
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
[env:controllino]
@@ -799,6 +809,7 @@ lib_deps =
https://github.com/anklimov/Arduino-PID-Library.git
ArduinoMDNS
https://github.com/khoih-prog/TimerInterrupt_Generic.git
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
@@ -858,6 +869,7 @@ lib_deps =
ArduinoMDNS
https://github.com/khoih-prog/TimerInterrupt_Generic.git
https://github.com/anklimov/ModbusMaster
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
@@ -927,8 +939,7 @@ lib_deps =
ArduinoMDNS
https://github.com/khoih-prog/TimerInterrupt_Generic.git
https://github.com/anklimov/ModbusMaster
https://github.com/anklimov/ModbusMaster
https://github.com/mathertel/RotaryEncoder
monitor_speed = 115200
@@ -999,6 +1010,7 @@ lib_deps =
https://github.com/anklimov/ModbusMaster
pazi88/STM32_CAN
ericksimoes/Ultrasonic
https://github.com/mathertel/RotaryEncoderv
monitor_speed = 115200

View File

@@ -1,53 +0,0 @@
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
function post_cmd(endpoint, param) {
var username = $("input#login").val();
var password = $("input#password").val();
var surl = $("input#url").val();
var settings = {
"url": surl+endpoint,
//"http://192.168.11.234:65280"+endpoint,
"method": "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
xhr.setRequestHeader ("Pragma", "no-cache");
//xhr.withCredentials = true;
},
"timeout": 20000,
"headers": {
"Content-Type": "text/plain"
},
"data": param+"\n",
};
$.ajax(settings).done(function (response) {
document.getElementById("resp").innerHTML = response;
});
}
</script>
<h1>LazyHome PWA </h1>
<form name="cookieform" id="loginform">
<table>
<tr>
<td>URL:<td><input type="text" name="url" id="url" value="" class="text"/>
<tr>
<td>Login: <td><input type="text" name="login" id="login" value="arduino" class="text"/>
<td>Password: <td> <input type="text" name="password" id="password" value="password" class="text"/>
</tr>
</table>
</form>
<table>
<tr>
<td><button onclick='post_cmd("/item/relays/cmd","toggle")'>Toggle</button>
<td><button onclick='post_cmd("/command/save","")'>Save</button>
<td><button onclick='post_cmd("/command/reboot","")'>Reboot</button>
<td><button onclick='post_cmd("/command/get,"")'>Get</button>
<td><button onclick='post_cmd("/command/load","")'>Load</button>
<tr>
<td>item:<td><input type="text" name="item" id="item" value="" class="text"/>
<td>command:<td><input type="text" name="command" id="command" value="toggle" class="text"/>
<td><button onclick='post_cmd("/item/"+$("input#item").val(),$("input#command").val())'>Exec</button>
</table>
<p id="resp"></p>

View File

@@ -1,302 +0,0 @@
{
"mqtt":["edem3","192.168.88.2"],
"syslog":["192.168.88.2"],
"dmx":[3,80],
"topics":{"root":"edem"},
"items":
{
"lightall":[7,[
"lampbedr3",
"lampcab31",
"lampcab32",
"lampsauna3",
"lampbath33",
"lampktc3",
"lampwc3",
"lamp4",
"lampext4",
"lamphall3",
"lampstw3",
"fasadeast",
"bra31",
"lampgst3",
"lampkln3",
"lampbalk3",
"fasadsouth",
"bra32"]],
"gr_hall3":[7,["lamphall3","lampstw3"]],
"gr_gost3":[7,["lampgst3","lampktc3"]],
"relays":[7,["pout0","thermostat","pout2","pout3","pout4","pout5","pout6"]],
"uouts":[7,["unprot0","unprot1","unprot2","unprot3","unprot4","unprot5","unprot6","unprot7"]],
"mb1":[44,[1,0,3,100]],
"mb2":[44,[1,1,3,100]],
"mb3":[44,[1,2,3,100]],
"mb4":[44,[1,3,3,100]],
"mba":[44,[96,0,0]],
"lamp_zal":[4,[1,60001,-1,255]],
"lampbedr3":[0,1],
"lampcab31":[0,2],
"lampcab32":[0,3],
"lampsauna3":[0,4],
"lampbath3":[0,5],
"lampwc3":[0,6],
"lampktc3":[0,7],
"lamp4":[0,8],
"lamphall3":[0,9],
"lampext4":[0,10],
"lampstw3":[0,11],
"fasadeast":[0,12],
"lampgst3":[0,13],
"bra31":[0,14],
"bra32":[0,15],
"lampbalk3":[0,16],
"fasadsouth":[0,17],
"lampkln3":[0,18],
"lampbar3":[0,21],
"ledbedr3":[1,22],
"ledcab31":[1,26],
"ledcab32":[1,30],
"ledkab":[7,["ledcab31","ledcab32"]],
"ledsauna31":[1,34],
"ledsauna32":[1,38],
"ledsauna":[7,["ledsauna31","ledsauna32"]],
"led4":[1,42],
"ledktc31":[1,48],
"ledktc31w":[0,52],
"ledktc32":[1,53],
"ledktc32w":[0,57],
"ledgst31":[1,58],
"ledgst31w":[0,62],
"ledgst32":[1,63],
"ledgst32w":[0,67],
"ledktc3w":[7,["ledktc31w","ledktc32w","ledgst31w","ledgst32w"]],
"ledktc3":[7,["ledktc31","ledktc32","ledgst31","ledgst32"]],
"fanbath3":[0,68],
"fanwc3":[0,69],
"pout0":[6,22],
"thermostat":[5,23,33],
"pout2":[6,24],
"water3":[6,25],
"pout4":[3,9],
"pout5":[3,8],
"pout6":[3,11],
"pout7":[6,12],
"pwm0" :[3,4],
"pwm1" :[3,5],
"pwm2" :[3,6],
"pwm3" :[3,7],
"pwm10":[3,10],
"unprot0":[6,33],
"unprot1":[6,32],
"unprot2":[6,31],
"unprot3":[6,30],
"unprot4":[6,29],
"unprot5":[6,28],
"unprot6":[6,27],
"unprot7":[6,26]
},
"in":
[ {"#":42,"emit":"power3","item":"fanwc3"},
{"#":44,"emit":"in1"},
{"#":46,"emit":"in2"},
{"#":49,"emit":"in3"},
{"#":43,"emit":"in4"},
{"#":45,"emit":"in5"},
{"#":47,"emit":"in6"},
{"#":48,"emit":"in7"},
{"#":34,"emit":"in8"},
{"#":36,"emit":"in9"},
{"#":38,"T":0,
"click":{"item":"gr_hall3","icmd":"ON"},
"dclick":{"item":"lampbedr3","icmd":"ON"},
"tclick":{"item":"lightall","icmd":"REST"},
"rpcmd":{"item":"gr_hall3","icmd":"%+2"}
},
{"#":40,"T":0,
"click":{"item":"gr_hall3","icmd":"OFF"},
"dclick":{"item":"lampbedr3","icmd":"OFF"},
"tclick":{"item":"lightall","icmd":"HALT"},
"rpcmd":{"item":"gr_hall3","icmd":"%-2"}
},
{"#":35,"T":0,
"click":{"item":"gr_gost3","icmd":"ON"},
"dclick":{"item":"lampwc3","icmd":"ON"},
"tclick":{"item":"lampbath3","icmd":"ON"},
"rpcmd":{"item":"gr_gost3","icmd":"%+2"}
},
{"#":37,"T":0,
"click":{"item":"gr_gost3","icmd":"OFF"},
"dclick":{"item":"lampwc3","icmd":"OFF"},
"tclick":{"item":"lampbath3","icmd":"OFF"},
"rpcmd":{"item":"gr_gost3","icmd":"%-2"}
},
{"#":39,"emit":"in14"},
{"#":41,"emit":"in15"},
{"#":54,"T":0,"act":
[
{
"map":[128,640],
"click":{"item":"gr_gost3","icmd":"ON"},
"dclick":{"item":"lampwc3","icmd":"ON"},
"tclick":{"item":"lampbath3","icmd":"ON"},
"rpcmd":{"item":"gr_gost3","icmd":"%+2"}
},
{
"map":[641,1024],
"click":{"item":"gr_gost3","icmd":"OFF"},
"dclick":{"item":"lampwc3","icmd":"OFF"},
"tclick":{"item":"lampbath3","icmd":"OFF"},
"rpcmd":{"item":"gr_gost3","icmd":"%-2"}
}
]},
{"#":55,"T":66,"emit":"a01","map":[0,1024,0,1024,10]},
{"#":56,"T":66,"emit":"a02","map":[0,1024,0,1024,10]},
{"#":57,"T":66,"emit":"a03","map":[0,1024,0,1024,10]},
{"#":58,"T":66,"emit":"a04","map":[0,1024,0,1024,10]},
{"#":59,"T":66,"emit":"a05","map":[0,1024,0,1024,10]},
{"#":60,"T":0,"act":
[
{
"map":[128,640],
"click":{"item":"gr_hall3","icmd":"ON"},
"dclick":{"item":"lampbedr3","icmd":"ON"},
"tclick":{"item":"lightall","icmd":"REST"},
"rpcmd":{"item":"gr_hall3","icmd":"%+2"}
},
{
"map":[641,1024],
"click":{"item":"gr_hall3","icmd":"OFF"},
"dclick":{"item":"lampbedr3","icmd":"OFF"},
"tclick":{"item":"lightall","icmd":"HALT"},
"rpcmd":{"item":"gr_hall3","icmd":"%-2"}
}
]},
{"#":61,"T":0,"act":
[
{
"map":[128,640],
"click":{"item":"gr_gost3","icmd":"ON"},
"dclick":{"item":"lampwc3","icmd":"ON"},
"tclick":{"item":"lampbath3","icmd":"ON"},
"rpcmd":{"item":"gr_gost3","icmd":"%+2"}
},
{
"map":[641,1024],
"click":{"item":"gr_gost3","icmd":"OFF"},
"dclick":{"item":"lampwc3","icmd":"OFF"},
"tclick":{"item":"lampbath3","icmd":"OFF"},
"rpcmd":{"item":"gr_gost3","icmd":"%-2"}
}
]},
{"#":62,"T":66,"emit":"a08","map":[0,1024,0,1024,10]},
{"#":63,"T":66,"emit":"a09","map":[0,1024,0,1024,10]},
{"#":64,"T":66,"emit":"a10","map":[0,1024,0,1024,10]},
{"#":65,"T":66,"emit":"a11","map":[0,1024,0,1024,10]},
{"#":66,"T":0,"emit":"leak31","item":"water3","scmd":"OFF","rcmd":"ON"},
{"#":67,"T":2,"emit":"leak32","item":"water3","scmd":"OFF","rcmd":"ON"},
{"#":68,"T":0,"emit":"leak33","item":"water3","scmd":"OFF","rcmd":"ON"},
{"#":69,"T":0,"emit":"a15"}
],
"in2":
{ "42":{"emit":"power3","item":"fanwc3"},
"44":{"emit":"in1"},
"46":{"emit":"in2"},
"49":{"emit":"in3"},
"43":{"emit":"in4"},
"45":{"emit":"in5"},
"47":{"emit":"in6"},
"48":{"emit":"in7"},
"34":{"emit":"in8"},
"36":{"emit":"in9"},
"38":{"T":0,
"click":{"item":"gr_hall3","icmd":"ON"},
"dclick":{"item":"lampbedr3","icmd":"ON"},
"tclick":{"item":"lightall","icmd":"REST"},
"rpcmd":{"item":"gr_hall3","icmd":"%+2"}
},
"40":{"T":0,
"click":{"item":"gr_hall3","icmd":"OFF"},
"dclick":{"item":"lampbedr3","icmd":"OFF"},
"tclick":{"item":"lightall","icmd":"HALT"},
"rpcmd":{"item":"gr_hall3","icmd":"%-2"}
},
"35":{"T":0,
"click":{"item":"gr_gost3","icmd":"ON"},
"dclick":{"item":"lampwc3","icmd":"ON"},
"tclick":{"item":"lampbath3","icmd":"ON"},
"rpcmd":{"item":"gr_gost3","icmd":"%+2"}
},
"37":{"T":0,
"click":{"item":"gr_gost3","icmd":"OFF"},
"dclick":{"item":"lampwc3","icmd":"OFF"},
"tclick":{"item":"lampbath3","icmd":"OFF"},
"rpcmd":{"item":"gr_gost3","icmd":"%-2"}
},
"39":{"emit":"in14"},
"41":{"emit":"in15"},
"54":{"addr":54,"T":0,"act":
[
{
"map":[128,640],
"click":{"item":"gr_gost3","icmd":"ON"},
"dclick":{"item":"lampwc3","icmd":"ON"},
"tclick":{"item":"lampbath3","icmd":"ON"},
"rpcmd":{"item":"gr_gost3","icmd":"%+2"}
},
{
"map":[641,1024],
"click":{"item":"gr_gost3","icmd":"OFF"},
"dclick":{"item":"lampwc3","icmd":"OFF"},
"tclick":{"item":"lampbath3","icmd":"OFF"},
"rpcmd":{"item":"gr_gost3","icmd":"%-2"}
}
]},
"55":{"T":66,"emit":"a01","map":[0,1024,0,1024,10]},
"56":{"T":66,"emit":"a02","map":[0,1024,0,1024,10]},
"57":{"T":66,"emit":"a03","map":[0,1024,0,1024,10]},
"58":{"T":66,"emit":"a04","map":[0,1024,0,1024,10]},
"59":{"T":66,"emit":"a05","map":[0,1024,0,1024,10]},
"60":{"T":66,"emit":"a06","map":[0,1024,0,1024,10]},
"61":{"T":66,"emit":"a07","map":[0,1024,0,1024,10]},
"62":{"T":66,"emit":"a08","map":[0,1024,0,1024,10]},
"63":{"T":66,"emit":"a09","map":[0,1024,0,1024,10]},
"64":{"T":66,"emit":"a10","map":[0,1024,0,1024,10]},
"65":{"T":66,"emit":"a11","map":[0,1024,0,1024,10]},
"66":{"T":0,"emit":"leak31","item":"water3","scmd":"OFF","rcmd":"ON"},
"67":{"T":2,"emit":"leak32","item":"water3","scmd":"OFF","rcmd":"ON"},
"68":{"T":0,"emit":"leak33","item":"water3","scmd":"OFF","rcmd":"ON"}
}
}

File diff suppressed because it is too large Load Diff