@alowhum
bool MySensorsBase::WriteToHardware(const char *pdata, const unsigned char length)
{
const tRBUF *pCmd = reinterpret_cast<const tRBUF *>(pdata);
unsigned char packettype = pCmd->ICMND.packettype;
unsigned char subtype = pCmd->ICMND.subtype;
if (packettype == pTypeLighting2)
{
//Light command
int node_id = pCmd->LIGHTING2.id4;
int child_sensor_id = pCmd->LIGHTING2.unitcode;
if (_tMySensorNode *pNode = FindNode(node_id))
{
_tMySensorChild *pChild = pNode->FindChild(child_sensor_id);
if (!pChild)
{
_log.Log(LOG_ERROR, "MySensors: Light command received for unknown node_id: %d, child_id: %d", node_id, child_sensor_id);
return false;
}
int light_command = pCmd->LIGHTING2.cmnd;
if ((pCmd->LIGHTING2.cmnd == light2_sSetLevel) && (pCmd->LIGHTING2.level == 0))
{
light_command = light2_sOff;
}
else if ((pCmd->LIGHTING2.cmnd == light2_sSetLevel) && (pCmd->LIGHTING2.level == 255))
{
light_command = light2_sOn;
}
if ((light_command == light2_sOn) || (light_command == light2_sOff))
{
std::string lState = (light_command == light2_sOn) ? "1" : "0";
if (pChild->presType == S_LOCK)
{
//Door lock/contact
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_LOCK_STATUS, lState, pChild->useAck, pChild->ackTimeout);
}
else if (pChild->presType == S_SCENE_CONTROLLER)
{
//Scene Controller
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, (light_command == light2_sOn) ? V_SCENE_ON : V_SCENE_OFF, lState, pChild->useAck, pChild->ackTimeout);
}
else
{
//normal
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_STATUS, lState, pChild->useAck, pChild->ackTimeout);
}
}
else if (light_command == light2_sSetLevel)
{
float fvalue = (100.0f / 14.0f)*float(pCmd->LIGHTING2.level);
if (fvalue > 100.0f)
fvalue = 100.0f; //99 is fully on
int svalue = round(fvalue);
std::stringstream sstr;
sstr << svalue;
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_PERCENTAGE, sstr.str(), pChild->useAck, pChild->ackTimeout);
}
}
else {
_log.Log(LOG_ERROR, "MySensors: Light command received for unknown node_id: %d", node_id);
return false;
}
}
else if (packettype == pTypeLimitlessLights)
{
//RGW/RGBW command
_tLimitlessLights *pLed = (_tLimitlessLights *)pdata;
//unsigned char ID1 = (unsigned char)((pLed->id & 0xFF000000) >> 24);
//unsigned char ID2 = (unsigned char)((pLed->id & 0x00FF0000) >> 16);
unsigned char ID3 = (unsigned char)((pLed->id & 0x0000FF00) >> 8);
unsigned char ID4 = (unsigned char)pLed->id & 0x000000FF;
int node_id = (ID3 << 8) | ID4;
int child_sensor_id = pLed->dunit;
if (_tMySensorNode *pNode = FindNode(node_id))
{
_tMySensorChild *pChild = pNode->FindChild(child_sensor_id);
if (!pChild)
{
_log.Log(LOG_ERROR, "MySensors: Light command received for unknown node_id: %d, child_id: %d", node_id, child_sensor_id);
return false;
}
bool bIsRGBW = (pNode->FindChildWithPresentationType(child_sensor_id, S_RGBW_LIGHT) != NULL);
if (pLed->command == Limitless_SetRGBColour)
{
int red, green, blue;
float cHue = (360.0f / 255.0f)*float(pLed->value);//hue given was in range of 0-255
int Brightness = 100;
int dMax = round((255.0f / 100.0f)*float(Brightness));
hue2rgb(cHue, red, green, blue, dMax);
std::stringstream sstr;
sstr << std::setw(2) << std::uppercase << std::hex << std::setfill('0') << std::hex << red
<< std::setw(2) << std::uppercase << std::hex << std::setfill('0') << std::hex << green
<< std::setw(2) << std::uppercase << std::hex << std::setfill('0') << std::hex << blue;
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, (bIsRGBW == true) ? V_RGBW : V_RGB, sstr.str(), pChild->useAck, pChild->ackTimeout);
}
else if (pLed->command == Limitless_SetColorToWhite)
{
std::stringstream sstr;
int Brightness = 100;
int wWhite = round((255.0f / 100.0f)*float(Brightness));
if (!bIsRGBW)
{
sstr << std::setw(2) << std::uppercase << std::hex << std::setfill('0') << std::hex << wWhite
<< std::setw(2) << std::uppercase << std::hex << std::setfill('0') << std::hex << wWhite
<< std::setw(2) << std::uppercase << std::hex << std::setfill('0') << std::hex << wWhite;
}
else
{
sstr << "#000000"
<< std::setw(2) << std::uppercase << std::hex << std::setfill('0') << std::hex << wWhite;
}
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, (bIsRGBW == true) ? V_RGBW : V_RGB, sstr.str(), pChild->useAck, pChild->ackTimeout);
}
else if (pLed->command == Limitless_SetBrightnessLevel)
{
float fvalue = pLed->value;
int svalue = round(fvalue);
if (svalue > 100)
svalue = 100;
std::stringstream sstr;
sstr << svalue;
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_PERCENTAGE, sstr.str(), pChild->useAck, pChild->ackTimeout);
}
else if ((pLed->command == Limitless_LedOff) || (pLed->command == Limitless_LedOn))
{
std::string lState = (pLed->command == Limitless_LedOn) ? "1" : "0";
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_STATUS, lState, pChild->useAck, pChild->ackTimeout);
}
}
else
{
_log.Log(LOG_ERROR, "MySensors: Light command received for unknown node_id: %d", node_id);
return false;
}
}
else if (packettype == pTypeBlinds)
{
//Blinds/Window command
int node_id = pCmd->BLINDS1.id3;
int child_sensor_id = pCmd->BLINDS1.unitcode;
if (_tMySensorNode *pNode = FindNode(node_id))
{
_tMySensorChild *pChild = pNode->FindChild(child_sensor_id);
if (!pChild)
{
_log.Log(LOG_ERROR, "MySensors: Light command received for unknown node_id: %d, child_id: %d", node_id, child_sensor_id);
return false;
}
if (pCmd->BLINDS1.cmnd == blinds_sOpen)
{
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_UP, "", pChild->useAck, pChild->ackTimeout);
}
else if (pCmd->BLINDS1.cmnd == blinds_sClose)
{
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_DOWN, "", pChild->useAck, pChild->ackTimeout);
}
else if (pCmd->BLINDS1.cmnd == blinds_sStop)
{
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, V_STOP, "", pChild->useAck, pChild->ackTimeout);
}
}
else {
_log.Log(LOG_ERROR, "MySensors: Blinds/Window command received for unknown node_id: %d", node_id);
return false;
}
}
else if ((packettype == pTypeThermostat) && (subtype == sTypeThermSetpoint))
{
//Set Point
const _tThermostat *pMeter = reinterpret_cast<const _tThermostat *>(pCmd);
int node_id = pMeter->id2;
int child_sensor_id = pMeter->id3;
_eSetType vtype_id = (_eSetType)pMeter->id4;
if (_tMySensorNode *pNode = FindNode(node_id))
{
_tMySensorChild *pChild = pNode->FindChild(child_sensor_id);
if (!pChild)
{
_log.Log(LOG_ERROR, "MySensors: Light command received for unknown node_id: %d, child_id: %d", node_id, child_sensor_id);
return false;
}
char szTmp[10];
sprintf(szTmp, "%.1f", pMeter->temp);
return SendNodeSetCommand(node_id, child_sensor_id, MT_Set, vtype_id, szTmp, pChild->useAck, pChild->ackTimeout);
}
else {
_log.Log(LOG_ERROR, "MySensors: Blinds/Window command received for unknown node_id: %d", node_id);
return false;
}
}
else if (packettype == pTypeGeneralSwitch)
{
//Used to store IR codes
const _tGeneralSwitch *pSwitch= reinterpret_cast<const _tGeneralSwitch *>(pCmd);
int node_id = pSwitch->unitcode;
unsigned int ir_code = pSwitch->id;
if (_tMySensorNode *pNode = FindNode(node_id))
{
_tMySensorChild* pChild = pNode->FindChildByValueType(V_IR_RECEIVE);
if (pChild)
{
std::stringstream sstr;
sstr << ir_code;
return SendNodeSetCommand(node_id, pChild->childID, MT_Set, V_IR_SEND, sstr.str(), pChild->useAck, pChild->ackTimeout);
}
}
else {
_log.Log(LOG_ERROR, "MySensors: Blinds/Window command received for unknown node_id: %d", node_id);
return false;
}
}
else
{
_log.Log(LOG_ERROR, "MySensors: Unknown action received");
return false;
}
return true;
}```