#include "xb_CAYENNE_MOD.h"
#include <xb_board.h>
#include <xb_GUI_Gadget.h>
#include <xb_GUI.h>
#include <Preferences.h>
#include <CAYENNEMQTTESP32.h>
CayenneMQTTWiFiClient *Cayenne;
CAYENNE_IN_DEFAULT()
{
board.Log(String("Request channel "+String(request.channel)).c_str(),true,true);
board.Log(String("Request Value " + String(getValue.asStr())).c_str(), true, true);
}
CAYENNE_OUT_DEFAULT()
{
Cayenne->digitalSensorWrite(20, 1);
}
TCayenneFrameItem *CayenneFrameItemList;
uint32_t CayenneFrameItemList_Count;
TIDROM ChannelAsIDROM[CAYENNE_CHANNELS_USE];
bool XB_CAYENNE_MOD_DoMessage(TMessageBoard *Am);
void XB_CAYENNE_MOD_Setup();
uint32_t XB_CAYENNE_MOD_DoLoop();
TTaskDef XB_CAYENNE_MOD_DefTask = { &XB_CAYENNE_MOD_Setup,&XB_CAYENNE_MOD_DoLoop,&XB_CAYENNE_MOD_DoMessage,NULL,1 };
typedef enum { fscIDLE, fscLoadConfig, fscInit, fscDeInit, fscConnected } TFunctionStepCAYENNE_MOD;
TFunctionStepCAYENNE_MOD FunctionStepCAYENNE_MOD;
bool XB_CAYENNE_MOD_DEBUG = true;
Preferences cfg;
String CAYENNE_MOD_MQTT_USERNAME;
String CAYENNE_MOD_MQTT_PASSWORD;
String CAYENNE_MOD_CLIENTID;
String CAYENNE_MOD_MQTT_SERVER;
uint16_t CAYENNE_MOD_MQTT_PORT;
TCayenneFrameItem *XB_CAYENNE_MOD_NEW_TCayenneFrameItem()
{
TCayenneFrameItem *cfi = (TCayenneFrameItem *)board.malloc_psram(sizeof(TCayenneFrameItem));
if (cfi != NULL)
{
ADD_TO_LIST_STR(CayenneFrameItemList, TCayenneFrameItem, cfi);
CayenneFrameItemList_Count++;
}
return cfi;
}
void XB_CAYENNE_MOD_DELETE_TCayenneFrameItem(TCayenneFrameItem *Acfi)
{
if (Acfi != NULL)
{
DELETE_FROM_LIST_STR(CayenneFrameItemList, Acfi);
board.free(Acfi);
CayenneFrameItemList_Count--;
}
}
void XB_CAYENNE_MOD_SetupServer()
{
if (Cayenne != NULL)
{
delete(Cayenne);
Cayenne = NULL;
}
Cayenne = new CayenneMQTTWiFiClient();
Cayenne->begin(CAYENNE_MOD_MQTT_USERNAME.c_str(), CAYENNE_MOD_MQTT_PASSWORD.c_str(), CAYENNE_MOD_CLIENTID.c_str());
}
bool XB_CAYENNE_MOD_LoopServer()
{
Cayenne->loop();
return true;
}
uint8_t XB_CAYENNE_MOD_GetChannelByIDROM(TIDROM Aidrom)
{
uint8_t res = 255;
for (uint8_t i = 0; i < CAYENNE_CHANNELS_USE; i++)
{
if (Aidrom.ROM == ChannelAsIDROM[i].ROM)
{
res = i;
break;
}
}
return res;
}
uint8_t XB_CAYENNE_MOD_GetFreeChannel()
{
uint8_t res = 255;
for (uint8_t i = 0; i < CAYENNE_CHANNELS_USE; i++)
{
if (ChannelAsIDROM[i].ROM==0)
{
res = i;
break;
}
}
return res;
}
void XB_CAYENNE_MOD_ClearChannelAsIDROM()
{
if (XB_CAYENNE_MOD_DEBUG) board.Log("Clear Channel as IDROM table", true, true);
for (uint8_t i = 0; i < CAYENNE_CHANNELS_USE; i++)
{
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
ChannelAsIDROM[i].ROM = 0;
}
if (XB_CAYENNE_MOD_DEBUG) board.Log("OK");
}
bool XB_CAYENNE_MOD_LoadConfig()
{
if (XB_CAYENNE_MOD_DEBUG) board.Log(FSS("Load config"), true, true);
cfg.begin("CAYENNE_MOD");
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
CAYENNE_MOD_MQTT_USERNAME = cfg.getString("MQTT_USERNAME", CAYENNE_DEFAULT_MQTT_USERNAME);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
CAYENNE_MOD_MQTT_PASSWORD = cfg.getString("MQTT_PASSWORD", CAYENNE_DEFAULT_MQTT_PASSWORD);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
CAYENNE_MOD_CLIENTID = cfg.getString("CLIENTID", CAYENNE_DEFAULT_CLIENTID);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
CAYENNE_MOD_MQTT_SERVER = cfg.getString("MQTT_SERVER", CAYENNE_DEFAULT_MQTT_SERVER);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
CAYENNE_MOD_MQTT_PORT = cfg.getUShort("MQTT_PORT", CAYENNE_DEFAULT_MQTT_PORT);
cfg.getBytes("ChannelAsIDROM", &ChannelAsIDROM, sizeof(ChannelAsIDROM));
cfg.end();
if (XB_CAYENNE_MOD_DEBUG) board.Log(FSS("OK"));
return true;
}
bool XB_CAYENNE_MOD_SaveConfig()
{
if (XB_CAYENNE_MOD_DEBUG) board.Log(FSS("Save config"), true, true);
cfg.begin("CAYENNE_MOD");
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
cfg.putString("MQTT_USERNAME", CAYENNE_MOD_MQTT_USERNAME);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
cfg.putString("MQTT_PASSWORD", CAYENNE_MOD_MQTT_PASSWORD);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
cfg.putString("CLIENTID", CAYENNE_MOD_CLIENTID);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
cfg.putString("MQTT_SERVER", CAYENNE_MOD_MQTT_SERVER);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
cfg.putUShort("MQTT_PORT", CAYENNE_MOD_MQTT_PORT);
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
cfg.putBytes("ChannelAsIDROM", &ChannelAsIDROM, sizeof(ChannelAsIDROM));
if (XB_CAYENNE_MOD_DEBUG) board.Log('.');
cfg.end();
if (XB_CAYENNE_MOD_DEBUG) board.Log(FSS("OK"));
return true;
}
void XB_CAYENNE_MOD_Setup()
{
board.Log(FSS("Init."), true, true, &XB_CAYENNE_MOD_DefTask);
FunctionStepCAYENNE_MOD = fscLoadConfig;
board.Log(FSS("..OK"));
}
uint32_t XB_CAYENNE_MOD_DoLoop()
{
switch (FunctionStepCAYENNE_MOD)
{
case fscIDLE:
{
return 5000;
}
case fscLoadConfig:
{
XB_CAYENNE_MOD_LoadConfig();
FunctionStepCAYENNE_MOD = fscIDLE;
break;
}
case fscInit:
{
if (XB_CAYENNE_MOD_DEBUG) board.Log("Connect..", true, true);
XB_CAYENNE_MOD_SetupServer();
if (XB_CAYENNE_MOD_DEBUG) board.Log(".OK");
FunctionStepCAYENNE_MOD = fscConnected;
return 10;
}
case fscDeInit:
{
if (XB_CAYENNE_MOD_DEBUG) board.Log("Internet is disconnect, Wait for connection...", true, true);
if (!NetworkConnected(&Cayenne->_network) || !CayenneMQTTConnected(&Cayenne->_mqttClient))
{
CayenneMQTTDisconnect(&Cayenne->_mqttClient);
NetworkDisconnect(&Cayenne->_network);
}
delete(Cayenne);
Cayenne = NULL;
FunctionStepCAYENNE_MOD = fscIDLE;
return 0;
}
case fscConnected:
{
DEF_WAITMS_VAR(ccl);
BEGIN_WAITMS(ccl,100)
{
if (NetworkConnected(&Cayenne->_network) && CayenneMQTTConnected(&Cayenne->_mqttClient))
{
MQTTYield(&Cayenne->_mqttClient.mqttClient, 10);
TCayenneFrameItem *CayenneFrameItem = CayenneFrameItemList;
if (CayenneFrameItem != NULL)
{
switch (CayenneFrameItem->CayenneFrameTransport.type)
{
case ctfSetChannel:
{
uint8_t Channel = CayenneFrameItem->CayenneFrameTransport.Data.SetChannel.Channel;
if ((Channel == 255) || (Channel >= CAYENNE_CHANNELS_USE))
{
Channel = XB_CAYENNE_MOD_GetChannelByIDROM(CayenneFrameItem->CayenneFrameTransport.Data.SetChannel.idrom);
if (Channel == 255)
{
Channel = XB_CAYENNE_MOD_GetFreeChannel();
if (Channel == 255)
{
XB_CAYENNE_MOD_DELETE_TCayenneFrameItem(CayenneFrameItem);
break;
}
ChannelAsIDROM[Channel].ROM = CayenneFrameItem->CayenneFrameTransport.Data.SetChannel.idrom.ROM;
}
}
else
{
ChannelAsIDROM[Channel].ROM = CayenneFrameItem->CayenneFrameTransport.Data.SetChannel.idrom.ROM;
}
switch (CayenneFrameItem->CayenneFrameTransport.Data.SetChannel.SensorValue.Type)
{
case svtTemperature:
{
if (Cayenne == NULL) XB_CAYENNE_MOD_SetupServer();
Cayenne->celsiusWrite(Channel, CayenneFrameItem->CayenneFrameTransport.Data.SetChannel.SensorValue.Data.Temperature);
break;
}
default:
{
if (XB_CAYENNE_MOD_DEBUG) board.Log("Frame, type value not support!", true, true);
break;
}
}
XB_CAYENNE_MOD_DELETE_TCayenneFrameItem(CayenneFrameItem);
break;
}
default:
{
if (XB_CAYENNE_MOD_DEBUG) board.Log("Type frame transport is not support!", true, true);
break;
}
}
}
}
else
{
DEF_WAITMS_VAR(cpc);
BEGIN_WAITMS(cpc, 5000);
{
if (XB_CAYENNE_MOD_DEBUG) board.Log("Client problem connection.!", true, true);
if (XB_CAYENNE_MOD_DEBUG) board.Log("Reconnect.", true, true);
CayenneMQTTDisconnect(&Cayenne->_mqttClient);
if (XB_CAYENNE_MOD_DEBUG) board.Log(".");
NetworkDisconnect(&Cayenne->_network);
if (XB_CAYENNE_MOD_DEBUG) board.Log(".");
Cayenne->connect();
if (XB_CAYENNE_MOD_DEBUG) board.Log(".OK");
}
END_WAITMS(cpc);
}
}
END_WAITMS(ccl);
break;
}
default: FunctionStepCAYENNE_MOD = fscIDLE;
}
return 0;
}
bool XB_CAYENNE_MOD_DoMessage(TMessageBoard *Am)
{
switch (Am->IDMessage)
{
case IM_FRAME_RECEIVE:
{
TCayenneFrameTransport *src_cft = (TCayenneFrameTransport *)Am->Data.FrameReceiveData.DataFrame;
TCayenneFrameItem *cfi = XB_CAYENNE_MOD_NEW_TCayenneFrameItem();
xb_memorycopy(src_cft, &cfi->CayenneFrameTransport, sizeof(TCayenneFrameTransport));
return true;
}
case IM_INTERNET_CONNECT:
{
if (FunctionStepCAYENNE_MOD == fscIDLE)
{
FunctionStepCAYENNE_MOD = fscInit;
}
return true;
}
case IM_INTERNET_DISCONNECT:
{
if ((FunctionStepCAYENNE_MOD == fscConnected ) || (FunctionStepCAYENNE_MOD == fscInit))
{
FunctionStepCAYENNE_MOD = fscDeInit;
}
return true;
}
case IM_GET_TASKNAME_STRING:
{
*(Am->Data.PointerString) = FSS("CAYENNE_MOD");
return true;
}
case IM_GET_TASKSTATUS_STRING:
{
switch (FunctionStepCAYENNE_MOD)
{
case fscIDLE: *(Am->Data.PointerString) = "IDLE "; break;
case fscLoadConfig: *(Am->Data.PointerString) = "LoadConfig "; break;
case fscInit: *(Am->Data.PointerString) = "Init "; break;
case fscConnected: *(Am->Data.PointerString) = "Connected "; break;
default: *(Am->Data.PointerString) = "??? "; break;
}
*(Am->Data.PointerString) += "(FC:" + String(CayenneFrameItemList_Count) + ") ";
return true;
}
case IM_MENU:
{
TGADGETMenu *menuhandle=NULL;
switch (Am->Data.MenuData.TypeMenuAction)
{
case tmaOPEN_MAINMENU:
{
menuhandle = GUIGADGET_CreateMenu(&XB_CAYENNE_MOD_DefTask, 1);
break;
}
case tmaGET_INIT_MENU:
{
Am->Data.MenuData.ActionData.MenuInitData.ItemCount = 4;
Am->Data.MenuData.ActionData.MenuInitData.Width = 32;
Am->Data.MenuData.ActionData.MenuInitData.CurrentSelect = 0;
break;
}
case tmaGET_ITEM_MENU_STRING:
{
(XB_CAYENNE_MOD_DEBUG == true ? "*" : " ");
switch (Am->Data.MenuData.ActionData.MenuItemData.ItemIndex)
{
DEF_MENUITEMNAME(0, "Load configuration");
DEF_MENUITEMNAME(1, "Save configuration");
DEF_MENUITEMNAME(2, "Clear Channel as IDROM");
case 3: *Am->Data.MenuData.ActionData.MenuItemData.PointerString = "Debug info [" + String(XB_CAYENNE_MOD_DEBUG == true ? "*" : " ") + "]"; break;
default:
break;
}
break;
}
case tmaCLICK_ITEM_MENU:
{
switch (Am->Data.MenuData.ActionData.MenuClickData.ItemIndex)
{
case 0:
{
XB_CAYENNE_MOD_LoadConfig();
break;
}
case 1:
{
XB_CAYENNE_MOD_SaveConfig();
break;
}
case 2:
{
XB_CAYENNE_MOD_ClearChannelAsIDROM();
break;
}
case 3:
{
XB_CAYENNE_MOD_DEBUG = !XB_CAYENNE_MOD_DEBUG;
break;
}
default: break;
}
}
default: break;
}
return true;
}
default: break;
}
return false;
}