void Meteostick::SendSoilMoistureSensor(const unsigned char Idx, const unsigned char Channel, const int Moisture, const std::string &defaultname) { bool bDeviceExits = true; int finalID = (Idx * 10) + Channel; SendMoistureSensor(finalID,255, Moisture, defaultname); }
bool CDavisLoggerSerial::HandleLoopData(const unsigned char *data, size_t len) { const uint8_t *pData=data+1; #ifndef DEBUG_DAVIS if (len!=100) return false; if ( (data[1]!='L')|| (data[2]!='O')|| (data[3]!='O')|| (data[96]!=0x0a)|| (data[97]!=0x0d) ) return false; //bool bIsRevA = (data[4]=='P'); #else // FILE *fOut=fopen("davisrob.bin","wb+"); // fwrite(data,1,len,fOut); // fclose(fOut); unsigned char szBuffer[200]; FILE *fIn=fopen("E:\\davis2.bin","rb+"); //FILE *fIn=fopen("davisrob.bin","rb+"); fread(&szBuffer,1,100,fIn); fclose(fIn); pData=szBuffer+1; bool bIsRevA(szBuffer[4]=='P'); #endif RBUF tsen; memset(&tsen,0,sizeof(RBUF)); unsigned char tempIdx=1; bool bBaroValid=false; float BaroMeter=0; bool bInsideTemperatureValid=false; float InsideTemperature=0; bool bInsideHumidityValid=false; int InsideHumidity=0; bool bOutsideTemperatureValid=false; float OutsideTemperature=0; bool bOutsideHumidityValid=false; int OutsideHumidity=0; bool bWindDirectionValid=false; int WindDirection=0; bool bWindSpeedValid=false; float WindSpeed=0; bool bWindSpeedAVR10Valid=false; float WindSpeedAVR10=0; bool bUVValid=false; float UV=0; //Barometer if ((pData[7]!=0xFF)&&(pData[8]!=0xFF)) { bBaroValid=true; BaroMeter=((unsigned int)((pData[8] << 8) | pData[7])) / 29.53f; //in hPa } //Inside Temperature if ((pData[9]!=0xFF)||(pData[10]!=0x7F)) { bInsideTemperatureValid=true; InsideTemperature=((unsigned int)((pData[10] << 8) | pData[9])) / 10.f; InsideTemperature = (InsideTemperature - 32.0f) * 5.0f / 9.0f; } //Inside Humidity if (pData[11]!=0xFF) { InsideHumidity=pData[11]; if (InsideHumidity<101) bInsideHumidityValid=true; } if (bBaroValid&&bInsideTemperatureValid&&bInsideHumidityValid) { uint8_t forecastitem = pData[89]; int forecast = 0; if ((forecastitem & 0x01) == 0x01) forecast = wsbaroforcast_rain; else if ((forecastitem & 0x02) == 0x02) forecast = wsbaroforcast_cloudy; else if ((forecastitem & 0x04) == 0x04) forecast = wsbaroforcast_some_clouds; else if ((forecastitem & 0x08) == 0x08) forecast = wsbaroforcast_sunny; else if ((forecastitem & 0x10) == 0x10) forecast = wsbaroforcast_snow; SendTempHumBaroSensorFloat(tempIdx++, 255, InsideTemperature, InsideHumidity, BaroMeter, forecast, "THB"); } //Outside Temperature if ((pData[12]!=0xFF)||(pData[13]!=0x7F)) { bOutsideTemperatureValid=true; OutsideTemperature=((unsigned int)((pData[13] << 8) | pData[12])) / 10.f; OutsideTemperature = (OutsideTemperature - 32.0f) * 5.0f / 9.0f; } //Outside Humidity if (pData[33]!=0xFF) { OutsideHumidity=pData[33]; if (OutsideHumidity<101) bOutsideHumidityValid=true; } if (bOutsideTemperatureValid||bOutsideHumidityValid) { if ((bOutsideTemperatureValid)&&(bOutsideHumidityValid)) { //Temp+hum SendTempHumSensor(tempIdx++, 255, OutsideTemperature, OutsideHumidity,"Outside TempHum"); } else if (bOutsideTemperatureValid) { //Temp SendTempSensor(tempIdx++, 255, OutsideTemperature, "Outside Temp"); } else if (bOutsideHumidityValid) { //hum SendHumiditySensor(tempIdx++, 255, OutsideHumidity, "Outside Humidity"); } } tempIdx=10; //Add Extra Temp/Hum Sensors int iTmp; for (int iTmp=0; iTmp<7; iTmp++) { bool bTempValid=false; bool bHumValid=false; float temp=0; uint8_t hum=0; if (pData[18+iTmp]!=0xFF) { bTempValid=true; temp=pData[18+iTmp]-90.0f; temp = (temp - 32.0f) * 5.0f / 9.0f; } if (pData[34+iTmp]!=0xFF) { bHumValid=true; hum=pData[34+iTmp]; } if ((bTempValid)&&(bHumValid)) { //Temp+hum SendTempHumSensor(tempIdx++, 255, temp, hum, "Extra TempHum"); } else if (bTempValid) { //Temp SendTempSensor(tempIdx++, 255, temp, "Extra Temp"); } else if (bHumValid) { //hum SendHumiditySensor(tempIdx++, 255, hum, "Extra Humidity"); } } tempIdx=20; //Add Extra Soil Temp Sensors for (iTmp=0; iTmp<4; iTmp++) { bool bTempValid=false; float temp=0; if (pData[25+iTmp]!=0xFF) { bTempValid=true; temp=pData[25+iTmp]-90.0f; temp = (temp - 32.0f) * 5.0f / 9.0f; } if (bTempValid) { SendTempSensor(tempIdx++, 255, temp, "Soil Temp"); } } tempIdx=30; //Add Extra Leaf Temp Sensors for (iTmp=0; iTmp<4; iTmp++) { bool bTempValid=false; float temp=0; if (pData[29+iTmp]!=0xFF) { bTempValid=true; temp=pData[29+iTmp]-90.0f; temp = (temp - 32.0f) * 5.0f / 9.0f; } if (bTempValid) { SendTempSensor(tempIdx++, 255, temp, "Leaf Temp"); } } //Wind Speed if (pData[14]!=0xFF) { bWindSpeedValid=true; WindSpeed=(pData[14])*(4.0f/9.0f); } //Wind Speed AVR 10 minutes if (pData[15]!=0xFF) { bWindSpeedAVR10Valid=true; WindSpeedAVR10=(pData[15])*(4.0f/9.0f); } //Wind Direction if ((pData[16]!=0xFF)&&(pData[17]!=0x7F)) { bWindDirectionValid=true; WindDirection=((unsigned int)((pData[17] << 8) | pData[16])); } if ((bWindSpeedValid)&&(bWindDirectionValid)) { memset(&tsen,0,sizeof(RBUF)); tsen.WIND.packetlength=sizeof(tsen.WIND)-1; tsen.WIND.packettype=pTypeWIND; tsen.WIND.subtype=sTypeWINDNoTemp; tsen.WIND.battery_level=9; tsen.WIND.rssi=12; tsen.WIND.id1=0; tsen.WIND.id2=1; int aw=round(WindDirection); tsen.WIND.directionh=(BYTE)(aw/256); aw-=(tsen.WIND.directionh*256); tsen.WIND.directionl=(BYTE)(aw); tsen.WIND.av_speedh=0; tsen.WIND.av_speedl=0; int sw=round(WindSpeed*10.0f); tsen.WIND.av_speedh=(BYTE)(sw/256); sw-=(tsen.WIND.av_speedh*256); tsen.WIND.av_speedl=(BYTE)(sw); tsen.WIND.gusth=0; tsen.WIND.gustl=0; //this is not correct, why no wind temperature? and only chill? tsen.WIND.chillh=0; tsen.WIND.chilll=0; tsen.WIND.temperatureh=0; tsen.WIND.temperaturel=0; if (bOutsideTemperatureValid) { tsen.WIND.tempsign=(OutsideTemperature>=0)?0:1; tsen.WIND.chillsign=(OutsideTemperature>=0)?0:1; int at10=round(abs(OutsideTemperature*10.0f)); tsen.WIND.temperatureh=(BYTE)(at10/256); tsen.WIND.chillh=(BYTE)(at10/256); at10-=(tsen.WIND.chillh*256); tsen.WIND.temperaturel=(BYTE)(at10); tsen.WIND.chilll=(BYTE)(at10); } sDecodeRXMessage(this, (const unsigned char *)&tsen.WIND, NULL, 255); } //UV if (pData[43]!=0xFF) { UV=(pData[43])/10.0f; if (UV<100) bUVValid=true; } if (bUVValid) { RBUF tsen; memset(&tsen,0,sizeof(RBUF)); tsen.UV.packetlength=sizeof(tsen.UV)-1; tsen.UV.packettype=pTypeUV; tsen.UV.subtype=sTypeUV1; tsen.UV.battery_level=9; tsen.UV.rssi=12; tsen.UV.id1=0; tsen.UV.id2=1; tsen.UV.uv=(BYTE)round(UV*10); sDecodeRXMessage(this, (const unsigned char *)&tsen.UV, NULL, 255); } //Rain Rate if ((pData[41]!=0xFF)&&(pData[42]!=0xFF)) { float rainRate=((unsigned int)((pData[42] << 8) | pData[41])) / 100.0f; //inches rainRate*=25.4f; //mm } //Rain Day if ((pData[50]!=0xFF)&&(pData[51]!=0xFF)) { float rainDay=((unsigned int)((pData[51] << 8) | pData[50])) / 100.0f; //inches rainDay*=25.4f; //mm } //Rain Year if ((pData[54]!=0xFF)&&(pData[55]!=0xFF)) { float rainYear=((unsigned int)((pData[55] << 8) | pData[54])) / 100.0f; //inches rainYear*=25.4f; //mm SendRainSensor(1, 255, rainYear, "Rain"); } //Solar Radiation if ((pData[44]!=0xFF)&&(pData[45]!=0x7F)) { unsigned int solarRadiation=((unsigned int)((pData[45] << 8) | pData[44]));//Watt/M2 _tGeneralDevice gdevice; gdevice.subtype=sTypeSolarRadiation; gdevice.floatval1=float(solarRadiation); sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255); } //Soil Moistures for (int iMoister=0; iMoister<4; iMoister++) { if (pData[62+iMoister]!=0xFF) { int moister=pData[62+iMoister]; SendMoistureSensor(1 + iMoister, 255, moister, "Moisture"); } } //Leaf Wetness for (int iLeaf=0; iLeaf<4; iLeaf++) { if (pData[66+iLeaf]!=0xFF) { int leaf_wetness=pData[66+iLeaf]; _tGeneralDevice gdevice; gdevice.subtype=sTypeLeafWetness; gdevice.intval1=leaf_wetness; gdevice.id=1+iLeaf; sDecodeRXMessage(this, (const unsigned char *)&gdevice, NULL, 255); } } return true; }
void MySensorsBase::SendSensor2Domoticz(_tMySensorNode *pNode, _tMySensorChild *pChild, const _eSetType vType) { m_iLastSendNodeBatteryValue = 255; if (pChild->hasBattery) { m_iLastSendNodeBatteryValue = pChild->batValue; } int cNode = (pChild->nodeID << 8) | pChild->childID; int intValue; float floatValue; std::string stringValue; switch (vType) { case V_TEMP: { float Temp = 0; pChild->GetValue(V_TEMP, Temp); _tMySensorChild *pChildHum = FindChildWithValueType(pChild->nodeID, V_HUM); _tMySensorChild *pChildBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE); if (pChildHum && pChildBaro) { int Humidity; float Baro; bool bHaveHumidity = pChildHum->GetValue(V_HUM, Humidity); bool bHaveBaro = pChildBaro->GetValue(V_PRESSURE, Baro); if (bHaveHumidity && bHaveBaro) { int forecast = bmpbaroforecast_unknown; _tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST); if (pSensorForecast) { pSensorForecast->GetValue(V_FORECAST, forecast); } if (forecast == bmpbaroforecast_cloudy) { if (Baro < 1010) forecast = bmpbaroforecast_rain; } //We are using the TempHumBaro Float type now, convert the forecast int nforecast = wsbaroforcast_some_clouds; if (Baro <= 980) nforecast = wsbaroforcast_heavy_rain; else if (Baro <= 995) { if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } else if (Baro >= 1029) nforecast = wsbaroforcast_sunny; switch (forecast) { case bmpbaroforecast_sunny: nforecast = wsbaroforcast_sunny; break; case bmpbaroforecast_cloudy: nforecast = wsbaroforcast_cloudy; break; case bmpbaroforecast_thunderstorm: nforecast = wsbaroforcast_heavy_rain; break; case bmpbaroforecast_rain: if (Temp>1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } SendTempHumBaroSensorFloat(cNode, pChild->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro"); } } else if (pChildHum) { int Humidity; bool bHaveHumidity = pChildHum->GetValue(V_HUM, Humidity); if (bHaveHumidity) { SendTempHumSensor(cNode, pChild->batValue, Temp, Humidity, (!pChild->childName.empty()) ? pChild->childName : "TempHum"); } } else { SendTempSensor(cNode, pChild->batValue, Temp, (!pChild->childName.empty()) ? pChild->childName : "Temp"); } } break; case V_HUM: { _tMySensorChild *pChildTemp = FindChildWithValueType(pChild->nodeID, V_TEMP); _tMySensorChild *pChildBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE); int forecast = bmpbaroforecast_unknown; _tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST); if (pSensorForecast) { pSensorForecast->GetValue(V_FORECAST, forecast); } if (forecast == bmpbaroforecast_cloudy) { if (pChildBaro) { float Baro; if (pChildBaro->GetValue(V_PRESSURE, Baro)) { if (Baro < 1010) forecast = bmpbaroforecast_rain; } } } float Temp; float Baro; int Humidity; pChild->GetValue(V_HUM, Humidity); if (pChildTemp && pChildBaro) { bool bHaveTemp = pChildTemp->GetValue(V_TEMP, Temp); bool bHaveBaro = pChildBaro->GetValue(V_PRESSURE, Baro); if (bHaveTemp && bHaveBaro) { cNode = (pChildTemp->nodeID << 8) | pChildTemp->childID; //We are using the TempHumBaro Float type now, convert the forecast int nforecast = wsbaroforcast_some_clouds; if (Baro <= 980) nforecast = wsbaroforcast_heavy_rain; else if (Baro <= 995) { if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } else if (Baro >= 1029) nforecast = wsbaroforcast_sunny; switch (forecast) { case bmpbaroforecast_sunny: nforecast = wsbaroforcast_sunny; break; case bmpbaroforecast_cloudy: nforecast = wsbaroforcast_cloudy; break; case bmpbaroforecast_thunderstorm: nforecast = wsbaroforcast_heavy_rain; break; case bmpbaroforecast_rain: if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } SendTempHumBaroSensorFloat(cNode, pChildTemp->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro"); } } else if (pChildTemp) { bool bHaveTemp = pChildTemp->GetValue(V_TEMP, Temp); if (bHaveTemp) { cNode = (pChildTemp->nodeID << 8) | pChildTemp->childID; SendTempHumSensor(cNode, pChildTemp->batValue, Temp, Humidity, (!pChild->childName.empty()) ? pChild->childName : "TempHum"); } } else { SendHumiditySensor(cNode, pChild->batValue, Humidity); } } break; case V_PRESSURE: { float Baro; pChild->GetValue(V_PRESSURE, Baro); _tMySensorChild *pSensorTemp = FindChildWithValueType(pChild->nodeID, V_TEMP); _tMySensorChild *pSensorHum = FindChildWithValueType(pChild->nodeID, V_HUM); int forecast = bmpbaroforecast_unknown; _tMySensorChild *pSensorForecast = FindChildWithValueType(pChild->nodeID, V_FORECAST); if (pSensorForecast) { pSensorForecast->GetValue(V_FORECAST, forecast); } if (forecast == bmpbaroforecast_cloudy) { if (Baro < 1010) forecast = bmpbaroforecast_rain; } if (pSensorTemp && pSensorHum) { float Temp; int Humidity; bool bHaveTemp = pSensorTemp->GetValue(V_TEMP, Temp); bool bHaveHumidity = pSensorHum->GetValue(V_HUM, Humidity); if (bHaveTemp && bHaveHumidity) { cNode = (pSensorTemp->nodeID << 8) | pSensorTemp->childID; //We are using the TempHumBaro Float type now, convert the forecast int nforecast = wsbaroforcast_some_clouds; if (Baro <= 980) nforecast = wsbaroforcast_heavy_rain; else if (Baro <= 995) { if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } else if (Baro >= 1029) nforecast = wsbaroforcast_sunny; switch (forecast) { case bmpbaroforecast_sunny: nforecast = wsbaroforcast_sunny; break; case bmpbaroforecast_cloudy: nforecast = wsbaroforcast_cloudy; break; case bmpbaroforecast_thunderstorm: nforecast = wsbaroforcast_heavy_rain; break; case bmpbaroforecast_rain: if (Temp > 1) nforecast = wsbaroforcast_rain; else nforecast = wsbaroforcast_snow; break; } SendTempHumBaroSensorFloat(cNode, pSensorTemp->batValue, Temp, Humidity, Baro, nforecast, (!pChild->childName.empty()) ? pChild->childName : "TempHumBaro"); } } else SendBaroSensor(pChild->nodeID, pChild->childID, pChild->batValue, Baro, forecast); } break; case V_TRIPPED: // Tripped status of a security sensor. 1 = Tripped, 0 = Untripped if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, (!pChild->childName.empty()) ? pChild->childName : "Security Sensor"); break; case V_ARMED: //Armed status of a security sensor. 1 = Armed, 0 = Bypassed if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, (!pChild->childName.empty()) ? pChild->childName : "Security Sensor"); break; case V_LOCK_STATUS: //Lock status. 1 = Locked, 0 = Unlocked if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID, (intValue == 1), 100, (!pChild->childName.empty()) ? pChild->childName : "Lock Sensor"); break; case V_STATUS: // Light status. 0 = off 1 = on if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID, (intValue != 0), 100, (!pChild->childName.empty()) ? pChild->childName : "Light"); break; case V_SCENE_ON: if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID + intValue, true, 100, (!pChild->childName.empty()) ? pChild->childName : "Scene"); break; case V_SCENE_OFF: if (pChild->GetValue(vType, intValue)) UpdateSwitch(pChild->nodeID, pChild->childID + intValue, false, 100, (!pChild->childName.empty()) ? pChild->childName : "Scene"); break; case V_PERCENTAGE: // Dimmer value. 0 - 100 % if (pChild->GetValue(vType, intValue)) { int level = intValue; UpdateSwitch(pChild->nodeID, pChild->childID, (level != 0), level, (!pChild->childName.empty()) ? pChild->childName : "Light"); } break; case V_RGB: //RRGGBB if (pChild->GetValue(vType, intValue)) SendRGBWSwitch(pChild->nodeID, pChild->childID, pChild->batValue, intValue, false, (!pChild->childName.empty()) ? pChild->childName : "RGB Light"); break; case V_RGBW: //RRGGBBWW if (pChild->GetValue(vType, intValue)) SendRGBWSwitch(pChild->nodeID, pChild->childID, pChild->batValue, intValue, true, (!pChild->childName.empty()) ? pChild->childName : "RGBW Light"); break; case V_UP: case V_DOWN: case V_STOP: if (pChild->GetValue(vType, intValue)) SendBlindSensor(pChild->nodeID, pChild->childID, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Blinds/Window"); break; case V_LIGHT_LEVEL: if (pChild->GetValue(vType, floatValue)) { _tLightMeter lmeter; lmeter.id1 = 0; lmeter.id2 = 0; lmeter.id3 = 0; lmeter.id4 = pChild->nodeID; lmeter.dunit = pChild->childID; lmeter.fLux = floatValue; lmeter.battery_level = pChild->batValue; if (pChild->hasBattery) lmeter.battery_level = pChild->batValue; sDecodeRXMessage(this, (const unsigned char *)&lmeter); } break; case V_LEVEL: if (pChild->GetValue(vType, intValue)) { if (pChild->presType == S_DUST) { SendAirQualitySensor(pChild->nodeID, pChild->childID, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Dust"); } else if (pChild->presType == S_AIR_QUALITY) { SendAirQualitySensor(pChild->nodeID, pChild->childID, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Air Quality"); } else if (pChild->presType == S_LIGHT_LEVEL) { SendLuxSensor(pChild->nodeID, pChild->childID, pChild->batValue, (float)intValue, (!pChild->childName.empty()) ? pChild->childName : "Lux"); } else if (pChild->presType == S_SOUND) { SendSoundSensor(cNode, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Sound Level"); } else if (pChild->presType == S_MOISTURE) { SendMoistureSensor(cNode, pChild->batValue, intValue, (!pChild->childName.empty()) ? pChild->childName : "Moisture"); } } break; case V_RAIN: if (pChild->GetValue(vType, floatValue)) SendRainSensor(cNode, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Rain"); break; case V_WATT: { if (pChild->GetValue(vType, floatValue)) { _tMySensorChild *pSensorKwh = pNode->FindChildWithValueType(pChild->childID, V_KWH);// FindChildWithValueType(pChild->nodeID, V_KWH); if (pSensorKwh) { float Kwh; if (pSensorKwh->GetValue(V_KWH, Kwh)) SendKwhMeter(pSensorKwh->nodeID, pSensorKwh->childID, pSensorKwh->batValue, floatValue, Kwh, (!pChild->childName.empty()) ? pChild->childName : "Meter"); } else { SendWattMeter(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Usage"); } } } break; case V_KWH: if (pChild->GetValue(vType, floatValue)) { _tMySensorChild *pSensorWatt = pNode->FindChildWithValueType(pChild->childID, V_WATT);// FindChildWithValueType(pChild->nodeID, V_WATT); if (pSensorWatt) { float Watt; if (pSensorWatt->GetValue(V_WATT, Watt)) SendKwhMeter(pChild->nodeID, pChild->childID, pChild->batValue, Watt, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Meter"); } else { SendKwhMeter(pChild->nodeID, pChild->childID, pChild->batValue, 0, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Meter"); } } break; case V_DISTANCE: if (pChild->GetValue(vType, floatValue)) SendDistanceSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Distance"); break; case V_FLOW: //Flow of water/gas in meter (for now send as a percentage sensor) if (pChild->GetValue(vType, floatValue)) SendPercentageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Water Flow"); break; case V_VOLUME: //Water or Gas Volume if (pChild->GetValue(vType, floatValue)) { if (pChild->presType == S_WATER) SendMeterSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Water"); else SendMeterSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Gas"); } break; case V_VOLTAGE: if (pChild->GetValue(vType, floatValue)) SendVoltageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Voltage"); break; case V_UV: if (pChild->GetValue(vType, floatValue)) SendUVSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "UV"); break; case V_IMPEDANCE: if (pChild->GetValue(vType, floatValue)) SendPercentageSensor(pChild->nodeID, pChild->childID, pChild->batValue, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Impedance"); break; case V_WEIGHT: if (pChild->GetValue(vType, floatValue)) { while (1 == 0); } break; case V_CURRENT: if (pChild->GetValue(vType, floatValue)) SendCurrentSensor(cNode, pChild->batValue, floatValue, 0, 0, (!pChild->childName.empty()) ? pChild->childName : "Current"); break; case V_FORECAST: if (pChild->GetValue(vType, intValue)) { _tMySensorChild *pSensorBaro = FindChildWithValueType(pChild->nodeID, V_PRESSURE); if (pSensorBaro) { float Baro; if (pSensorBaro->GetValue(V_PRESSURE, Baro)) { int forecast = intValue; if (forecast == bmpbaroforecast_cloudy) { if (Baro < 1010) forecast = bmpbaroforecast_rain; } SendBaroSensor(pSensorBaro->nodeID, pSensorBaro->childID, pSensorBaro->batValue, Baro, forecast); } } else { if (pChild->GetValue(V_FORECAST, stringValue)) { std::stringstream sstr; sstr << pChild->nodeID; std::string devname = (!pChild->childName.empty()) ? pChild->childName : "Forecast"; m_sql.UpdateValue(m_HwdID, sstr.str().c_str(), pChild->childID, pTypeGeneral, sTypeTextStatus, 12, pChild->batValue, 0, stringValue.c_str(), devname); } } } break; case V_WIND: case V_GUST: case V_DIRECTION: MakeAndSendWindSensor(pChild->nodeID, (!pChild->childName.empty()) ? pChild->childName : "Wind"); break; case V_HVAC_SETPOINT_HEAT: if (pChild->GetValue(vType, floatValue)) SendSetPointSensor(pNode->nodeID, pChild->childID, (unsigned char)vType, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Setpoint Heat"); break; case V_HVAC_SETPOINT_COOL: if (pChild->GetValue(vType, floatValue)) SendSetPointSensor(pNode->nodeID, pChild->childID, (unsigned char)vType, floatValue, (!pChild->childName.empty()) ? pChild->childName : "Setpoint Cool"); break; case V_TEXT: if (pChild->GetValue(vType, stringValue)) { SendTextSensor(pNode->nodeID, pChild->childID, pChild->batValue, stringValue, (!pChild->childName.empty()) ? pChild->childName : "Text Sensor"); } break; case V_IR_RECEIVE: if (pChild->GetValue(vType, intValue)) { _tGeneralSwitch gswitch; gswitch.subtype = sSwitchTypeMDREMOTE; gswitch.id = intValue; gswitch.unitcode = pNode->nodeID; gswitch.cmnd = gswitch_sOn; gswitch.level = 100; gswitch.battery_level = pChild->batValue; gswitch.rssi = 12; gswitch.seqnbr = 0; sDecodeRXMessage(this, (const unsigned char *)&gswitch); } break; } }