diff --git a/drivers.xml b/drivers.xml index 3c7711a63d..1715888dfa 100644 --- a/drivers.xml +++ b/drivers.xml @@ -785,6 +785,10 @@ indi_dragon_light 1.0 + + indi_terrans_powerboxpro_v2 + 1.0 + diff --git a/drivers/auxiliary/CMakeLists.txt b/drivers/auxiliary/CMakeLists.txt index 20b5e07030..3f2281f38c 100644 --- a/drivers/auxiliary/CMakeLists.txt +++ b/drivers/auxiliary/CMakeLists.txt @@ -1,6 +1,14 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") INSTALL(FILES 99-indi_auxiliary.rules DESTINATION ${UDEVRULES_INSTALL_DIR}) ENDIF() +# ########## Terrans PowerBoxPro V2 ############### +SET(terranspowerboxprov2_SRC + Terrans_PowerBoxPro_V2.cpp) + +add_executable(indi_terrans_powerboxpro_v2 ${terranspowerboxprov2_SRC}) +target_link_libraries(indi_terrans_powerboxpro_v2 indidriver) +install(TARGETS indi_terrans_powerboxpro_v2 RUNTIME DESTINATION bin) + # ########## WandererCover V4-EC############### SET(indi_wanderercover_v4_ec_SRC wanderer_cover_v4_ec.cpp) diff --git a/drivers/auxiliary/Terrans_PowerBoxPro_V2.cpp b/drivers/auxiliary/Terrans_PowerBoxPro_V2.cpp new file mode 100644 index 0000000000..7051eb844d --- /dev/null +++ b/drivers/auxiliary/Terrans_PowerBoxPro_V2.cpp @@ -0,0 +1,1905 @@ +/******************************************************************************* + Copyright(c) 2015 Jasem Mutlaq. All rights reserved. + + TerransPowerBoxProV2 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. +*******************************************************************************/ + +#include "config.h" +#include "Terrans_PowerBoxPro_V2.h" + +#include "indicom.h" +#include "connectionplugins/connectionserial.h" + +#include +#include +#include +#include +#include +#include +#include + +// We declare an auto pointer to TerransPowerBoxProV2. +static std::unique_ptr terranspowerboxprov2(new TerransPowerBoxProV2()); + +#define CMD_LEN 8 +#define TIMEOUT 500 +#define TAB_INFO "Status" +#define TAB_RENAME "Rename" + +int get_count=0; +int init=0; +double ch1_shuntv = 0; +double ch2_shuntv = 0; +double ch3_shuntv = 0; +double ch1_current = 0; +double ch2_current = 0; +double ch3_current = 0; +double ch1_bus = 0; +double ch2_bus = 0; +double ch3_bus = 0; +double ch1_w = 0; +double ch2_w = 0; +double ch3_w = 0; +double chusb_w = 0; +double humidity = 0; +double temperature = 0; +double dewPoint=0; +double mcu_temp = 0; + + +TerransPowerBoxProV2::TerransPowerBoxProV2() : WI(this) +{ + setVersion(1, 0); +} + +bool TerransPowerBoxProV2::initProperties() +{ + INDI::DefaultDevice::initProperties(); + + setDriverInterface(AUX_INTERFACE | WEATHER_INTERFACE); + + WI::initProperties(ENVIRONMENT_TAB, ENVIRONMENT_TAB); + + addAuxControls(); + + //////////////////////////////////////////////////////////////////////////// + /// Name + //////////////////////////////////////////////////////////////////////////// + char DCANAME[MAXINDINAME] = "DC OUT A"; + char DCBNAME[MAXINDINAME] = "DC OUT B"; + char DCCNAME[MAXINDINAME] = "DC OUT C"; + char DCDNAME[MAXINDINAME] = "DC OUT D"; + char DCENAME[MAXINDINAME] = "DC OUT E"; + char DCFNAME[MAXINDINAME] = "DC OUT F"; + char DC19VNAME[MAXINDINAME] = "DC OUT 19V"; + char USBANAME[MAXINDINAME] = "USB3.0 A"; + char USBBNAME[MAXINDINAME] = "USB3.0 B"; + char USBCNAME[MAXINDINAME] = "USB3.0 C"; + char USBDNAME[MAXINDINAME] = "USB3.0 D"; + char USBENAME[MAXINDINAME] = "USB2.0 E"; + char USBFNAME[MAXINDINAME] = "USB2.0 F"; + char DCADJNAME[MAXINDINAME] = "DC ADJ"; + + IUGetConfigText(getDeviceName(), "RENAME", "DC_A_NAME", DCANAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "DC_B_NAME", DCBNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "DC_C_NAME", DCCNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "DC_D_NAME", DCDNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "DC_E_NAME", DCENAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "DC_F_NAME", DCFNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "DC_19V_NAME", DC19VNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "USB_A_NAME", USBANAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "USB_B_NAME", USBBNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "USB_C_NAME", USBCNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "USB_D_NAME", USBDNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "USB_E_NAME", USBENAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "USB_F_NAME", USBFNAME, MAXINDINAME); + IUGetConfigText(getDeviceName(), "RENAME", "DC_ADJ_NAME", DCADJNAME, MAXINDINAME); + + IUFillText(&RenameT[0], "DC_A_NAME", "DC A NAME", DCANAME); + IUFillText(&RenameT[1], "DC_B_NAME", "DC B NAME", DCBNAME); + IUFillText(&RenameT[2], "DC_C_NAME", "DC CNAME", DCCNAME); + IUFillText(&RenameT[3], "DC_D_NAME", "DC D NAME", DCDNAME); + IUFillText(&RenameT[4], "DC_E_NAME", "DC E NAME", DCENAME); + IUFillText(&RenameT[5], "DC_F_NAME", "DC F NAME", DCFNAME); + IUFillText(&RenameT[6], "DC_19V_NAME", "DC 19V NAME", DC19VNAME); + IUFillText(&RenameT[7], "USB_A_NAME", "USB A NAME", USBANAME); + IUFillText(&RenameT[8], "USB_B_NAME", "USB B NAME", USBBNAME); + IUFillText(&RenameT[9], "USB_C_NAME", "USB C NAME", USBCNAME); + IUFillText(&RenameT[10], "USB_D_NAME", "USB D NAME", USBDNAME); + IUFillText(&RenameT[11], "USB_E_NAME", "USB E NAME", USBENAME); + IUFillText(&RenameT[12], "USB_F_NAME", "USB F NAME", USBFNAME); + IUFillText(&RenameT[13], "DC_ADJ_NAME", "DC ADJ NAME", DCADJNAME); + + IUFillTextVector(&RenameTP, RenameT, 14, getDeviceName(), "RENAME", "Rename", + ADD_SETTING_TAB, IP_RW, 60, IPS_IDLE); + + ConfigRenameDCA = RenameT[0].text; + ConfigRenameDCB = RenameT[1].text; + ConfigRenameDCC = RenameT[2].text; + ConfigRenameDCD = RenameT[3].text; + ConfigRenameDCE = RenameT[4].text; + ConfigRenameDCF = RenameT[5].text; + ConfigRenameDC19V = RenameT[6].text; + ConfigRenameUSBA = RenameT[7].text; + ConfigRenameUSBB = RenameT[8].text; + ConfigRenameUSBC = RenameT[9].text; + ConfigRenameUSBD = RenameT[10].text; + ConfigRenameUSBE = RenameT[11].text; + ConfigRenameUSBF = RenameT[12].text; + ConfigRenameADJ = RenameT[13].text; + + //////////////////////////////////////////////////////////////////////////// + /// Power Group + //////////////////////////////////////////////////////////////////////////// + IUFillSwitch(&DCAS[0], "DC OUT A ON", "ON", ISS_OFF); + IUFillSwitch(&DCBS[0], "DC OUT B ON", "ON", ISS_OFF); + IUFillSwitch(&DCCS[0], "DC OUT C ON", "ON", ISS_OFF); + IUFillSwitch(&DCDS[0], "DC OUT D ON", "ON", ISS_OFF); + IUFillSwitch(&DCES[0], "DC OUT E ON", "ON", ISS_OFF); + IUFillSwitch(&DCFS[0], "DC OUT F ON", "ON", ISS_OFF); + IUFillSwitch(&DC19VS[0], "DC OUT 19V ON", "ON", ISS_OFF); + + IUFillSwitch(&DCAS[1], "DC OUT A OFF", "OFF", ISS_OFF); + IUFillSwitch(&DCBS[1], "DC OUT B OFF", "OFF", ISS_OFF); + IUFillSwitch(&DCCS[1], "DC OUT C OFF", "OFF", ISS_OFF); + IUFillSwitch(&DCDS[1], "DC OUT D OFF", "OFF", ISS_OFF); + IUFillSwitch(&DCES[1], "DC OUT E OFF", "OFF", ISS_OFF); + IUFillSwitch(&DCFS[1], "DC OUT F OFF", "OFF", ISS_OFF); + IUFillSwitch(&DC19VS[1], "DC OUT 19V OFF", "OFF", ISS_OFF); + + IUFillSwitch(&USBAS[0], "USB3.0 A ON", "ON", ISS_OFF); + IUFillSwitch(&USBBS[0], "USB3.0 B ON", "ON", ISS_OFF); + IUFillSwitch(&USBCS[0], "USB3.0 C ON", "ON", ISS_OFF); + IUFillSwitch(&USBDS[0], "USB3.0 D ON", "ON", ISS_OFF); + IUFillSwitch(&USBES[0], "USB2.0 E ON", "ON", ISS_OFF); + IUFillSwitch(&USBFS[0], "USB2.0 F ON", "ON", ISS_OFF); + + IUFillSwitch(&USBAS[1], "USB3.0 A OFF", "OFF", ISS_OFF); + IUFillSwitch(&USBBS[1], "USB3.0 B OFF", "OFF", ISS_OFF); + IUFillSwitch(&USBCS[1], "USB3.0 C OFF", "OFF", ISS_OFF); + IUFillSwitch(&USBDS[1], "USB3.0 D OFF", "OFF", ISS_OFF); + IUFillSwitch(&USBES[1], "USB2.0 E OFF", "OFF", ISS_OFF); + IUFillSwitch(&USBFS[1], "USB2.0 F OFF", "OFF", ISS_OFF); + + + IUFillSwitch(&DCADJS[0], "DC OUT ADJ OFF", "OFF", ISS_OFF); + IUFillSwitch(&DCADJS[1], "DC OUT ADJ 5V", "5V", ISS_OFF); + IUFillSwitch(&DCADJS[2], "DC OUT ADJ 9V", "9V", ISS_OFF); + IUFillSwitch(&DCADJS[3], "DC OUT ADJ 12V", "12V", ISS_OFF); + + IUFillSwitch(&StateSaveS[0], "Save ON", "ON", ISS_OFF); + IUFillSwitch(&StateSaveS[1], "Save OFF", "OFF", ISS_OFF); + + IUFillSwitchVector(&DCASP, DCAS, 2, getDeviceName(), "DC_OUT_A", ConfigRenameDCA, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&DCBSP, DCBS, 2, getDeviceName(), "DC_OUT_B", ConfigRenameDCB, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&DCCSP, DCCS, 2, getDeviceName(), "DC_OUT_C", ConfigRenameDCC, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&DCDSP, DCDS, 2, getDeviceName(), "DC_OUT_D", ConfigRenameDCD, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&DCESP, DCES, 2, getDeviceName(), "DC_OUT_E", ConfigRenameDCE, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&DCFSP, DCFS, 2, getDeviceName(), "DC_OUT_F", ConfigRenameDCF, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&DC19VSP, DC19VS, 2, getDeviceName(), "DC_19V", ConfigRenameDC19V, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&DCADJSP, DCADJS, 4, getDeviceName(), "DC_ADJ", ConfigRenameADJ, MAIN_CONTROL_TAB, + IP_RW, ISR_1OFMANY, 60, IPS_IDLE); + + IUFillSwitchVector(&USBASP, USBAS, 2, getDeviceName(), "USB3.0_A", ConfigRenameUSBA, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&USBBSP, USBBS, 2, getDeviceName(), "USB3.0_B", ConfigRenameUSBB, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&USBCSP, USBCS, 2, getDeviceName(), "USB3.0_C", ConfigRenameUSBC, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&USBDSP, USBDS, 2, getDeviceName(), "USB3.0_D", ConfigRenameUSBD, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&USBESP, USBES, 2, getDeviceName(), "USB2.0_E", ConfigRenameUSBE, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + IUFillSwitchVector(&USBFSP, USBFS, 2, getDeviceName(), "USB2.0_F", ConfigRenameUSBF, MAIN_CONTROL_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + + IUFillSwitchVector(&StateSaveSP, StateSaveS, 2, getDeviceName(), "State_Save", "State memory", ADD_SETTING_TAB, + IP_RW, ISR_ATMOST1, 60, IPS_IDLE); + + //////////////////////////////////////////////////////////////////////////// + /// Auto Heater + //////////////////////////////////////////////////////////////////////////// + IUFillSwitch(&AutoHeater12VS[0], "HEATER_DCA", "DC A", ISS_OFF); + IUFillSwitch(&AutoHeater12VS[1], "HEATER_DCB", "DC B", ISS_OFF); + IUFillSwitch(&AutoHeater12VS[2], "HEATER_DCC", "DC C", ISS_OFF); + IUFillSwitch(&AutoHeater12VS[3], "HEATER_DCD", "DC D", ISS_OFF); + IUFillSwitch(&AutoHeater12VS[4], "HEATER_DCE", "DC E", ISS_OFF); + IUFillSwitch(&AutoHeater12VS[5], "HEATER_DCF", "DC F", ISS_OFF); + + IUFillSwitch(&AutoHeater5VS[0], "HEATER_USBA", "USB A", ISS_OFF); + IUFillSwitch(&AutoHeater5VS[1], "HEATER_USBB", "USB B", ISS_OFF); + IUFillSwitch(&AutoHeater5VS[2], "HEATER_USBC", "USB C", ISS_OFF); + IUFillSwitch(&AutoHeater5VS[3], "HEATER_USBD", "USB D", ISS_OFF); + IUFillSwitch(&AutoHeater5VS[4], "HEATER_USBE", "USB E", ISS_OFF); + IUFillSwitch(&AutoHeater5VS[5], "HEATER_USBF", "USB F", ISS_OFF); + + IUFillSwitchVector(&AutoHeater12VSP, AutoHeater12VS, 6, getDeviceName(), "12V_Auto_Heater", "12V Auto Heater", ADD_SETTING_TAB, + IP_RW, ISR_NOFMANY, 60, IPS_IDLE); + IUFillSwitchVector(&AutoHeater5VSP, AutoHeater5VS, 6, getDeviceName(), "5V_Auto_Heater", "5V Auto Heater", ADD_SETTING_TAB, + IP_RW, ISR_NOFMANY, 60, IPS_IDLE); + + //////////////////////////////////////////////////////////////////////////// + /// Sensor Data + //////////////////////////////////////////////////////////////////////////// + addParameter("WEATHER_TEMPERATURE", "Temperature (C)", -15, 35, 15); + addParameter("WEATHER_HUMIDITY", "Humidity %", 0, 100, 15); + addParameter("WEATHER_DEWPOINT", "Dew Point (C)", 0, 100, 15); + + IUFillNumber(&InputVotageN[0], "Input_Votage", "InputVotage (V)", "%.2f", 0, 20, 0.01, 0); + IUFillNumber(&InputCurrentN[0], "Input_Current", "InputCurrent (V)", "%.2f", 0, 30, 0.01, 0); + + IUFillNumber(&PowerN[0], "Total_Power", "Total Power (W)", "%.2f", 0, 100, 10, 0); + IUFillNumber(&PowerN[1], "12V_Power", "12V Power (W)", "%.2f", 0, 200, 0.01, 0); + IUFillNumber(&PowerN[2], "19V_Power", "19V Power (W)", "%.2f", 0, 200, 0.01, 0); + IUFillNumber(&PowerN[3], "USB_Power", "USB Power (W)", "%.2f", 0, 200, 0.01, 0); + + IUFillNumber(&MCUTempN[0], "MCU_Temp", "MCU Temperature (C)", "%.2f", 0, 200, 0.01, 0); + + IUFillNumberVector(&InputVotageNP, InputVotageN, 1, getDeviceName(), "Input_Votage", "InputVotage", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE); + IUFillNumberVector(&InputCurrentNP, InputCurrentN, 1, getDeviceName(), "Input_Current", "InputCurrent", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE); + IUFillNumberVector(&PowerNP, PowerN, 4, getDeviceName(), "Power_Sensor", "Power", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE); + IUFillNumberVector(&MCUTempNP, MCUTempN, 1, getDeviceName(), "MCU_Temp", "MCU", MAIN_CONTROL_TAB, IP_RO, 60, IPS_IDLE); + + //////////////////////////////////////////////////////////////////////////// + /// Serial Connection + //////////////////////////////////////////////////////////////////////////// + serialConnection = new Connection::Serial(this); + serialConnection->registerHandshake([&](){return Handshake();}); + serialConnection->setDefaultBaudRate(Connection::Serial::B_9600); + registerConnection(serialConnection); + + return true; +} + +bool TerransPowerBoxProV2::updateProperties() +{ + INDI::DefaultDevice::updateProperties(); + + if (isConnected()) + { + // Main Control + defineProperty(&InputVotageNP); + defineProperty(&InputCurrentNP); + defineProperty(&PowerNP); + defineProperty(&MCUTempNP); + + defineProperty(&DCASP); + defineProperty(&DCBSP); + defineProperty(&DCCSP); + defineProperty(&DCDSP); + defineProperty(&DCESP); + defineProperty(&DCFSP); + defineProperty(&DC19VSP); + + defineProperty(&USBASP); + defineProperty(&USBBSP); + defineProperty(&USBCSP); + defineProperty(&USBDSP); + defineProperty(&USBESP); + defineProperty(&USBFSP); + + defineProperty(&DCADJSP); + + WI::updateProperties(); + + defineProperty(&AutoHeater12VSP); + defineProperty(&AutoHeater5VSP); + defineProperty(&StateSaveSP); + defineProperty(&RenameTP); + + setupComplete = true; + } + else + { + // Main Control + deleteProperty(InputVotageNP.name); + deleteProperty(InputCurrentNP.name); + deleteProperty(PowerNP.name); + deleteProperty(MCUTempNP.name); + + deleteProperty(DCASP.name); + deleteProperty(DCBSP.name); + deleteProperty(DCCSP.name); + deleteProperty(DCDSP.name); + deleteProperty(DCESP.name); + deleteProperty(DCFSP.name); + deleteProperty(DC19VSP.name); + + deleteProperty(USBASP.name); + deleteProperty(USBBSP.name); + deleteProperty(USBCSP.name); + deleteProperty(USBDSP.name); + deleteProperty(USBESP.name); + deleteProperty(USBFSP.name); + + deleteProperty(DCADJSP.name); + + WI::updateProperties(); + + deleteProperty(AutoHeater12VSP.name); + deleteProperty(AutoHeater5VSP.name); + deleteProperty(StateSaveSP.name); + deleteProperty(RenameTP.name); + + setupComplete = false; + } + + return true; +} + +bool TerransPowerBoxProV2::saveConfigItems(FILE *fp) +{ + INDI::DefaultDevice::saveConfigItems(fp); + IUSaveConfigText(fp, &RenameTP); + return true; +} + +bool TerransPowerBoxProV2::Handshake() +{ + char res[CMD_LEN] = {0}; + if (isSimulation()) + { + LOGF_INFO("Connected successfuly to simulated %s.", getDeviceName()); + return true; + } + + for(int HS = 0 ; HS < 3 ; HS++) + { + if (sendCommand(">VR#",res)) + { + if(!strcmp(res, "*TPPNNN")) + { + if (sendCommand(">VN#",res)) + { + if(!strcmp(res, "*V001")) + { + LOG_INFO("Handshake successfully!"); + return true; + }else + { + LOG_INFO("The firmware version does not match the driver. Please use the latest firmware and driver!"); + return false; + } + } + }else + { + LOG_INFO("Handshake failed!"); + LOG_INFO("Retry..."); + } + } + } + LOG_INFO("Handshake failed!"); + return false; +} + + +const char *TerransPowerBoxProV2::getDefaultName() +{ + LOG_INFO("GET Name"); + return "TerransPowerBoxProV2"; +} + +bool TerransPowerBoxProV2::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) +{ + if (dev != nullptr && strcmp(dev, getDeviceName()) == 0) + { + if (processButtonSwitch(dev, name, states, names, n)) + return true; + } + return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n); +} + +bool TerransPowerBoxProV2::ISNewText(const char * dev, const char * name, char * texts[], char * names[], int n) +{ + if (dev && !strcmp(dev, getDeviceName())) + { + // Power Labels + if (!strcmp(name, RenameTP.name)) + { + IUUpdateText(&RenameTP, texts, names, n); + RenameTP.s = IPS_OK; + IDSetText(&RenameTP, nullptr); + saveConfig(true, RenameTP.label); + if(init){LOG_INFO("Renaming successful, please restart Ekos to make the name effective!");} + return true; + } + } + return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n); +} + +bool TerransPowerBoxProV2::sendCommand(const char * cmd, char * res) +{ + + int nbytes_read = 0, nbytes_written = 0, tty_rc = 0; + char command[CMD_LEN] = {0}; + PortFD = serialConnection->getPortFD(); + LOGF_DEBUG("CMD <%s>", cmd); + + for (int i = 0; i < 2; i++) + { + tcflush(PortFD, TCIOFLUSH); + snprintf(command, CMD_LEN, "%s", cmd); + if ( (tty_rc = tty_write_string(PortFD, command, &nbytes_written)) != TTY_OK) + continue; + + if (!res) + { + tcflush(PortFD, TCIOFLUSH); + return true; + } + + if ( (tty_rc = tty_nread_section(PortFD, res, CMD_LEN, '#', TIMEOUT, &nbytes_read)) != TTY_OK || nbytes_read == 1) + continue; + + tcflush(PortFD, TCIOFLUSH); + res[nbytes_read - 1] = '\0'; + LOGF_DEBUG("RES <%s>", res); + return true; + } + + if (tty_rc != TTY_OK) + { + char errorMessage[MAXRBUF]; + tty_error_msg(tty_rc, errorMessage, MAXRBUF); + LOGF_ERROR("Serial error: %s", errorMessage); + } + + return false; +} + +void TerransPowerBoxProV2::TimerHit() +{ + if (!isConnected() || setupComplete == false) + { + SetTimer(100); + return; + } + + Get_State(); + SetTimer(100); +} + +void TerransPowerBoxProV2::Get_State() +{ + char res[CMD_LEN] = {0}; + if(get_count == 0) + { + if (sendCommand(">GDA#",res)) + { + if(!strcmp(res, "*DA1NNN")) + { + DCASP.s = IPS_OK; + DCAS[0].s = ISS_ON; + DCAS[1].s = ISS_OFF; + }else if(!strcmp(res, "*DA0NNN")) + { + DCASP.s = IPS_ALERT; + DCAS[0].s = ISS_OFF; + DCAS[1].s = ISS_ON; + }else + { + DCASP.s = IPS_BUSY; + DCAS[0].s = ISS_OFF; + DCAS[1].s = ISS_OFF; + } + } + IDSetSwitch(&DCASP, nullptr); + get_count++; + }else if(get_count == 1) + { + if (sendCommand(">GDB#",res)) + { + if(!strcmp(res, "*DB1NNN")) + { + DCBSP.s = IPS_OK; + DCBS[0].s = ISS_ON; + DCBS[1].s = ISS_OFF; + }else if(!strcmp(res, "*DB0NNN")) + { + DCBSP.s = IPS_ALERT; + DCBS[0].s = ISS_OFF; + DCBS[1].s = ISS_ON; + }else + { + DCBSP.s = IPS_BUSY; + DCBS[0].s = ISS_OFF; + DCBS[1].s = ISS_OFF; + } + } + IDSetSwitch(&DCBSP, nullptr); + get_count++; + }else if(get_count == 2) + { + if (sendCommand(">GDC#",res)) + { + if(!strcmp(res, "*DC1NNN")) + { + DCCSP.s = IPS_OK; + DCCS[0].s = ISS_ON; + DCCS[1].s = ISS_OFF; + }else if(!strcmp(res, "*DC0NNN")) + { + DCCSP.s = IPS_ALERT; + DCCS[0].s = ISS_OFF; + DCCS[1].s = ISS_ON; + }else + { + DCCSP.s = IPS_BUSY; + DCCS[0].s = ISS_OFF; + DCCS[1].s = ISS_OFF; + } + } + IDSetSwitch(&DCCSP, nullptr); + get_count++; + }else if(get_count == 3) + { + if (sendCommand(">GDD#",res)) + { + if(!strcmp(res, "*DD1NNN")) + { + DCDSP.s = IPS_OK; + DCDS[0].s = ISS_ON; + DCDS[1].s = ISS_OFF; + }else if(!strcmp(res, "*DD0NNN")) + { + DCDSP.s = IPS_ALERT; + DCDS[0].s = ISS_OFF; + DCDS[1].s = ISS_ON; + }else + { + DCDSP.s = IPS_BUSY; + DCDS[0].s = ISS_OFF; + DCDS[1].s = ISS_OFF; + } + } + IDSetSwitch(&DCDSP, nullptr); + get_count++; + }else if(get_count == 4) + { + if (sendCommand(">GDE#",res)) + { + if(!strcmp(res, "*DE1NNN")) + { + DCESP.s = IPS_OK; + DCES[0].s = ISS_ON; + DCES[1].s = ISS_OFF; + }else if(!strcmp(res, "*DE0NNN")) + { + DCESP.s = IPS_ALERT; + DCES[0].s = ISS_OFF; + DCES[1].s = ISS_ON; + }else + { + DCESP.s = IPS_BUSY; + DCES[0].s = ISS_OFF; + DCES[1].s = ISS_OFF; + } + } + IDSetSwitch(&DCESP, nullptr); + get_count++; + }else if(get_count == 5) + { + if (sendCommand(">GDF#",res)) + { + if(!strcmp(res, "*DF1NNN")) + { + DCFSP.s = IPS_OK; + DCFS[0].s = ISS_ON; + DCFS[1].s = ISS_OFF; + }else if(!strcmp(res, "*DF0NNN")) + { + DCFSP.s = IPS_ALERT; + DCFS[0].s = ISS_OFF; + DCFS[1].s = ISS_ON; + }else + { + DCFSP.s = IPS_BUSY; + DCFS[0].s = ISS_OFF; + DCFS[1].s = ISS_OFF; + } + } + IDSetSwitch(&DCFSP, nullptr); + get_count++; + }else if(get_count == 6) + { + if (sendCommand(">GDG#",res)) + { + if(!strcmp(res, "*DG1NNN")) + { + DC19VSP.s = IPS_OK; + DC19VS[0].s = ISS_ON; + DC19VS[1].s = ISS_OFF; + }else if(!strcmp(res, "*DG0NNN")) + { + DC19VSP.s = IPS_ALERT; + DC19VS[0].s = ISS_OFF; + DC19VS[1].s = ISS_ON; + }else + { + DC19VSP.s = IPS_BUSY; + DC19VS[0].s = ISS_OFF; + DC19VS[1].s = ISS_OFF; + } + } + IDSetSwitch(&DC19VSP, nullptr); + get_count++; + }else if(get_count == 7) + { + if (sendCommand(">GUA#",res)) + { + if(!strcmp(res, "*UA111N")) + { + USBASP.s = IPS_OK; + USBAS[0].s = ISS_ON; + USBAS[1].s = ISS_OFF; + }else if(!strcmp(res, "*UA000N")) + { + USBASP.s = IPS_ALERT; + USBAS[0].s = ISS_OFF; + USBAS[1].s = ISS_ON; + }else + { + USBASP.s = IPS_BUSY; + USBAS[0].s = ISS_OFF; + USBAS[1].s = ISS_OFF; + } + } + IDSetSwitch(&USBASP, nullptr); + get_count++; + }else if(get_count == 8) + { + if (sendCommand(">GUB#",res)) + { + if(!strcmp(res, "*UB111N")) + { + USBBSP.s = IPS_OK; + USBBS[0].s = ISS_ON; + USBBS[1].s = ISS_OFF; + }else if(!strcmp(res, "*UB000N")) + { + USBBSP.s = IPS_ALERT; + USBBS[0].s = ISS_OFF; + USBBS[1].s = ISS_ON; + }else + { + USBBSP.s = IPS_BUSY; + USBBS[0].s = ISS_OFF; + USBBS[1].s = ISS_OFF; + } + } + IDSetSwitch(&USBBSP, nullptr); + get_count++; + }else if(get_count == 9) + { + if (sendCommand(">GUC#",res)) + { + if(!strcmp(res, "*UC111N")) + { + USBCSP.s = IPS_OK; + USBCS[0].s = ISS_ON; + USBCS[1].s = ISS_OFF; + }else if(!strcmp(res, "*UC000N")) + { + USBCSP.s = IPS_ALERT; + USBCS[0].s = ISS_OFF; + USBCS[1].s = ISS_ON; + }else + { + USBCSP.s = IPS_BUSY; + USBCS[0].s = ISS_OFF; + USBCS[1].s = ISS_OFF; + } + } + IDSetSwitch(&USBCSP, nullptr); + get_count++; + }else if(get_count == 10) + { + if (sendCommand(">GUD#",res)) + { + if(!strcmp(res, "*UD111N")) + { + USBDSP.s = IPS_OK; + USBDS[0].s = ISS_ON; + USBDS[1].s = ISS_OFF; + }else if(!strcmp(res, "*UD000N")) + { + USBDSP.s = IPS_ALERT; + USBDS[0].s = ISS_OFF; + USBDS[1].s = ISS_ON; + }else + { + USBDSP.s = IPS_BUSY; + USBDS[0].s = ISS_OFF; + USBDS[1].s = ISS_OFF; + } + } + IDSetSwitch(&USBDSP, nullptr); + get_count++; + }else if(get_count == 11) + { + if (sendCommand(">GUE#",res)) + { + if(!strcmp(res, "*UE11NN")) + { + USBESP.s = IPS_OK; + USBES[0].s = ISS_ON; + USBES[1].s = ISS_OFF; + }else if(!strcmp(res, "*UE00NN")) + { + USBESP.s = IPS_ALERT; + USBES[0].s = ISS_OFF; + USBES[1].s = ISS_ON; + }else + { + USBESP.s = IPS_BUSY; + USBES[0].s = ISS_OFF; + USBES[1].s = ISS_OFF; + } + } + IDSetSwitch(&USBESP, nullptr); + get_count++; + }else if(get_count == 12) + { + if (sendCommand(">GUF#",res)) + { + if(!strcmp(res, "*UF11NN")) + { + USBFSP.s = IPS_OK; + USBFS[0].s = ISS_ON; + USBFS[1].s = ISS_OFF; + }else if(!strcmp(res, "*UF00NN")) + { + USBFSP.s = IPS_ALERT; + USBFS[0].s = ISS_OFF; + USBFS[1].s = ISS_ON; + }else + { + USBFSP.s = IPS_BUSY; + USBFS[0].s = ISS_OFF; + USBFS[1].s = ISS_OFF; + } + } + IDSetSwitch(&USBFSP, nullptr); + get_count++; + }else if(get_count == 13) + { + if (sendCommand(">GS#",res)) + { + if(!strcmp(res, "*SS1NNN")) + { + StateSaveSP.s = IPS_OK; + StateSaveS[0].s = ISS_ON; + StateSaveS[1].s = ISS_OFF; + }else if(!strcmp(res, "*SS0NNN")) + { + StateSaveSP.s = IPS_ALERT; + StateSaveS[0].s = ISS_OFF; + StateSaveS[1].s = ISS_ON; + }else + { + StateSaveSP.s = IPS_BUSY; + StateSaveS[0].s = ISS_OFF; + StateSaveS[1].s = ISS_OFF; + } + } + IDSetSwitch(&StateSaveSP, nullptr); + get_count++; + }else if(get_count == 14) + { + if (sendCommand(">GPF#",res)) + { + ch3_bus = (res[6]-0x30)+((res[5]-0x30)*10)+((res[4]-0x30)*100)+((res[3]-0x30)*1000); + ch3_bus = ch3_bus * 8 / 1000; + ch3_w = ch3_current * ch3_bus; + chusb_w = ch3_w - ch2_w - ch1_w; + if (chusb_w <= 0) + { + chusb_w = 0; + } + + InputVotageN[0].value = ch3_bus; + PowerN[0].value = ch3_w; + PowerN[3].value = chusb_w; + + InputVotageNP.s = IPS_OK; + } + IDSetNumber(&InputVotageNP, nullptr); + IDSetNumber(&PowerNP, nullptr); + get_count++; + }else if(get_count == 15) + { + if (sendCommand(">GPE#",res)) + { + ch3_shuntv = (res[6]-0x30)+((res[5]-0x30)*10)+((res[4]-0x30)*100)+((res[3]-0x30)*1000); + ch3_current = ch3_shuntv * 40 / 1000000 / 0.01; + ch3_w = ch3_current * ch3_bus; + chusb_w = ch3_w - ch2_w - ch1_w; + if (chusb_w <= 0) + { + chusb_w = 0; + } + + InputCurrentN[0].value = ch3_current; + PowerN[0].value = ch3_w; + PowerN[3].value = chusb_w; + + InputCurrentNP.s = IPS_OK; + } + IDSetNumber(&InputCurrentNP, nullptr); + IDSetNumber(&PowerNP, nullptr); + get_count++; + }else if(get_count == 16) + { + if (sendCommand(">GPC#",res)) + { + ch2_shuntv = (res[6]-0x30)+((res[5]-0x30)*10)+((res[4]-0x30)*100)+((res[3]-0x30)*1000); + ch2_current = ch2_shuntv * 40 / 1000000 / 0.002; + ch2_w = ch2_current * ch3_bus; + chusb_w = ch3_w - ch2_w - ch1_w; + if (chusb_w <= 0) + { + chusb_w = 0; + } + + PowerN[2].value = ch2_w; + PowerN[3].value = chusb_w; + } + IDSetNumber(&PowerNP, nullptr); + get_count++; + }else if(get_count == 17) + { + if (sendCommand(">GPA#",res)) + { + ch1_shuntv = (res[6]-0x30)+((res[5]-0x30)*10)+((res[4]-0x30)*100)+((res[3]-0x30)*1000); + ch1_current = ch1_shuntv * 40 / 1000000 / 0.002; + ch1_w = ch1_current * ch3_bus; + chusb_w = ch3_w - ch2_w - ch1_w; + if (chusb_w <= 0) + { + chusb_w = 0; + } + PowerN[1].value = ch1_w; + PowerN[3].value = chusb_w; + + PowerNP.s = IPS_OK; + } + IDSetNumber(&PowerNP, nullptr); + get_count++; + }else if(get_count == 18) + { + if (sendCommand(">GTC#",res)) + { + mcu_temp = (res[6]-0x30)+((res[5]-0x30)*10)+((res[4]-0x30)*100)+((res[3]-0x30)*1000); + if (mcu_temp == 0) + { + MCUTempN[0].value = 0; + }else + { + if (res[2] == 'A') + { + mcu_temp = mcu_temp / 100; + MCUTempN[0].value = mcu_temp; + + }else if (res[2] == 'B') + { + mcu_temp = mcu_temp / 100; + mcu_temp = mcu_temp * (-1); + MCUTempN[0].value = mcu_temp; + } + } + MCUTempNP.s = IPS_OK; + } + IDSetNumber(&MCUTempNP, nullptr); + get_count++; + }else if(get_count == 19) + { + if (sendCommand(">GTH#",res)) + { + humidity = (res[5]-0x30)+((res[4]-0x30)*10)+((res[3]-0x30)*100)+((res[2]-0x30)*1000); + if (humidity == 0) + { + setParameterValue("WEATHER_HUMIDITY", 0); + } + else + { + humidity = humidity / 100; + setParameterValue("WEATHER_HUMIDITY", humidity); + } + } + ParametersNP.apply(); + get_count++; + }else if(get_count == 20) + { + if (sendCommand(">GTT#",res)) + { + temperature = (res[6]-0x30)+((res[5]-0x30)*10)+((res[4]-0x30)*100)+((res[3]-0x30)*1000); + if (temperature == 0) + { + setParameterValue("WEATHER_TEMPERATURE", 0); + }else + { + if (res[2] == 'A') + { + temperature = temperature / 100; + setParameterValue("WEATHER_TEMPERATURE", temperature); + }else if (res[2] == 'B') + { + temperature = temperature / 100; + temperature = temperature * (-1); + setParameterValue("WEATHER_TEMPERATURE", temperature); + } + } + } + ParametersNP.apply(); + get_count++; + }else if(get_count == 21) + { + if (sendCommand(">GTD#",res)) + { + dewPoint = (res[6]-0x30)+((res[5]-0x30)*10)+((res[4]-0x30)*100)+((res[3]-0x30)*1000); + if (dewPoint == 0) + { + setParameterValue("WEATHER_DEWPOINT", 0); + }else + { + if (res[2] == 'A') + { + dewPoint = dewPoint / 100; + setParameterValue("WEATHER_DEWPOINT", dewPoint); + }else if (res[2] == 'B') + { + dewPoint = dewPoint / 100; + dewPoint = dewPoint * (-1); + setParameterValue("WEATHER_DEWPOINT", dewPoint); + } + } + ParametersNP.setState(IPS_OK); + } + ParametersNP.apply(); + get_count++; + }else if(get_count == 22) + { + if (sendCommand(">GHa#",res)) + { + if(res[1] == 'a') + { + if(res[2]-0x30 == 1){AutoHeater12VS[0].s = ISS_ON;} + else if(res[2]-0x30 == 0){AutoHeater12VS[0].s = ISS_OFF;} + + if(res[3]-0x30 == 1){AutoHeater12VS[1].s = ISS_ON;} + else if(res[3]-0x30 == 0){AutoHeater12VS[1].s = ISS_OFF;} + + if(res[4]-0x30 == 1){AutoHeater12VS[2].s = ISS_ON;} + else if(res[4]-0x30 == 0){AutoHeater12VS[2].s = ISS_OFF;} + + if(res[5]-0x30 == 1){AutoHeater12VS[3].s = ISS_ON;} + else if(res[5]-0x30 == 0){AutoHeater12VS[3].s = ISS_OFF;} + } + } else + { + + } + IDSetSwitch(&AutoHeater12VSP, nullptr); + get_count++; + }else if(get_count == 23) + { + if (sendCommand(">GHb#",res)) + { + if(res[1] == 'b') + { + if(res[2]-0x30 == 1){AutoHeater12VS[4].s = ISS_ON;} + else if(res[2]-0x30 == 0){AutoHeater12VS[4].s = ISS_OFF;} + + if(res[3]-0x30 == 1){AutoHeater12VS[5].s = ISS_ON;} + else if(res[3]-0x30 == 0){AutoHeater12VS[5].s = ISS_OFF;} + + if(res[4]-0x30 == 1){AutoHeater5VS[0].s = ISS_ON;} + else if(res[4]-0x30 == 0){AutoHeater5VS[0].s = ISS_OFF;} + + if(res[5]-0x30 == 1){AutoHeater5VS[1].s = ISS_ON;} + else if(res[5]-0x30 == 0){AutoHeater5VS[1].s = ISS_OFF;} + } + } + IDSetSwitch(&AutoHeater12VSP, nullptr); + IDSetSwitch(&AutoHeater5VSP, nullptr); + get_count++; + }else if(get_count == 24) + { + if (sendCommand(">GHc#",res)) + { + if(res[1] == 'c') + { + if(res[2]-0x30 == 1){AutoHeater5VS[2].s = ISS_ON;} + else if(res[2]-0x30 == 0){AutoHeater5VS[2].s = ISS_OFF;} + + if(res[3]-0x30 == 1){AutoHeater5VS[3].s = ISS_ON;} + else if(res[3]-0x30 == 0){AutoHeater5VS[3].s = ISS_OFF;} + + if(res[4]-0x30 == 1){AutoHeater5VS[4].s = ISS_ON;} + else if(res[4]-0x30 == 0){AutoHeater5VS[4].s = ISS_OFF;} + + if(res[5]-0x30 == 1){AutoHeater5VS[5].s = ISS_ON;} + else if(res[5]-0x30 == 0){AutoHeater5VS[5].s = ISS_OFF;} + } + } + IDSetSwitch(&AutoHeater5VSP, nullptr); + get_count = 0; + } + init = 1; +} + +bool TerransPowerBoxProV2::processButtonSwitch(const char *dev, const char *name, ISState *states, char *names[],int n) +{ + char res[CMD_LEN] = {0}; + if (dev != nullptr && strcmp(dev, getDeviceName()) == 0) + { + if (!strcmp(AutoHeater12VSP.name, name)) + { + IUUpdateSwitch(&AutoHeater12VSP, states, names, n); + if(AutoHeater12VS[0].s == ISS_OFF){sendCommand(">Shax#",nullptr);}else if(AutoHeater12VS[0].s == ISS_ON){sendCommand(">Shay#",nullptr);} + if(AutoHeater12VS[1].s == ISS_OFF){sendCommand(">Shbx#",nullptr);}else if(AutoHeater12VS[1].s == ISS_ON){sendCommand(">Shby#",nullptr);} + if(AutoHeater12VS[2].s == ISS_OFF){sendCommand(">Shcx#",nullptr);}else if(AutoHeater12VS[2].s == ISS_ON){sendCommand(">Shcy#",nullptr);} + if(AutoHeater12VS[3].s == ISS_OFF){sendCommand(">Shdx#",nullptr);}else if(AutoHeater12VS[3].s == ISS_ON){sendCommand(">Shdy#",nullptr);} + if(AutoHeater12VS[4].s == ISS_OFF){sendCommand(">Shex#",nullptr);}else if(AutoHeater12VS[4].s == ISS_ON){sendCommand(">Shey#",nullptr);} + if(AutoHeater12VS[5].s == ISS_OFF){sendCommand(">Shfx#",nullptr);}else if(AutoHeater12VS[5].s == ISS_ON){sendCommand(">Shfy#",nullptr);} + AutoHeater12VSP.s = IPS_OK; + IDSetSwitch(&AutoHeater12VSP, nullptr); + LOG_INFO("12V Auto Heater Set"); + } + + if (!strcmp(AutoHeater5VSP.name, name)) + { + IUUpdateSwitch(&AutoHeater5VSP, states, names, n); + if(AutoHeater5VS[0].s == ISS_OFF){sendCommand(">ShAx#",nullptr);}else if(AutoHeater5VS[0].s == ISS_ON){sendCommand(">ShAy#",nullptr);} + if(AutoHeater5VS[1].s == ISS_OFF){sendCommand(">ShBx#",nullptr);}else if(AutoHeater5VS[1].s == ISS_ON){sendCommand(">ShBy#",nullptr);} + if(AutoHeater5VS[2].s == ISS_OFF){sendCommand(">ShCx#",nullptr);}else if(AutoHeater5VS[2].s == ISS_ON){sendCommand(">ShCy#",nullptr);} + if(AutoHeater5VS[3].s == ISS_OFF){sendCommand(">ShDx#",nullptr);}else if(AutoHeater5VS[3].s == ISS_ON){sendCommand(">ShDy#",nullptr);} + if(AutoHeater5VS[4].s == ISS_OFF){sendCommand(">ShEx#",nullptr);}else if(AutoHeater5VS[4].s == ISS_ON){sendCommand(">ShEy#",nullptr);} + if(AutoHeater5VS[5].s == ISS_OFF){sendCommand(">ShFx#",nullptr);}else if(AutoHeater5VS[5].s == ISS_ON){sendCommand(">ShFy#",nullptr);} + AutoHeater5VSP.s = IPS_OK; + IDSetSwitch(&AutoHeater5VSP, nullptr); + LOG_INFO("5V Auto Heater Set"); + } + + if (!strcmp(DCASP.name, name)) + { + IUUpdateSwitch(&DCASP, states, names, n); + if (DCAS[0].s == ISS_ON) + { + if (sendCommand(">SDA1#",res)) + { + if(!strcmp(res, "*DA1NNN")) + { + DCASP.s = IPS_OK; + DCAS[0].s = ISS_ON; + DCAS[1].s = ISS_OFF; + LOG_INFO("DC A ON"); + }else if(!strcmp(res, "*DA0NNN")) + { + DCASP.s = IPS_ALERT; + DCAS[0].s = ISS_OFF; + DCAS[1].s = ISS_ON; + LOG_INFO("DC A OFF"); + }else + { + DCASP.s = IPS_BUSY; + DCAS[0].s = ISS_OFF; + DCAS[1].s = ISS_OFF; + LOG_INFO("DC A Set Fail"); + } + } + } + else if (DCAS[1].s == ISS_ON) + { + if (sendCommand(">SDA0#",res)) + { + if(!strcmp(res, "*DA1NNN")) + { + DCASP.s = IPS_OK; + DCAS[0].s = ISS_ON; + DCAS[1].s = ISS_OFF; + LOG_INFO("DC A ON"); + }else if(!strcmp(res, "*DA0NNN")) + { + DCASP.s = IPS_ALERT; + DCAS[0].s = ISS_OFF; + DCAS[1].s = ISS_ON; + LOG_INFO("DC A OFF"); + }else + { + DCASP.s = IPS_BUSY; + DCAS[0].s = ISS_OFF; + DCAS[1].s = ISS_OFF; + LOG_INFO("DC A Set Fail"); + } + } + } + IDSetSwitch(&DCASP, nullptr); + return true; + } + if (!strcmp(DCBSP.name, name)) + { + IUUpdateSwitch(&DCBSP, states, names, n); + if (DCBS[0].s == ISS_ON) + { + if (sendCommand(">SDB1#",res)) + { + if(!strcmp(res, "*DB1NNN")) + { + DCBSP.s = IPS_OK; + DCBS[0].s = ISS_ON; + DCBS[1].s = ISS_OFF; + LOG_INFO("DC B ON"); + }else if(!strcmp(res, "*DB0NNN")) + { + DCBSP.s = IPS_ALERT; + DCBS[0].s = ISS_OFF; + DCBS[1].s = ISS_ON; + LOG_INFO("DC B OFF"); + }else + { + DCBSP.s = IPS_BUSY; + DCBS[0].s = ISS_OFF; + DCBS[1].s = ISS_OFF; + LOG_INFO("DC B Set Fail"); + } + } + } + else if (DCBS[1].s == ISS_ON) + { + if (sendCommand(">SDB0#",res)) + { + if(!strcmp(res, "*DB1NNN")) + { + DCBSP.s = IPS_OK; + DCBS[0].s = ISS_ON; + DCBS[1].s = ISS_OFF; + LOG_INFO("DC B ON"); + }else if(!strcmp(res, "*DB0NNN")) + { + DCBSP.s = IPS_ALERT; + DCBS[0].s = ISS_OFF; + DCBS[1].s = ISS_ON; + LOG_INFO("DC B OFF"); + }else + { + DCBSP.s = IPS_BUSY; + DCBS[0].s = ISS_OFF; + DCBS[1].s = ISS_OFF; + LOG_INFO("DC B Set Fail"); + } + } + } + IDSetSwitch(&DCBSP, nullptr); + return true; + } + if (!strcmp(DCCSP.name, name)) + { + IUUpdateSwitch(&DCCSP, states, names, n); + if (DCCS[0].s == ISS_ON) + { + if (sendCommand(">SDC1#",res)) + { + if(!strcmp(res, "*DC1NNN")) + { + DCCSP.s = IPS_OK; + DCCS[0].s = ISS_ON; + DCCS[1].s = ISS_OFF; + LOG_INFO("DC C ON"); + }else if(!strcmp(res, "*DC0NNN")) + { + DCCSP.s = IPS_ALERT; + DCCS[0].s = ISS_OFF; + DCCS[1].s = ISS_ON; + LOG_INFO("DC C OFF"); + }else + { + DCCSP.s = IPS_BUSY; + DCCS[0].s = ISS_OFF; + DCCS[1].s = ISS_OFF; + LOG_INFO("DC C Set Fail"); + } + } + } + else if (DCCS[1].s == ISS_ON) + { + if (sendCommand(">SDC0#",res)) + { + if(!strcmp(res, "*DC1NNN")) + { + DCCSP.s = IPS_OK; + DCCS[0].s = ISS_ON; + DCCS[1].s = ISS_OFF; + LOG_INFO("DC C ON"); + }else if(!strcmp(res, "*DC0NNN")) + { + DCCSP.s = IPS_ALERT; + DCCS[0].s = ISS_OFF; + DCCS[1].s = ISS_ON; + LOG_INFO("DC C OFF"); + }else + { + DCCSP.s = IPS_BUSY; + DCCS[0].s = ISS_OFF; + DCCS[1].s = ISS_OFF; + LOG_INFO("DC C Set Fail"); + } + } + } + IDSetSwitch(&DCCSP, nullptr); + return true; + } + if (!strcmp(DCDSP.name, name)) + { + IUUpdateSwitch(&DCDSP, states, names, n); + if (DCDS[0].s == ISS_ON) + { + if (sendCommand(">SDD1#",res)) + { + if(!strcmp(res, "*DD1NNN")) + { + DCDSP.s = IPS_OK; + DCDS[0].s = ISS_ON; + DCDS[1].s = ISS_OFF; + LOG_INFO("DC D ON"); + }else if(!strcmp(res, "*DD0NNN")) + { + DCDSP.s = IPS_ALERT; + DCDS[0].s = ISS_OFF; + DCDS[1].s = ISS_ON; + LOG_INFO("DC D OFF"); + }else + { + DCDSP.s = IPS_BUSY; + DCDS[0].s = ISS_OFF; + DCDS[1].s = ISS_OFF; + LOG_INFO("DC D Set Fail"); + } + } + } + else if (DCDS[1].s == ISS_ON) + { + if (sendCommand(">SDD0#",res)) + { + if(!strcmp(res, "*DD1NNN")) + { + DCDSP.s = IPS_OK; + DCDS[0].s = ISS_ON; + DCDS[1].s = ISS_OFF; + LOG_INFO("DC D ON"); + }else if(!strcmp(res, "*DD0NNN")) + { + DCDSP.s = IPS_ALERT; + DCDS[0].s = ISS_OFF; + DCDS[1].s = ISS_ON; + LOG_INFO("DC D OFF"); + }else + { + DCDSP.s = IPS_BUSY; + DCDS[0].s = ISS_OFF; + DCDS[1].s = ISS_OFF; + LOG_INFO("DC D Set Fail"); + } + } + } + IDSetSwitch(&DCDSP, nullptr); + return true; + } + if (!strcmp(DCESP.name, name)) + { + IUUpdateSwitch(&DCESP, states, names, n); + if (DCES[0].s == ISS_ON) + { + if (sendCommand(">SDE1#",res)) + { + if(!strcmp(res, "*DE1NNN")) + { + DCESP.s = IPS_OK; + DCES[0].s = ISS_ON; + DCES[1].s = ISS_OFF; + LOG_INFO("DC E ON"); + }else if(!strcmp(res, "*DE0NNN")) + { + DCESP.s = IPS_ALERT; + DCES[0].s = ISS_OFF; + DCES[1].s = ISS_ON; + LOG_INFO("DC E OFF"); + }else + { + DCESP.s = IPS_BUSY; + DCES[0].s = ISS_OFF; + DCES[1].s = ISS_OFF; + LOG_INFO("DC E Set Fail"); + } + } + } + else if (DCES[1].s == ISS_ON) + { + if (sendCommand(">SDE0#",res)) + { + if(!strcmp(res, "*DE1NNN")) + { + DCESP.s = IPS_OK; + DCES[0].s = ISS_ON; + DCES[1].s = ISS_OFF; + LOG_INFO("DC E ON"); + }else if(!strcmp(res, "*DE0NNN")) + { + DCESP.s = IPS_ALERT; + DCES[0].s = ISS_OFF; + DCES[1].s = ISS_ON; + LOG_INFO("DC E OFF"); + }else + { + DCESP.s = IPS_BUSY; + DCES[0].s = ISS_OFF; + DCES[1].s = ISS_OFF; + LOG_INFO("DC E Set Fail"); + } + } + } + IDSetSwitch(&DCESP, nullptr); + return true; + } + if (!strcmp(DCFSP.name, name)) + { + IUUpdateSwitch(&DCFSP, states, names, n); + if (DCFS[0].s == ISS_ON) + { + if (sendCommand(">SDF1#",res)) + { + if(!strcmp(res, "*DF1NNN")) + { + DCFSP.s = IPS_OK; + DCFS[0].s = ISS_ON; + DCFS[1].s = ISS_OFF; + LOG_INFO("DC F ON"); + }else if(!strcmp(res, "*DF0NNN")) + { + DCFSP.s = IPS_ALERT; + DCFS[0].s = ISS_OFF; + DCFS[1].s = ISS_ON; + LOG_INFO("DC F OFF"); + }else + { + DCFSP.s = IPS_BUSY; + DCFS[0].s = ISS_OFF; + DCFS[1].s = ISS_OFF; + LOG_INFO("DC F Set Fail"); + } + } + } + else if (DCFS[1].s == ISS_ON) + { + if (sendCommand(">SDF0#",res)) + { + if(!strcmp(res, "*DF1NNN")) + { + DCFSP.s = IPS_OK; + DCFS[0].s = ISS_ON; + DCFS[1].s = ISS_OFF; + LOG_INFO("DC F ON"); + }else if(!strcmp(res, "*DF0NNN")) + { + DCFSP.s = IPS_ALERT; + DCFS[0].s = ISS_OFF; + DCFS[1].s = ISS_ON; + LOG_INFO("DC F OFF"); + }else + { + DCFSP.s = IPS_BUSY; + DCFS[0].s = ISS_OFF; + DCFS[1].s = ISS_OFF; + LOG_INFO("DC F Set Fail"); + } + } + } + IDSetSwitch(&DCFSP, nullptr); + return true; + } + if (!strcmp(DC19VSP.name, name)) + { + IUUpdateSwitch(&DC19VSP, states, names, n); + if (DC19VS[0].s == ISS_ON) + { + if (sendCommand(">SDG1#",res)) + { + if(!strcmp(res, "*DG1NNN")) + { + DC19VSP.s = IPS_OK; + DC19VS[0].s = ISS_ON; + DC19VS[1].s = ISS_OFF; + LOG_INFO("DC 19V ON"); + }else if(!strcmp(res, "*DG0NNN")) + { + DC19VSP.s = IPS_ALERT; + DC19VS[0].s = ISS_OFF; + DC19VS[1].s = ISS_ON; + LOG_INFO("DC 19V OFF"); + }else + { + DC19VSP.s = IPS_BUSY; + DC19VS[0].s = ISS_OFF; + DC19VS[1].s = ISS_OFF; + LOG_INFO("DC 19V Set Fail"); + } + } + } + else if (DC19VS[1].s == ISS_ON) + { + if (sendCommand(">SDG0#",res)) + { + if(!strcmp(res, "*DG1NNN")) + { + DC19VSP.s = IPS_OK; + DC19VS[0].s = ISS_ON; + DC19VS[1].s = ISS_OFF; + LOG_INFO("DC 19V ON"); + }else if(!strcmp(res, "*DG0NNN")) + { + DC19VSP.s = IPS_ALERT; + DC19VS[0].s = ISS_OFF; + DC19VS[1].s = ISS_ON; + LOG_INFO("DC 19V OFF"); + }else + { + DC19VSP.s = IPS_BUSY; + DC19VS[0].s = ISS_OFF; + DC19VS[1].s = ISS_OFF; + LOG_INFO("DC 19V Set Fail"); + } + } + } + IDSetSwitch(&DC19VSP, nullptr); + return true; + } + if (!strcmp(USBASP.name, name)) + { + IUUpdateSwitch(&USBASP, states, names, n); + if (USBAS[0].s == ISS_ON) + { + if (sendCommand(">SUA1A#",res)) + { + if(!strcmp(res, "*UA111N")) + { + USBASP.s = IPS_OK; + USBAS[0].s = ISS_ON; + USBAS[1].s = ISS_OFF; + LOG_INFO("USB A ON"); + }else if(!strcmp(res, "*UA000N")) + { + USBASP.s = IPS_ALERT; + USBAS[0].s = ISS_OFF; + USBAS[1].s = ISS_ON; + LOG_INFO("USB A OFF"); + }else + { + USBASP.s = IPS_BUSY; + USBAS[0].s = ISS_OFF; + USBAS[1].s = ISS_OFF; + LOG_INFO("USB A Set Fail"); + } + } + } + else if (USBAS[1].s == ISS_ON) + { + if (sendCommand(">SUA0A#",res)) + { + if(!strcmp(res, "*UA111N")) + { + USBASP.s = IPS_OK; + USBAS[0].s = ISS_ON; + USBAS[1].s = ISS_OFF; + LOG_INFO("USB A ON"); + }else if(!strcmp(res, "*UA000N")) + { + USBASP.s = IPS_ALERT; + USBAS[0].s = ISS_OFF; + USBAS[1].s = ISS_ON; + LOG_INFO("USB A OFF"); + }else + { + USBASP.s = IPS_BUSY; + USBAS[0].s = ISS_OFF; + USBAS[1].s = ISS_OFF; + LOG_INFO("USB A Set Fail"); + } + } + } + IDSetSwitch(&USBASP, nullptr); + return true; + } + if (!strcmp(USBBSP.name, name)) + { + IUUpdateSwitch(&USBBSP, states, names, n); + if (USBBS[0].s == ISS_ON) + { + if (sendCommand(">SUB1A#",res)) + { + if(!strcmp(res, "*UB111N")) + { + USBBSP.s = IPS_OK; + USBBS[0].s = ISS_ON; + USBBS[1].s = ISS_OFF; + LOG_INFO("USB B ON"); + }else if(!strcmp(res, "*UB000N")) + { + USBBSP.s = IPS_ALERT; + USBBS[0].s = ISS_OFF; + USBBS[1].s = ISS_ON; + LOG_INFO("USB B OFF"); + }else + { + USBBSP.s = IPS_BUSY; + USBBS[0].s = ISS_OFF; + USBBS[1].s = ISS_OFF; + LOG_INFO("USB B Set Fail"); + } + } + } + else if (USBBS[1].s == ISS_ON) + { + if (sendCommand(">SUB0A#",res)) + { + if(!strcmp(res, "*UB111N")) + { + USBBSP.s = IPS_OK; + USBBS[0].s = ISS_ON; + USBBS[1].s = ISS_OFF; + LOG_INFO("USB B ON"); + }else if(!strcmp(res, "*UB000N")) + { + USBBSP.s = IPS_ALERT; + USBBS[0].s = ISS_OFF; + USBBS[1].s = ISS_ON; + LOG_INFO("USB B OFF"); + }else + { + USBBSP.s = IPS_BUSY; + USBBS[0].s = ISS_OFF; + USBBS[1].s = ISS_OFF; + LOG_INFO("USB B Set Fail"); + } + } + } + IDSetSwitch(&USBBSP, nullptr); + return true; + } + if (!strcmp(USBCSP.name, name)) + { + IUUpdateSwitch(&USBCSP, states, names, n); + if (USBCS[0].s == ISS_ON) + { + if (sendCommand(">SUC1A#",res)) + { + if(!strcmp(res, "*UC111N")) + { + USBCSP.s = IPS_OK; + USBCS[0].s = ISS_ON; + USBCS[1].s = ISS_OFF; + LOG_INFO("USB C ON"); + }else if(!strcmp(res, "*UC000N")) + { + USBCSP.s = IPS_ALERT; + USBCS[0].s = ISS_OFF; + USBCS[1].s = ISS_ON; + LOG_INFO("USB C OFF"); + }else + { + USBCSP.s = IPS_BUSY; + USBCS[0].s = ISS_OFF; + USBCS[1].s = ISS_OFF; + LOG_INFO("USB C Set Fail"); + } + } + } + else if (USBCS[1].s == ISS_ON) + { + if (sendCommand(">SUC0A#",res)) + { + if(!strcmp(res, "*UC111N")) + { + USBCSP.s = IPS_OK; + USBCS[0].s = ISS_ON; + USBCS[1].s = ISS_OFF; + LOG_INFO("USB C ON"); + }else if(!strcmp(res, "*UC000N")) + { + USBCSP.s = IPS_ALERT; + USBCS[0].s = ISS_OFF; + USBCS[1].s = ISS_ON; + LOG_INFO("USB C OFF"); + }else + { + USBCSP.s = IPS_BUSY; + USBCS[0].s = ISS_OFF; + USBCS[1].s = ISS_OFF; + LOG_INFO("USB C Set Fail"); + } + } + } + IDSetSwitch(&USBCSP, nullptr); + return true; + } + if (!strcmp(USBDSP.name, name)) + { + IUUpdateSwitch(&USBDSP, states, names, n); + if (USBDS[0].s == ISS_ON) + { + if (sendCommand(">SUD1A#",res)) + { + if(!strcmp(res, "*UD111N")) + { + USBDSP.s = IPS_OK; + USBDS[0].s = ISS_ON; + USBDS[1].s = ISS_OFF; + LOG_INFO("USB D ON"); + }else if(!strcmp(res, "*UD000N")) + { + USBDSP.s = IPS_ALERT; + USBDS[0].s = ISS_OFF; + USBDS[1].s = ISS_ON; + LOG_INFO("USB D OFF"); + }else + { + USBDSP.s = IPS_BUSY; + USBDS[0].s = ISS_OFF; + USBDS[1].s = ISS_OFF; + LOG_INFO("USB D Set Fail"); + } + } + } + else if (USBDS[1].s == ISS_ON) + { + if (sendCommand(">SUD0A#",res)) + { + if(!strcmp(res, "*UD111N")) + { + USBDSP.s = IPS_OK; + USBDS[0].s = ISS_ON; + USBDS[1].s = ISS_OFF; + LOG_INFO("USB D ON"); + }else if(!strcmp(res, "*UD000N")) + { + USBDSP.s = IPS_ALERT; + USBDS[0].s = ISS_OFF; + USBDS[1].s = ISS_ON; + LOG_INFO("USB D OFF"); + }else + { + USBDSP.s = IPS_BUSY; + USBDS[0].s = ISS_OFF; + USBDS[1].s = ISS_OFF; + LOG_INFO("USB D Set Fail"); + } + } + } + IDSetSwitch(&USBDSP, nullptr); + return true; + } + if (!strcmp(USBESP.name, name)) + { + IUUpdateSwitch(&USBESP, states, names, n); + if (USBES[0].s == ISS_ON) + { + if (sendCommand(">SUE1A#",res)) + { + if(!strcmp(res, "*UE11NN")) + { + USBESP.s = IPS_OK; + USBES[0].s = ISS_ON; + USBES[1].s = ISS_OFF; + LOG_INFO("USB E ON"); + }else if(!strcmp(res, "*UE00NN")) + { + USBESP.s = IPS_ALERT; + USBES[0].s = ISS_OFF; + USBES[1].s = ISS_ON; + LOG_INFO("USB E OFF"); + }else + { + USBESP.s = IPS_BUSY; + USBES[0].s = ISS_OFF; + USBES[1].s = ISS_OFF; + LOG_INFO("USB E Set Fail"); + } + } + } + else if (USBES[1].s == ISS_ON) + { + if (sendCommand(">SUE0A#",res)) + { + if(!strcmp(res, "*UE11NN")) + { + USBESP.s = IPS_OK; + USBES[0].s = ISS_ON; + USBES[1].s = ISS_OFF; + LOG_INFO("USB E ON"); + }else if(!strcmp(res, "*UE00NN")) + { + USBESP.s = IPS_ALERT; + USBES[0].s = ISS_OFF; + USBES[1].s = ISS_ON; + LOG_INFO("USB E OFF"); + }else + { + USBESP.s = IPS_BUSY; + USBES[0].s = ISS_OFF; + USBES[1].s = ISS_OFF; + LOG_INFO("USB E Set Fail"); + } + } + } + IDSetSwitch(&USBESP, nullptr); + return true; + } + if (!strcmp(USBFSP.name, name)) + { + IUUpdateSwitch(&USBFSP, states, names, n); + if (USBFS[0].s == ISS_ON) + { + if (sendCommand(">SUF1A#",res)) + { + if(!strcmp(res, "*UF11NN")) + { + USBFSP.s = IPS_OK; + USBFS[0].s = ISS_ON; + USBFS[1].s = ISS_OFF; + LOG_INFO("USB F ON"); + }else if(!strcmp(res, "*UF00NN")) + { + USBFSP.s = IPS_ALERT; + USBFS[0].s = ISS_OFF; + USBFS[1].s = ISS_ON; + LOG_INFO("USB F OFF"); + }else + { + USBFSP.s = IPS_BUSY; + USBFS[0].s = ISS_OFF; + USBFS[1].s = ISS_OFF; + LOG_INFO("USB F Set Fail"); + } + } + } + else if (USBFS[1].s == ISS_ON) + { + if (sendCommand(">SUF0A#",res)) + { + if(!strcmp(res, "*UF11NN")) + { + USBFSP.s = IPS_OK; + USBFS[0].s = ISS_ON; + USBFS[1].s = ISS_OFF; + LOG_INFO("USB F ON"); + }else if(!strcmp(res, "*UF00NN")) + { + USBFSP.s = IPS_ALERT; + USBFS[0].s = ISS_OFF; + USBFS[1].s = ISS_ON; + LOG_INFO("USB F OFF"); + }else + { + USBFSP.s = IPS_BUSY; + USBFS[0].s = ISS_OFF; + USBFS[1].s = ISS_OFF; + LOG_INFO("USB F Set Fail"); + } + } + } + IDSetSwitch(&USBFSP, nullptr); + return true; + } + if (!strcmp(StateSaveSP.name, name)) + { + IUUpdateSwitch(&StateSaveSP, states, names, n); + if (StateSaveS[0].s == ISS_ON) + { + if (sendCommand(">SS1#",res)) + { + if(!strcmp(res, "*SS1NNN")) + { + StateSaveSP.s = IPS_OK; + StateSaveS[0].s = ISS_ON; + StateSaveS[1].s = ISS_OFF; + LOG_INFO("Save Switch State Enable"); + }else if(!strcmp(res, "*SS0NNN")) + { + StateSaveSP.s = IPS_ALERT; + StateSaveS[0].s = ISS_OFF; + StateSaveS[1].s = ISS_ON; + LOG_INFO("Save Switch State Disable"); + }else + { + StateSaveSP.s = IPS_BUSY; + StateSaveS[0].s = ISS_OFF; + StateSaveS[1].s = ISS_OFF; + LOG_INFO("Save Switch State Set Fail"); + } + } + } + else if (StateSaveS[1].s == ISS_ON) + { + if (sendCommand(">SS0#",res)) + { + if(!strcmp(res, "*SS1NNN")) + { + StateSaveSP.s = IPS_OK; + StateSaveS[0].s = ISS_ON; + StateSaveS[1].s = ISS_OFF; + LOG_INFO("Save Switch State Enable"); + }else if(!strcmp(res, "*SS0NNN")) + { + StateSaveSP.s = IPS_ALERT; + StateSaveS[0].s = ISS_OFF; + StateSaveS[1].s = ISS_ON; + LOG_INFO("Save Switch State Disable"); + }else + { + StateSaveSP.s = IPS_BUSY; + StateSaveS[0].s = ISS_OFF; + StateSaveS[1].s = ISS_OFF; + LOG_INFO("Save Switch State Set Fail"); + } + } + } + IDSetSwitch(&StateSaveSP, nullptr); + return true; + } + if (!strcmp(DCADJSP.name, name)) + { + IUUpdateSwitch(&DCADJSP, states, names, n); + if (DCADJS[0].s == ISS_ON) + { + sendCommand(">SA10#",nullptr); + LOG_INFO("DCADJ OFF"); + DCADJSP.s = IPS_ALERT; + } + else if (DCADJS[1].s == ISS_ON) + { + sendCommand(">SA20#",nullptr); + LOG_INFO("DC ADJ 5V"); + DCADJSP.s = IPS_OK; + } + else if (DCADJS[2].s == ISS_ON) + { + sendCommand(">SA40#",nullptr); + LOG_INFO("DC ADJ 9V"); + DCADJSP.s = IPS_OK; + } + else if (DCADJS[3].s == ISS_ON) + { + sendCommand(">SA550#",nullptr); + LOG_INFO("DC ADJ 12V"); + DCADJSP.s = IPS_OK; + } + IDSetSwitch(&DCADJSP, nullptr); + return true; + } + } + return false; +} diff --git a/drivers/auxiliary/Terrans_PowerBoxPro_V2.h b/drivers/auxiliary/Terrans_PowerBoxPro_V2.h new file mode 100644 index 0000000000..ad172797c7 --- /dev/null +++ b/drivers/auxiliary/Terrans_PowerBoxPro_V2.h @@ -0,0 +1,154 @@ +/******************************************************************************* + Copyright(c) 2015 Jasem Mutlaq. All rights reserved. + + TerransPowerBoxProV2 + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. +*******************************************************************************/ + +#pragma once + +#include "libindi/defaultdevice.h" +#include "indiweatherinterface.h" + +#include +#include + +#include "basedevice.h" + +namespace Connection +{ + class Serial; +} + +class TerransPowerBoxProV2 : public INDI::DefaultDevice, public INDI::WeatherInterface +{ +public: + TerransPowerBoxProV2(); + public: + virtual ~TerransPowerBoxProV2() = default; + virtual bool initProperties() override; + virtual bool updateProperties() override; + virtual void TimerHit() override; + virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override; + virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override; + + // Weather Overrides + virtual IPState updateWeather() override + { + return IPS_OK; + } + + protected: + virtual const char *getDefaultName() override; + virtual bool saveConfigItems(FILE *fp) override; + + private: + bool Handshake(); + bool sendCommand(const char * cmd, char * res); + int PortFD{-1}; + + bool setupComplete { false }; + bool processButtonSwitch(const char *dev, const char *name, ISState *states, char *names[],int n); + + void Get_State(); + + Connection::Serial *serialConnection { nullptr }; + + const char *ConfigRenameDCA { nullptr }; + const char *ConfigRenameDCB { nullptr }; + const char *ConfigRenameDCC { nullptr }; + const char *ConfigRenameDCD { nullptr }; + const char *ConfigRenameDCE { nullptr }; + const char *ConfigRenameDCF { nullptr }; + const char *ConfigRenameDC19V { nullptr }; + const char *ConfigRenameUSBA { nullptr }; + const char *ConfigRenameUSBB { nullptr }; + const char *ConfigRenameUSBC { nullptr }; + const char *ConfigRenameUSBD { nullptr }; + const char *ConfigRenameUSBE { nullptr }; + const char *ConfigRenameUSBF { nullptr }; + const char *ConfigRenameADJ { nullptr }; + + //Power Switch + ISwitch DCAS[2]; + ISwitch DCBS[2]; + ISwitch DCCS[2]; + ISwitch DCDS[2]; + ISwitch DCES[2]; + ISwitch DCFS[2]; + ISwitch DC19VS[2]; + + ISwitch USBAS[2]; + ISwitch USBBS[2]; + ISwitch USBCS[2]; + ISwitch USBDS[2]; + ISwitch USBES[2]; + ISwitch USBFS[2]; + + ISwitch DCADJS[4]; + ISwitch StateSaveS[2]; + + ISwitch AutoHeater12VS[6]; + ISwitch AutoHeater5VS[6]; + + ISwitchVectorProperty DCASP; + ISwitchVectorProperty DCBSP; + ISwitchVectorProperty DCCSP; + ISwitchVectorProperty DCDSP; + ISwitchVectorProperty DCESP; + ISwitchVectorProperty DCFSP; + ISwitchVectorProperty DC19VSP; + + ISwitchVectorProperty USBASP; + ISwitchVectorProperty USBBSP; + ISwitchVectorProperty USBCSP; + ISwitchVectorProperty USBDSP; + ISwitchVectorProperty USBESP; + ISwitchVectorProperty USBFSP; + + ISwitchVectorProperty DCADJSP; + ISwitchVectorProperty StateSaveSP; + + ISwitchVectorProperty AutoHeater12VSP; + ISwitchVectorProperty AutoHeater5VSP; + + //Sensor Date + INumber InputVotageN[1]; + INumberVectorProperty InputVotageNP; + + INumber InputCurrentN[1]; + INumberVectorProperty InputCurrentNP; + + INumber PowerN[4]; + INumberVectorProperty PowerNP; + + INumber MCUTempN[1]; + INumberVectorProperty MCUTempNP; + + //save name + IText RenameT[14]; + ITextVectorProperty RenameTP; + + static constexpr const char *ENVIRONMENT_TAB {"Environment"}; + static constexpr const char *ADD_SETTING_TAB {"Additional Settings"}; + +}; + +