#include "xb_CAYENNE_MOD.h" #include #include #include #include #include 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; }