Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion History.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Version 2020.xxxx (xxxx)
- Implemented: RTL433, Switched to Json input
- Implemented: The following sensor types now support RSSI: Distance Sensor, Moisture Sensor, Watt Meter, kWh Meter
- Implemented: Websocket notification for secondary/sub devices
- Implemented: ZWave, Legend and tooltips in Neighbor�s overview
- Implemented: ZWave, Legend and tooltips in Neighbor�s overview
- Updated: dzVents version 3.0.11 ( https://www.domoticz.com/wiki/DzVents:_next_generation_LUA_scripting#History )
- Updated: eVehicles, added ODO meter, unlock/open alert, max charge level to Tesla module
- Updated: OpenZWave configuration files
Expand All @@ -30,6 +30,7 @@ Version 2020.xxxx (xxxx)
- Fixed: Font in events editor on MacOS
- Fixed: Possible crash in CEventSystem::SetEventTrigger
- Fixed: Sound device was incorrectly displayed on the Floorplan
- Fixed Annatherm Presets usage in Events, Please use the following percentages: 10% for Home, 20% for Away, 30% Night 40% for Vacation
- For a full overview visit: https://www.domoticz.com/wiki/Domoticz_versions_-_Commits for details

Version 2020.2 (April 26th 2020)
Expand Down
106 changes: 71 additions & 35 deletions hardware/AnnaThermostat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

// Anna Switches

#define sAnneBoilerState 8
#define sAnneBoilerState 8
#define sAnnaFlameState 9
#define sAnnaProximity 10
#define sAnnaPresets 11
Expand All @@ -29,8 +29,10 @@ const std::string ANNA_LOCATION = "/cache/domain_objects;class=Location";
const std::string ANNA_SET_LOCATION = "/core/locations";


//#define _DEBUG // toggle for reading and writing local files

#ifdef _DEBUG
//#define DEBUG_AnnaThermostat
//define DEBUG_AnnaThermostat
#define DEBUG_ANNA_APPLIANCE_READ "/tmp/anna/appliances.xml"
#define DEBUG_ANNA_WRITE "/tmp/anna/output.txt"
#define DEBUG_ANNA_LOCATION_READ "/tmp/anna/location.xml"
Expand Down Expand Up @@ -73,7 +75,8 @@ CAnnaThermostat::CAnnaThermostat(const int ID, const std::string& IPAddress, con
{
m_HwdID = ID;
Init();
GetMeterDetails();
// GetMeterDetails();

}

CAnnaThermostat::~CAnnaThermostat(void)
Expand All @@ -95,10 +98,18 @@ void CAnnaThermostat::CAnnaThermostat::Init()

bool CAnnaThermostat::StartHardware()
{
RequestStart();
// Showing we are starting Annatherm and
// notify users in the log how to use the event system once per startup
Log(LOG_NORM, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Log(LOG_NORM, "AnnaTherm: Notice: To change presets in events, please use the following percentages levels:");
Log(LOG_NORM, "10%% for Home, 20%% for Away, 30%% for Night, 40%% for Vacation & 50%% for Frost (Lua use 'Set Level: 20')");
Log(LOG_NORM, "Any other value will set Annatherm for safety to frost protection! ");
Log(LOG_NORM, "To Detect changes in scripts use 'Off, Home, Away, Night, Vacation, Frost'");
Log(LOG_NORM, "Adjusting the Temp manually on the ANNA or via App, forces the ANNA to set Scenes to Off!!");
Log(LOG_NORM, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");

RequestStart();
Init();

//Start worker thread
m_thread = std::make_shared<std::thread>(&CAnnaThermostat::Do_Work, this);
SetThreadNameInt(m_thread->native_handle());
Expand Down Expand Up @@ -168,7 +179,7 @@ bool CAnnaThermostat::WriteToHardware(const char* pdata, const unsigned char /*l
bool bIsOn = (pCmd->LIGHTING2.cmnd == light2_sOn);
if (node_id == sAnneBoilerState || node_id == sAnnaFlameState)
{
return false; // just return Error as these are not supposed to be switches
return false; // just return Error as these are not supposed to be switches
}
else if (node_id == sAnnaProximity)
{
Expand Down Expand Up @@ -221,6 +232,7 @@ void CAnnaThermostat::SetSetpoint(const int /*idx*/, const float temp)
return;
}
}

bool CAnnaThermostat::AnnaSetPreset(uint8_t level)
{
std::stringstream szURL;
Expand Down Expand Up @@ -249,7 +261,7 @@ bool CAnnaThermostat::AnnaSetPreset(uint8_t level)

char szTemp[10];
switch (level) {
case 0:
case 0:
strcpy(szTemp, "none");
break;
case 10:
Expand All @@ -264,10 +276,14 @@ bool CAnnaThermostat::AnnaSetPreset(uint8_t level)
case 40:
strcpy(szTemp, "vacation");
break;
default:
strcpy(szTemp, "none");
case 50:
strcpy(szTemp, "no_frost");
break;
default:
Log(LOG_STATUS, "AnnaTherm: Invalid value for Preset %i .. Aborting Switch", level);
return false;
}
Log(LOG_STATUS, "Switching Anna gateway preset to: %s", szTemp);
sPostData << "<locations>";
sPostData << "<location id=\"";
sPostData << m_AnnaLocation.m_ALocationID;
Expand All @@ -289,14 +305,14 @@ bool CAnnaThermostat::AnnaSetPreset(uint8_t level)
SaveString2Disk(sPostData.str(), DEBUG_ANNA_WRITE);
SaveString2Disk(DEBUG_ANNA_CRLF, DEBUG_ANNA_WRITE);

#else
#else
if (!HTTPClient::PUT(szURL.str(), sPostData.str(), ExtraHeaders, sResult, true))
{
Log(LOG_ERROR, "AnnaTherm: Error setting Preset State !");
return false;
}
#endif
return true;
#endif
return true;
}

bool CAnnaThermostat::AnnaToggleProximity(bool bToggle)
Expand Down Expand Up @@ -343,17 +359,17 @@ bool CAnnaThermostat::AnnaToggleProximity(bool bToggle)

#ifdef DEBUG_AnnaThermostat
SaveString2Disk("<-- ANNA - TogglePRoximitySensor-->", DEBUG_ANNA_WRITE);
SaveString2Disk(DEBUG_ANNN_CRLF, DEBUG_ANNA_WRITE);
SaveString2Disk(DEBUG_ANNA_CRLF, DEBUG_ANNA_WRITE);
SaveString2Disk(szURL.str(), DEBUG_ANNA_WRITE);
SaveString2Disk(DEBUG_ANNN_CRLF, DEBUG_ANNA_WRITE);
SaveString2Disk(DEBUG_ANNA_CRLF, DEBUG_ANNA_WRITE);
SaveString2Disk(sPostData.str(), DEBUG_ANNA_WRITE);
#else
#else
if (!HTTPClient::PUT(szURL.str(), sPostData.str(), ExtraHeaders, sResult, true))
{
Log(LOG_ERROR, "AnnaTherm: Error setting toggle Proximity !");
return false;
}
#endif
#endif
return true;
}
bool CAnnaThermostat::SetAway(const bool /*bIsAway*/)
Expand Down Expand Up @@ -584,14 +600,14 @@ void CAnnaThermostat::GetMeterDetails()
SendSwitch(sAnnaFlameState, 1, 255, false, 0, sname);
}
//make device ID
const int NodeID = sAnnaFlameState;
unsigned char ID1 = (unsigned char)((NodeID & 0xFF000000) >> 24);
unsigned char ID2 = (unsigned char)((NodeID & 0xFF0000) >> 16);
unsigned char ID3 = (unsigned char)((NodeID & 0xFF00) >> 8);
unsigned char ID4 = (unsigned char)NodeID & 0xFF;

char szIdx[10];
sprintf(szIdx, "%X%02X%02X%02X", ID1, ID2, ID3, ID4);
//const int NodeID = sAnnaFlameState;
//unsigned char ID1 = (unsigned char)((NodeID & 0xFF000000) >> 24);
//unsigned char ID2 = (unsigned char)((NodeID & 0xFF0000) >> 16);
//unsigned char ID3 = (unsigned char)((NodeID & 0xFF00) >> 8);
//unsigned char ID4 = (unsigned char)NodeID & 0xFF;

//char szIdx[10];
//sprintf(szIdx, "%X%02X%02X%02X", ID1, ID2, ID3, ID4);
//m_sql.safe_query("UPDATE DeviceStatus SET SwitchType=%d WHERE (HardwareID==%d) AND (DeviceID=='%q')", 5, m_HwdID,szIdx);
}

Expand Down Expand Up @@ -628,7 +644,6 @@ void CAnnaThermostat::GetMeterDetails()
bSwitch = false;
}
SendSwitch(sAnnaProximity, 0, 255, bSwitch, 0, sname);
//m_sql.safe_query("UPDATE DeviceStatus SET CustomImage=%d WHERE (HardwareID==%d) AND (DeviceID=='%08X')", 12, m_HwdID,sAnnaProximity);
}
}
else if (sname == "preset_state")
Expand Down Expand Up @@ -664,21 +679,42 @@ void CAnnaThermostat::GetMeterDetails()
}
else if (strcmp(tmpstr.c_str(), "no_frost") == 0)
{
strncpy(sPreset, "00", sizeof(sPreset));
strncpy(sPreset, "50", sizeof(sPreset));
}
else strncpy(sPreset, "50", sizeof(sPreset));

// setting up code to let Domoticz know the selector is changed
_tGeneralSwitch xcmd;
xcmd.len = sizeof(_tGeneralSwitch) - 1;
xcmd.id = sAnnaPresets;
xcmd.type = pTypeGeneralSwitch;
//xcmd.subtype = sSwitchGeneralSwitch;
xcmd.unitcode = 1;
xcmd.subtype = sSwitchTypeSelector;
xcmd.level = std::stoi(sPreset);

std::string PresetName = "Anna Preset";
_eSwitchType switchtype;
switchtype = STYPE_Selector;
int customImage = 16;//Frost

std::vector<std::vector<std::string> > result;
result = m_sql.safe_query("SELECT ID FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%08X')", m_HwdID, sAnnaPresets);
result = m_sql.safe_query("SELECT ID , sValue FROM DeviceStatus WHERE (HardwareID==%d) AND (DeviceID=='%08X') AND (Unit == '%d')", m_HwdID, sAnnaPresets, xcmd.unitcode);
m_mainworker.PushAndWaitRxMessage(this, (const unsigned char *)&xcmd, PresetName.c_str(), 255);
if (result.empty()) //Switch is not yet in the system so create it
{
std::string options_str = m_sql.FormatDeviceOptions(m_sql.BuildDeviceOptions("SelectorStyle:0;LevelNames:Off|Home|Away|Night|Vacation;LevelOffHidden:true;LevelActions:00|10|20|30|40", false));
m_sql.safe_query(
"INSERT INTO DeviceStatus (HardwareID, DeviceID, Unit, Type, SubType, SwitchType, Used, SignalLevel, BatteryLevel, Name, nValue, sValue, CustomImage, Options) "
"VALUES (%d, '%08X', %d, %d, %d, %d, %d, 12, 255, '%q', 0, '%q', %d, '%q')", m_HwdID, sAnnaPresets, 0, pTypeGeneralSwitch, sSwitchTypeSelector, STYPE_Selector, 0, "Anna Presets", sPreset, customImage, options_str.c_str());
}
std::string options_str = m_sql.FormatDeviceOptions(m_sql.BuildDeviceOptions("SelectorStyle:0;LevelNames:Off|Home|Away|Night|Vacation|Frost;LevelOffHidden:true;LevelActions:00|10|20|30|40|50", false));
//m_sql.safe_query(
// "INSERT INTO DeviceStatus (HardwareID, DeviceID, Unit, Type, SubType, SwitchType, Used, SignalLevel, BatteryLevel, Name, nValue, sValue, CustomImage, Options) "
// "VALUES (%d, '%08X', %d, %d, %d, %d, %d, 12, 255, '%q', 0, '%q', %d, '%q')", m_HwdID, sAnnaPresets, 1, pTypeGeneralSwitch, sSwitchTypeSelector, STYPE_Selector, 0,PresetName.c_str() , sPreset, customImage, options_str.c_str());
m_sql.safe_query("UPDATE DeviceStatus SET Name='%q', SwitchType=%d, CustomImage=%i, Options='%q' WHERE(HardwareID == %d) AND (DeviceID=='%08X') AND (Unit == '%d')", PresetName.c_str(), (switchtype), customImage, options_str.c_str(), m_HwdID, sAnnaPresets, xcmd.unitcode);
}
else
{
result = m_sql.safe_query("UPDATE DeviceStatus SET sValue = '%q' where (HardwareID==%d) AND (DeviceID=='%08X')", sPreset, m_HwdID, sAnnaPresets);
int old_value = atoi(result[0][1].c_str());
if (old_value != xcmd.level)
Log(LOG_STATUS, "Syncing %s with Anna Gateway preset - Received : %s", PresetName.c_str(), tmpstr.c_str());
result = m_sql.safe_query("UPDATE DeviceStatus SET sValue = '%q' WHERE (HardwareID==%d) AND (DeviceID=='%08X')", sPreset, m_HwdID, sAnnaPresets);
}
}
}
Expand All @@ -687,7 +723,7 @@ void CAnnaThermostat::GetMeterDetails()
return;
}

// Checks if the USername and password are filled in
// Checks if the Username and password are filled in
bool CAnnaThermostat::CheckLoginData()
{
if (m_UserName.size() == 0)
Expand All @@ -697,7 +733,7 @@ bool CAnnaThermostat::CheckLoginData()
return true;
}

// Fetched the location information (id,name and type)from the first location given by the Anna/Adam Gateway
// Fetched the location information (id,name and type)from the first location given by the Anna/Adam Gateway
bool CAnnaThermostat::AnnaGetLocation()
{
std::string sResult;
Expand Down
7 changes: 4 additions & 3 deletions hardware/AnnaThermostat.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ class CAnnaThermostat : public CDomoticzHardwareBase
std::string m_ALocationName;
std::string m_ALocationType;
};

public:
CAnnaThermostat(const int ID, const std::string &IPAddress, const unsigned short usIPPort, const std::string &Username, const std::string &Password);
~CAnnaThermostat(void);
bool WriteToHardware(const char *pdata, const unsigned char length) override;
void SetSetpoint(const int idx, const float temp);
void SetProgramState(const int newState);
bool AnnaSetPreset(uint8_t level);

private:
void Init();
bool StartHardware() override;
Expand All @@ -27,9 +29,8 @@ class CAnnaThermostat : public CDomoticzHardwareBase
void SendSetPointSensor(const unsigned char Idx, const float Temp, const std::string &defaultname);
bool SetAway(const bool bIsAway);
bool AnnaToggleProximity(bool bToggle);
bool AnnaSetPreset(uint8_t level);
bool AnnaGetLocation();

private:
std::string m_IPAddress;
unsigned short m_IPPort;
Expand Down