1 #include "stdafx.h"
2 #include "RFXNames.h"
3 #include "RFXtrx.h"
4 #include "../hardware/EvohomeBase.h"
5 #include "../hardware/hardwaretypes.h"
6 #include "Helper.h"
7 #include "Logger.h"
8 
9 typedef struct _STR_TABLE_SINGLE {
10 	unsigned long    id;
11 	const char* str1;
12 	const char* str2;
13 } STR_TABLE_SINGLE;
14 
15 typedef struct _STR_TABLE_ID1_ID2 {
16 	unsigned long    id1;
17 	unsigned long    id2;
18 	const char* str1;
19 } STR_TABLE_ID1_ID2;
20 
findTableIDSingle1(const STR_TABLE_SINGLE * t,const unsigned long id)21 const char* findTableIDSingle1(const STR_TABLE_SINGLE* t, const unsigned long id)
22 {
23 	while (t->str1) {
24 		if (t->id == id)
25 			return t->str1;
26 		t++;
27 	}
28 	return "Unknown";
29 }
30 
findTableIDSingle2(const STR_TABLE_SINGLE * t,const unsigned long id)31 const char* findTableIDSingle2(const STR_TABLE_SINGLE* t, const unsigned long id)
32 {
33 	while (t->str2) {
34 		if (t->id == id)
35 			return t->str2;
36 		t++;
37 	}
38 	return "Unknown";
39 }
40 
findTableID1ID2(const _STR_TABLE_ID1_ID2 * t,const unsigned long id1,const unsigned long id2)41 const char* findTableID1ID2(const _STR_TABLE_ID1_ID2* t, const unsigned long id1, const unsigned long id2)
42 {
43 	while (t->str1) {
44 		if ((t->id1 == id1) && (t->id2 == id2))
45 			return t->str1;
46 		t++;
47 	}
48 	return "Unknown";
49 }
50 
RFX_Humidity_Status_Desc(const unsigned char status)51 const char* RFX_Humidity_Status_Desc(const unsigned char status)
52 {
53 	static const STR_TABLE_SINGLE	Table[] =
54 	{
55 		{ humstat_normal, "Normal" },
56 		{ humstat_comfort, "Comfortable" },
57 		{ humstat_dry, "Dry" },
58 		{ humstat_wet, "Wet" },
59 		{ 0,NULL,NULL }
60 	};
61 	return findTableIDSingle1(Table, status);
62 }
63 
Get_Humidity_Level(const unsigned char hlevel)64 unsigned char Get_Humidity_Level(const unsigned char hlevel)
65 {
66 	if (hlevel < 25)
67 		return humstat_dry;
68 	if (hlevel > 60)
69 		return humstat_wet;
70 	if ((hlevel >= 25) && (hlevel <= 60))
71 		return humstat_comfort;
72 	return humstat_normal;
73 }
74 
Security_Status_Desc(const unsigned char status)75 const char* Security_Status_Desc(const unsigned char status)
76 {
77 	static const STR_TABLE_SINGLE	Table[] =
78 	{
79 		{ sStatusNormal, "Normal" },
80 	{ sStatusNormalDelayed, "Normal Delayed" },
81 	{ sStatusAlarm, "Alarm" },
82 	{ sStatusAlarmDelayed, "Alarm Delayed" },
83 	{ sStatusMotion, "Motion" },
84 	{ sStatusNoMotion, "No Motion" },
85 	{ sStatusPanic, "Panic" },
86 	{ sStatusPanicOff, "Panic End" },
87 	{ sStatusArmAway, "Arm Away" },
88 	{ sStatusArmAwayDelayed, "Arm Away Delayed" },
89 	{ sStatusArmHome, "Arm Home" },
90 	{ sStatusArmHomeDelayed, "Arm Home Delayed" },
91 	{ sStatusDisarm, "Disarm" },
92 	{ sStatusLightOff, "Light Off" },
93 	{ sStatusLightOn, "Light On" },
94 	{ sStatusLight2Off, "Light 2 Off" },
95 	{ sStatusLight2On, "Light 2 On" },
96 	{ sStatusDark, "Dark detected" },
97 	{ sStatusLight, "Light Detected" },
98 	{ sStatusBatLow, "Battery low MS10 or XX18 sensor" },
99 	{ sStatusPairKD101, "Pair KD101" },
100 	{ sStatusNormalTamper, "Normal + Tamper" },
101 	{ sStatusNormalDelayedTamper, "Normal Delayed + Tamper" },
102 	{ sStatusAlarmTamper, "Alarm + Tamper" },
103 	{ sStatusAlarmDelayedTamper, "Alarm Delayed + Tamper" },
104 	{ sStatusMotionTamper, "Motion + Tamper" },
105 	{ sStatusNoMotionTamper, "No Motion + Tamper" },
106 	{ 0, NULL }
107 	};
108 	return findTableIDSingle1(Table, status);
109 }
110 
Timer_Type_Desc(const int tType)111 const char* Timer_Type_Desc(const int tType)
112 {
113 	static const STR_TABLE_SINGLE	Table[] =
114 	{
115 		{ TTYPE_BEFORESUNRISE, "Before Sunrise" },
116 	{ TTYPE_AFTERSUNRISE, "After Sunrise" },
117 	{ TTYPE_ONTIME, "On Time" },
118 	{ TTYPE_BEFORESUNSET, "Before Sunset" },
119 	{ TTYPE_AFTERSUNSET, "After Sunset" },
120 	{ TTYPE_FIXEDDATETIME, "Fixed Date/Time" },
121 	{ TTYPE_DAYSODD, "Odd Day Numbers" },
122 	{ TTYPE_DAYSEVEN, "Even Day Numbers" },
123 	{ TTYPE_WEEKSODD, "Odd Week Numbers" },
124 	{ TTYPE_WEEKSEVEN, "Even Week Numbers" },
125 	{ TTYPE_MONTHLY, "Monthly" },
126 	{ TTYPE_MONTHLY_WD, "Monthly (Weekday)" },
127 	{ TTYPE_YEARLY, "Yearly" },
128 	{ TTYPE_YEARLY_WD, "Yearly (Weekday)" },
129 	{ TTYPE_BEFORESUNATSOUTH, "Before Sun at South" },
130 	{ TTYPE_AFTERSUNATSOUTH, "After Sun at South" },
131 	{ TTYPE_BEFORECIVTWSTART, "Before Civil Twilight Start" },
132 	{ TTYPE_AFTERCIVTWSTART, "After Civil Twilight Start" },
133 	{ TTYPE_BEFORECIVTWEND, "Before Civil Twilight End" },
134 	{ TTYPE_AFTERCIVTWEND, "After Civil Twilight End" },
135 	{ TTYPE_BEFORENAUTTWSTART, "Before Nautical Twilight Start" },
136 	{ TTYPE_AFTERNAUTTWSTART, "After Nautical Twilight Start" },
137 	{ TTYPE_BEFORENAUTTWEND, "Before Nautical Twilight End" },
138 	{ TTYPE_AFTERNAUTTWEND, "After Nautical Twilight End" },
139 	{ TTYPE_BEFOREASTTWSTART, "Before Astronomical Twilight Start" },
140 	{ TTYPE_AFTERASTTWSTART, "After Astronomical Twilight Start" },
141 	{ TTYPE_BEFOREASTTWEND, "Before Astronomical Twilight End" },
142 	{ TTYPE_AFTERASTTWEND, "After Astronomical Twilight End" },
143 	{ 0,NULL,NULL }
144 	};
145 	return findTableIDSingle1(Table, tType);
146 }
147 
Timer_Cmd_Desc(const int tType)148 const char* Timer_Cmd_Desc(const int tType)
149 {
150 	static const STR_TABLE_SINGLE	Table[] =
151 	{
152 		{ TCMD_ON, "On" },
153 	{ TCMD_OFF, "Off" },
154 	{ 0,NULL,NULL }
155 	};
156 	return findTableIDSingle1(Table, tType);
157 }
158 
159 //ID, Long description, short description
160 static const STR_TABLE_SINGLE	HardwareTypeTable[] =
161 {
162 	{ HTYPE_RFXtrx315, "RFXCOM - RFXtrx315 USB 315MHz Transceiver",					"RFXCOM" },
163 	{ HTYPE_RFXtrx433, "RFXCOM - RFXtrx433 USB 433.92MHz Transceiver",				"RFXCOM" },
164 	{ HTYPE_RFXLAN, "RFXCOM - RFXtrx shared over LAN interface",					"RFXCOM" },
165 	{ HTYPE_Domoticz, "Domoticz - Remote Server",									"Domoticz Remote" },
166 	{ HTYPE_P1SmartMeter, "P1 Smart Meter USB",										"P1 Meter" },
167 	{ HTYPE_P1SmartMeterLAN, "P1 Smart Meter with LAN interface",					"P1 Meter" },
168 	{ HTYPE_YouLess, "YouLess Meter with LAN interface",							"YouLess" },
169 	{ HTYPE_WINDDELEN, "Winddelen",													"Winddelen" },
170 	{ HTYPE_TE923, "TE923 USB Compatible Weather Station",							"TE923" },
171 	{ HTYPE_Rego6XX, "Rego 6XX USB/serial interface",								"Rego_6XX" },
172 	{ HTYPE_TTN_MQTT, "The Things Network (MQTT/CayenneLPP) with LAN interface",	"TTN_MQTT" },
173 	{ HTYPE_DavisVantage, "Davis Vantage Weather Station USB",						"Davis" },
174 	{ HTYPE_VOLCRAFTCO20, "Volcraft CO-20 USB air quality sensor",					"Voltcraft" },
175 	{ HTYPE_1WIRE, "1-Wire (System)",												"1-Wire" },
176 	{ HTYPE_RaspberryBMP085, "I2C sensor BMP085/180 Temp+Baro",						"I2C BM" },
177 	{ HTYPE_Wunderground, "Weather Underground",									"WU" },
178 	{ HTYPE_DarkSky, "DarkSky (Weather Lookup)",									"Darksky" },
179 	{ HTYPE_Dummy, "Dummy (Does nothing, use for virtual switches only)",			"Dummy" },
180 	{ HTYPE_Tellstick, "Tellstick",													"Tellstick" },
181 	{ HTYPE_PiFace, "PiFace - Raspberry Pi IO expansion board",						"PiFace" },
182 	{ HTYPE_S0SmartMeterUSB, "S0 Meter USB",										"S0 Meter" },
183 	{ HTYPE_OpenThermGateway, "OpenTherm Gateway USB",								"OpenTherm" },
184 	{ HTYPE_TeleinfoMeter, "Teleinfo EDF",											"TeleInfo" },
185 	{ HTYPE_OpenThermGatewayTCP, "OpenTherm Gateway with LAN interface",			"OpenTherm" },
186 	{ HTYPE_OpenZWave, "OpenZWave USB",												"OpenZWave" },
187 	{ HTYPE_LimitlessLights, "Limitless/AppLamp/Mi Light with LAN/WiFi interface",	"Limitless" },
188 	{ HTYPE_System, "Motherboard sensors",											"HardwareMonitor" },
189 	{ HTYPE_EnOceanESP2, "EnOcean USB (ESP2)",										"EnOcean" },
190 	{ HTYPE_SolarEdgeTCP, "SolarEdge via LAN interface",							"SolarEdge" },
191 	{ HTYPE_SBFSpot, "SBFSpot (SMA)",												"SBFSpot" },
192 	{ HTYPE_ICYTHERMOSTAT, "ICY Thermostat",										"ICY" },
193 	{ HTYPE_WOL, "Wake-on-LAN",														"WOL" },
194 	{ HTYPE_PVOUTPUT_INPUT, "PVOutput (Input)",										"PVOutput" },
195 	{ HTYPE_EnOceanESP3, "EnOcean USB (ESP3)",										"EnOcean" },
196 	{ HTYPE_RaspberryGPIO, "Raspberry's GPIO port",									"GPIO" },
197 	{ HTYPE_Meteostick, "Meteostick USB",											"Meteostick" },
198 	{ HTYPE_TOONTHERMOSTAT, "Toon Thermostat",										"Toon" },
199 	{ HTYPE_ECODEVICES, "Eco Devices",												"Eco" },
200 	{ HTYPE_HARMONY_HUB, "Logitech Harmony Hub",									"Harmony" },
201 	{ HTYPE_Mochad, "Mochad CM15Pro/CM19A bridge with LAN interface",				"Mochad" },
202 	{ HTYPE_Philips_Hue, "Philips Hue Bridge",										"Philips Hue" },
203 	{ HTYPE_EVOHOME_SERIAL, "Evohome USB (for HGI/S80)",							"EvoHome" },
204 	{ HTYPE_EVOHOME_SCRIPT, "Evohome via script",									"EvoHome" },
205 	{ HTYPE_EVOHOME_WEB, "Evohome via Web API",										"EvoHome" },
206 	{ HTYPE_EVOHOME_TCP, "Evohome via LAN (remote HGI/S80)",						"EvoHome" },
207 	{ HTYPE_MySensorsUSB, "MySensors Gateway USB",									"MySensors" },
208 	{ HTYPE_MySensorsTCP, "MySensors Gateway with LAN interface",					"MySensors" },
209 	{ HTYPE_MySensorsMQTT, "MySensors Gateway with MQTT interface",					"MySensors" },
210 	{ HTYPE_MQTT, "MQTT Client Gateway with LAN interface",							"MQTT" },
211 	{ HTYPE_FRITZBOX, "Fritzbox Callmonitor via LAN interface",						"Fritzbox" },
212 	{ HTYPE_ETH8020, "ETH8020 Relay board with LAN interface",						"ETh8020" },
213 	{ HTYPE_RFLINKUSB, "RFLink Gateway USB",										"RFLink" },
214 	{ HTYPE_KMTronicUSB, "KMTronic Gateway USB",									"KMTronic" },
215 	{ HTYPE_KMTronicTCP, "KMTronic Gateway with LAN interface",						"KMTronic" },
216 	{ HTYPE_SOLARMAXTCP, "SolarMax via LAN interface",								"SolarMax" },
217 	{ HTYPE_KMTronic433, "KMTronic 433MHz Gateway USB",								"KMTronic" },
218 	{ HTYPE_Pinger, "System Alive Checker (Ping)",									"Pinger" },
219 	{ HTYPE_NEST, "Nest Thermostat/Protect",										"Nest" },
220 	{ HTYPE_Nest_OAuthAPI, "Nest Thermostat/Protect OAuth",							"Nest" },
221 	{ HTYPE_THERMOSMART, "Thermosmart Thermostat",									"ThermoSmart" },
222 	{ HTYPE_Netatmo, "Netatmo",														"Netatmo" },
223 	{ HTYPE_Kodi, "Kodi Media Server",												"Kodi" },
224 	{ HTYPE_PanasonicTV, "PanasonicTV",												"PanasonicTV" },
225 	{ HTYPE_ANNATHERMOSTAT, "Plugwise Anna Thermostat via LAN interface",			"Plugwise" },
226 	{ HTYPE_SatelIntegra, "Satel Integra via LAN interface",						"Satel Inegra" },
227 	{ HTYPE_LogitechMediaServer, "Logitech Media Server",							"Logitech Media Server" },
228 	{ HTYPE_RFXtrx868, "RFXCOM - RFXtrx868 USB 868MHz Transceiver",					"RFXCom 868" },
229 	{ HTYPE_RFLINKTCP, "RFLink Gateway with LAN interface",							"RFLink" },
230 	{ HTYPE_Comm5TCP, "Comm5 MA-5XXX with LAN interface",							"Comm5" },
231 	{ HTYPE_Comm5SMTCP, "Comm5 SM-XXXX with LAN interface",							"Comm5" },
232 	{ HTYPE_Comm5Serial, "Comm5 MA-4XXX/MI-XXXX Serial/USB interface",				"Comm5" },
233 	{ HTYPE_SolarEdgeAPI , "SolarEdge via Web API",									"SolarEdge" },
234 	{ HTYPE_CurrentCostMeter, "CurrentCost Meter USB",								"CurrentCost" },
235 	{ HTYPE_CurrentCostMeterLAN, "CurrentCost Meter with LAN interface",			"CurrentCost" },
236 	{ HTYPE_DomoticzInternal, "Domoticz Internal interface",						"Domoticz" },
237 	{ HTYPE_NefitEastLAN, "Nefit Easy HTTP server over LAN interface",				"Nefit" },
238 	{ HTYPE_OpenWebNetTCP, "MyHome OpenWebNet with LAN interface",					"MyHome" },
239 	{ HTYPE_RaspberryHTU21D, "I2C sensor HTU21D(F)/SI702x Temp+Humidity",			"I2C HTU21D" },
240 	{ HTYPE_AtagOne, "Atag One Thermostat",											"Atag" },
241 	{ HTYPE_Sterbox, "Sterbox v2-3 PLC with LAN interface",							"Sterbox" },
242 	{ HTYPE_HTTPPOLLER, "HTTP/HTTPS poller",										"HTTP(S) Poller" },
243 	{ HTYPE_RAVEn, "Rainforest RAVEn USB",											"Rainforest" },
244 	{ HTYPE_S0SmartMeterTCP, "S0 Meter with LAN interface",							"S0 Meter" },
245 	{ HTYPE_BuienRadar, "Buienradar (Dutch Weather Information)",					"BuienRadar" },
246 	{ HTYPE_AccuWeather, "AccuWeather (Weather Lookup)",							"AccuWeather" },
247 	{ HTYPE_Tesla, "Tesla Model S/3/X",												"Tesla" },
248 	{ HTYPE_BleBox, "BleBox devices",												"BleBox" },
249 	{ HTYPE_Ec3kMeterTCP, "Energy Count 3000/ NETBSEM4/ La Crosse RT-10 LAN",		"Ec3kMeter" },
250 	{ HTYPE_OpenWeatherMap, "Open Weather Map",										"OpenWeatherMap" },
251 	{ HTYPE_GoodweAPI, "Goodwe solar inverter via Web API",							"Goodwe" },
252 	{ HTYPE_RaspberryTSL2561, "I2C sensor TSL2561 Illuminance",						"I2C TSL2561" },
253 	{ HTYPE_Daikin, "Daikin Airconditioning with LAN (HTTP) interface",				"Daikin" },
254 	{ HTYPE_HEOS, "HEOS by DENON",													"HEOS" },
255 	{ HTYPE_MultiFun, "MultiFun LAN",												"Multifun" },
256 	{ HTYPE_ZIBLUEUSB, "ZiBlue RFPlayer USB",										"ZiBlue" },
257 	{ HTYPE_ZIBLUETCP, "ZiBlue RFPlayer with LAN interface",						"ZiBlue" },
258 	{ HTYPE_Yeelight, "YeeLight LED",												"YeeLight" },
259 	{ HTYPE_RaspberryPCF8574, "I2C sensor PIO 8bit expander PCF8574(A)",			"I2C PCF8574" },
260 	{ HTYPE_PythonPlugin, "Python Plugin System",									"Python Plugin System" },
261 	{ HTYPE_XiaomiGateway, "Xiaomi Gateway",										"Xiaomi" },
262 	{ HTYPE_RaspberryBME280, "I2C sensor BME280 Temp+Hum+Baro",						"I2C BME" },
263 	{ HTYPE_Arilux, "Arilux AL-LC0x",												"Arilux" },
264 	{ HTYPE_OpenWebNetUSB, "MyHome OpenWebNet USB",									"MyHome" },
265 	{ HTYPE_IntergasInComfortLAN2RF, "Intergas InComfort LAN2RF Gateway",			"InComfort" },
266 	{ HTYPE_RelayNet, "Relay-Net 8 channel LAN Relay and binary Input module",		"Relay-Net" },
267 	{ HTYPE_KMTronicUDP, "KMTronic Gateway with LAN/UDP interface",					"KMTronic" },
268 	{ HTYPE_SysfsGpio, "Generic sysfs GPIO",										"sysfs" },
269 	{ HTYPE_Rtl433, "Rtl433 RTL-SDR receiver",										"RTL433" },
270 	{ HTYPE_OnkyoAVTCP, "Onkyo AV Receiver (LAN)",									"Onkyo AV" },
271 	{ HTYPE_RESERVED_FOR_YOU_2, "",													"" },
272 	{ HTYPE_USBtinGateway, "USBtin Can Gateway",									"USBtin" },
273 	{ HTYPE_EnphaseAPI, "Enphase Envoy with LAN (HTTP) interface",					"Enphase" },
274 	{ HTYPE_RaspberryMCP23017, "I2C sensor GPIO 16bit expander MCP23017",			"I2C GPIO" },
275 	{ HTYPE_eHouseTCP, "eHouse UDP+TCP with LAN interface",							"eHouse" },
276 	{ HTYPE_EcoCompteur, "EcoCompteur Legrand with LAN interface",					"EcoCompteur" },
277 	{ HTYPE_Honeywell, "Honeywell Thermostat",										"Honeywell" },
278 	{ HTYPE_Tado, "Tado Thermostat",												"Tado" },
279 	{ HTYPE_DenkoviHTTPDevices, "Denkovi Modules with LAN (HTTP) Interface",		"Denkovi" },
280 	{ HTYPE_DenkoviUSBDevices, "Denkovi Modules with USB Interface",				"Denkovi" },
281 	{ HTYPE_DenkoviTCPDevices, "Denkovi Modules with LAN (TCP) Interface",			"Denkovi" },
282 	{ HTYPE_OctoPrint, "OctoPrint (MQTT/Gina Haussge) with LAN interface",			"OctoPrint" },
283 	{ 0, NULL, NULL }
284 };
285 
Hardware_Type_Desc(int hType)286 const char* Hardware_Type_Desc(int hType)
287 {
288 	return findTableIDSingle1(HardwareTypeTable, hType);
289 }
290 
Hardware_Short_Desc(int hType)291 const char* Hardware_Short_Desc(int hType)
292 {
293 	return findTableIDSingle2(HardwareTypeTable, hType);
294 }
295 
Switch_Type_Desc(const _eSwitchType sType)296 const char* Switch_Type_Desc(const _eSwitchType sType)
297 {
298 	static const STR_TABLE_SINGLE	Table[] =
299 	{
300 		{ STYPE_OnOff, "On/Off" },
301 	{ STYPE_Doorbell, "Doorbell" },
302 	{ STYPE_Contact, "Contact" },
303 	{ STYPE_Blinds, "Blinds" },
304 	{ STYPE_X10Siren, "X10 Siren" },
305 	{ STYPE_SMOKEDETECTOR, "Smoke Detector" },
306 	{ STYPE_BlindsInverted, "Blinds Inverted" },
307 	{ STYPE_Dimmer, "Dimmer" },
308 	{ STYPE_Motion, "Motion Sensor" },
309 	{ STYPE_PushOn, "Push On Button" },
310 	{ STYPE_PushOff, "Push Off Button" },
311 	{ STYPE_DoorContact, "Door Contact" },
312 	{ STYPE_Dusk, "Dusk Sensor" },
313 	{ STYPE_BlindsPercentage, "Blinds Percentage" },
314 	{ STYPE_VenetianBlindsUS, "Venetian Blinds US" },
315 	{ STYPE_VenetianBlindsEU, "Venetian Blinds EU" },
316 	{ STYPE_BlindsPercentageInverted, "Blinds Percentage Inverted" },
317 	{ STYPE_Media, "Media Player" },
318 	{ STYPE_Selector, "Selector" },
319 	{ STYPE_DoorLock, "Door Lock" },
320 	{ STYPE_DoorLockInverted, "Door Lock Inverted" },
321 	{ 0, NULL, NULL }
322 	};
323 	return findTableIDSingle1(Table, sType);
324 }
325 
Meter_Type_Desc(const _eMeterType sType)326 const char* Meter_Type_Desc(const _eMeterType sType)
327 {
328 	static const STR_TABLE_SINGLE	Table[] =
329 	{
330 		{ MTYPE_ENERGY, "Energy" },
331 	{ MTYPE_GAS, "Gas" },
332 	{ MTYPE_WATER, "Water" },
333 	{ MTYPE_COUNTER, "Counter" },
334 	{ MTYPE_ENERGY_GENERATED, "Energy Generated" },
335 	{ MTYPE_TIME , "Time" },
336 	{ 0,NULL,NULL }
337 	};
338 	return findTableIDSingle1(Table, sType);
339 }
340 
Notification_Type_Desc(const int nType,const unsigned char snum)341 const char* Notification_Type_Desc(const int nType, const unsigned char snum)
342 {
343 	static const STR_TABLE_SINGLE	Table[] =
344 	{
345 		{ NTYPE_TEMPERATURE, "Temperature","T" },
346 	{ NTYPE_HUMIDITY, "Humidity","H" },
347 	{ NTYPE_RAIN, "Rain","R" },
348 	{ NTYPE_UV, "UV","U" },
349 	{ NTYPE_WIND, "Wind","W" },
350 	{ NTYPE_USAGE, "Usage","M" },
351 	{ NTYPE_BARO, "Baro","B" },
352 	{ NTYPE_SWITCH_ON, "Switch On", "S" },
353 	{ NTYPE_AMPERE1, "Ampere 1", "1" },
354 	{ NTYPE_AMPERE2, "Ampere 2", "2" },
355 	{ NTYPE_AMPERE3, "Ampere 3", "3" },
356 	{ NTYPE_ENERGYINSTANT, "Instant", "I" },
357 	{ NTYPE_TODAYENERGY, "Today", "E" },
358 	{ NTYPE_TODAYGAS, "Today", "G" },
359 	{ NTYPE_TODAYCOUNTER, "Today", "C" },
360 	{ NTYPE_SWITCH_OFF, "Switch Off", "O" },
361 	{ NTYPE_PERCENTAGE, "Percentage", "P" },
362 	{ NTYPE_RPM, "RPM", "Z" },
363 	{ NTYPE_DEWPOINT, "Dew Point", "D" },
364 	{ NTYPE_SETPOINT, "Set Point", "N" },
365 	{ NTYPE_VIDEO, "Play Video", "V" },
366 	{ NTYPE_AUDIO, "Play Audio", "A" },
367 	{ NTYPE_PHOTO, "View Photo", "X" },
368 	{ NTYPE_PAUSED, "Pause Stream", "Y" },
369 	{ NTYPE_STOPPED, "Stop Stream", "Q" },
370 	{ NTYPE_PLAYING, "Play Stream", "a" },
371 	{ NTYPE_VALUE, "Value", "F" },
372 	{ NTYPE_LASTUPDATE, "Last Update", "J" },
373 	{ 0,NULL,NULL }
374 	};
375 	if (snum == 0)
376 		return findTableIDSingle1(Table, nType);
377 	else
378 		return findTableIDSingle2(Table, nType);
379 }
380 
Notification_Type_Label(const int nType)381 const char* Notification_Type_Label(const int nType)
382 {
383 	static const STR_TABLE_SINGLE	Table[] =
384 	{
385 		{ NTYPE_TEMPERATURE, "degrees" },
386 	{ NTYPE_HUMIDITY, "%" },
387 	{ NTYPE_RAIN, "mm" },
388 	{ NTYPE_UV, "UVI" },
389 	{ NTYPE_WIND, "m/s" },
390 	{ NTYPE_USAGE, "" },
391 	{ NTYPE_BARO, "hPa" },
392 	{ NTYPE_SWITCH_ON, "" },
393 	{ NTYPE_AMPERE1, "Ampere" },
394 	{ NTYPE_AMPERE2, "Ampere" },
395 	{ NTYPE_AMPERE3, "Ampere" },
396 	{ NTYPE_ENERGYINSTANT, "Watt" },
397 	{ NTYPE_TODAYENERGY, "kWh" },
398 	{ NTYPE_TODAYGAS, "m3" },
399 	{ NTYPE_TODAYCOUNTER, "cnt" },
400 	{ NTYPE_SWITCH_OFF, "On" },
401 	{ NTYPE_PERCENTAGE, "%" },
402 	{ NTYPE_RPM, "RPM" },
403 	{ NTYPE_DEWPOINT, "degrees" },
404 	{ NTYPE_SETPOINT, "degrees" },
405 	{ NTYPE_VIDEO, "" },
406 	{ NTYPE_AUDIO, "" },
407 	{ NTYPE_PHOTO, "" },
408 	{ NTYPE_PAUSED, "" },
409 	{ NTYPE_STOPPED, "" },
410 	{ NTYPE_PLAYING, "" },
411 	{ NTYPE_VALUE, "" },
412 	{ NTYPE_LASTUPDATE, "minutes" },
413 	{ 0,NULL,NULL }
414 	};
415 	return findTableIDSingle1(Table, nType);
416 }
417 
RFX_Forecast_Desc(const unsigned char Forecast)418 const char* RFX_Forecast_Desc(const unsigned char Forecast)
419 {
420 	static const STR_TABLE_SINGLE	Table[] =
421 	{
422 		{ baroForecastNoInfo, "No Info" },
423 	{ baroForecastSunny, "Sunny" },
424 	{ baroForecastPartlyCloudy, "Partly Cloudy" },
425 	{ baroForecastCloudy, "Cloudy" },
426 	{ baroForecastRain, "Rain" },
427 	{ 0,NULL,NULL }
428 	};
429 	return findTableIDSingle1(Table, Forecast);
430 }
431 
RFX_WSForecast_Desc(const unsigned char Forecast)432 const char* RFX_WSForecast_Desc(const unsigned char Forecast)
433 {
434 	static const STR_TABLE_SINGLE	Table[] =
435 	{
436 		{ wsbaroforecast_heavy_snow,"Heavy Snow" },
437 	{ wsbaroforecast_snow, "Snow" },
438 	{ wsbaroforecast_heavy_rain, "Heavy Rain" },
439 	{ wsbaroforecast_rain, "Rain" },
440 	{ wsbaroforecast_cloudy, "Cloudy" },
441 	{ wsbaroforecast_some_clouds, "Some Clouds" },
442 	{ wsbaroforecast_sunny, "Sunny" },
443 	{ wsbaroforecast_unknown, "Unknown" },
444 	{ wsbaroforecast_unstable, "Unstable" },
445 	{ wsbaroforecast_stable, "Stable" },
446 	{ 0, NULL, NULL }
447 	};
448 	return findTableIDSingle1(Table, Forecast);
449 }
450 
BMP_Forecast_Desc(const unsigned char Forecast)451 const char* BMP_Forecast_Desc(const unsigned char Forecast)
452 {
453 	static const STR_TABLE_SINGLE	Table[] =
454 	{
455 		{ bmpbaroforecast_stable, "Stable" },
456 	{ bmpbaroforecast_sunny, "Sunny" },
457 	{ bmpbaroforecast_cloudy, "Cloudy" },
458 	{ bmpbaroforecast_unstable, "Unstable" },
459 	{ bmpbaroforecast_thunderstorm, "Thunderstorm" },
460 	{ bmpbaroforecast_unknown, "Unknown" },
461 	{ bmpbaroforecast_rain, "Cloudy/Rain" },
462 	{ 0, NULL, NULL }
463 	};
464 	return findTableIDSingle1(Table, Forecast);
465 }
466 
RFX_Type_Desc(const unsigned char i,const unsigned char snum)467 const char* RFX_Type_Desc(const unsigned char i, const unsigned char snum)
468 {
469 	static const STR_TABLE_SINGLE	Table[] =
470 	{
471 		{ pTypeInterfaceControl, "Interface Control", "unknown" },
472 	{ pTypeInterfaceMessage, "Interface Message", "unknown" },
473 	{ pTypeRecXmitMessage, "Receiver/Transmitter Message", "unknown" },
474 	{ pTypeUndecoded, "Undecoded RF Message", "unknown" },
475 	{ pTypeLighting1, "Lighting 1" , "lightbulb", },
476 	{ pTypeLighting2, "Lighting 2" , "lightbulb", },
477 	{ pTypeLighting3, "Lighting 3" , "lightbulb", },
478 	{ pTypeLighting4, "Lighting 4" , "lightbulb", },
479 	{ pTypeLighting5, "Lighting 5" , "lightbulb", },
480 	{ pTypeLighting6, "Lighting 6" , "lightbulb", },
481 	{ pTypeHomeConfort, "Home Confort" , "lightbulb" },
482 	{ pTypeColorSwitch, "Color Switch" , "lightbulb" },
483 	{ pTypeCurtain, "Curtain" , "blinds" },
484 	{ pTypeBlinds, "Blinds" , "blinds" },
485 	{ pTypeSecurity1, "Security", "security" },
486 	{ pTypeSecurity2, "Security", "security" },
487 	{ pTypeCamera, "Camera", "unknown" },
488 	{ pTypeRemote, "Remote & IR" , "unknown" },
489 	{ pTypeThermostat1, "Thermostat 1" , "temperature" },
490 	{ pTypeThermostat2, "Thermostat 2" , "temperature" },
491 	{ pTypeThermostat3, "Thermostat 3" , "temperature" },
492 	{ pTypeThermostat4, "Thermostat 4" , "temperature" },
493 	{ pTypeRadiator1, "Radiator 1", "temperature" },
494 	{ pTypeTEMP, "Temp", "temperature" },
495 	{ pTypeHUM, "Humidity" , "temperature" },
496 	{ pTypeTEMP_HUM, "Temp + Humidity" , "temperature" },
497 	{ pTypeBARO, "Barometric" , "temperature" },
498 	{ pTypeTEMP_HUM_BARO, "Temp + Humidity + Baro" , "temperature" },
499 	{ pTypeRAIN, "Rain" , "rain" },
500 	{ pTypeWIND, "Wind" , "wind" },
501 	{ pTypeUV, "UV" , "uv" },
502 	{ pTypeDT, "Date/Time" , "unknown" },
503 	{ pTypeCURRENT, "Current" , "current" },
504 	{ pTypeENERGY, "Energy" , "current" },
505 	{ pTypeCURRENTENERGY, "Current/Energy" , "current" },
506 	{ pTypeGAS, "Gas" , "counter" },
507 	{ pTypeWATER, "Water" , "counter" },
508 	{ pTypeWEIGHT, "Weight" , "scale" },
509 	{ pTypeRFXSensor, "RFXSensor" , "unknown" },
510 	{ pTypeRFXMeter, "RFXMeter" , "counter" },
511 	{ pTypeP1Power, "P1 Smart Meter" , "counter" },
512 	{ pTypeP1Gas, "P1 Smart Meter" , "counter" },
513 	{ pTypeYouLess, "YouLess Meter", "counter" },
514 	{ pTypeFS20, "FS20" , "lightbulb" },
515 	{ pTypeRego6XXTemp, "Temp" , "temperature" },
516 	{ pTypeRego6XXValue, "Value" , "utility" },
517 	{ pTypeAirQuality, "Air Quality" , "air" },
518 	{ pTypeUsage, "Usage" , "current" },
519 	{ pTypeTEMP_BARO, "Temp + Baro" , "temperature" },
520 	{ pTypeLux, "Lux" , "lux" },
521 	{ pTypeGeneral, "General" , "General" },
522 	{ pTypeThermostat, "Thermostat" , "thermostat" },
523 	{ pTypeTEMP_RAIN, "Temp + Rain" , "Temp + Rain" },
524 	{ pTypeChime, "Chime" , "doorbell" },
525 	{ pTypeFan, "Fan" , "fan" },
526 	{ pTypeBBQ, "BBQ Meter", "bbq" },
527 	{ pTypePOWER, "Power" , "current" },
528 	{ pTypeRFY, "RFY" , "blinds" },
529 	{ pTypeEvohome, "Heating" , "evohome" },
530 	{ pTypeEvohomeZone, "Heating" , "evohome" },
531 	{ pTypeEvohomeWater, "Heating" , "evohome" },
532 	{ pTypeEvohomeRelay, "Heating" , "evohome" },
533 	{ pTypeGeneralSwitch, "Light/Switch", "lightbulb" },
534 	{ pTypeWEATHER, "Weather" , "weather" },
535 	{ pTypeSOLAR, "Solar" , "solar" },
536 	{ pTypeHunter, "Hunter" , "Hunter" },
537 	{ 0, NULL, NULL }
538 	};
539 	if (snum == 1)
540 		return findTableIDSingle1(Table, i);
541 
542 	return findTableIDSingle2(Table, i);
543 }
544 
RFX_Type_SubType_Desc(const unsigned char dType,const unsigned char sType)545 const char* RFX_Type_SubType_Desc(const unsigned char dType, const unsigned char sType)
546 {
547 	static const STR_TABLE_ID1_ID2	Table[] =
548 	{
549 		{ pTypeTEMP, sTypeTEMP1, "THR128/138, THC138" },
550 	{ pTypeTEMP, sTypeTEMP2, "THC238/268, THN132, THWR288, THRN122, THN122, AW129/131" },
551 	{ pTypeTEMP, sTypeTEMP3, "THWR800" },
552 	{ pTypeTEMP, sTypeTEMP4, "RTHN318" },
553 	{ pTypeTEMP, sTypeTEMP5, "LaCrosse TX3" },
554 	{ pTypeTEMP, sTypeTEMP6, "TS15C" },
555 	{ pTypeTEMP, sTypeTEMP7, "Viking 02811/02813, Proove TSS330" },
556 	{ pTypeTEMP, sTypeTEMP8, "LaCrosse WS2300" },
557 	{ pTypeTEMP, sTypeTEMP9, "RUBiCSON" },
558 	{ pTypeTEMP, sTypeTEMP10, "TFA 30.3133" },
559 	{ pTypeTEMP, sTypeTEMP11, "WT0122 Pool sensor" },
560 	{ pTypeTEMP, sTypeTEMP_SYSTEM, "System" },
561 
562 	{ pTypeHUM, sTypeHUM1, "LaCrosse TX3" },
563 	{ pTypeHUM, sTypeHUM2, "LaCrosse WS2300" },
564 
565 	{ pTypeTEMP_HUM, sTypeTH1, "THGN122/123/132, THGR122/228/238/268" },
566 	{ pTypeTEMP_HUM, sTypeTH2, "THGR810, THGN800" },
567 	{ pTypeTEMP_HUM, sTypeTH3, "RTGR328" },
568 	{ pTypeTEMP_HUM, sTypeTH4, "THGR328" },
569 	{ pTypeTEMP_HUM, sTypeTH5, "WTGR800" },
570 	{ pTypeTEMP_HUM, sTypeTH6, "THGR918, THGRN228, THGN500" },
571 	{ pTypeTEMP_HUM, sTypeTH7, "Cresta, TFA TS34C" },
572 	{ pTypeTEMP_HUM, sTypeTH8, "WT450H" },
573 	{ pTypeTEMP_HUM, sTypeTH9, "Viking 02035, 02038, TSS320" },
574 	{ pTypeTEMP_HUM, sTypeTH10, "Rubicson/IW008T/TX95" },
575 	{ pTypeTEMP_HUM, sTypeTH11, "Oregon EW109" },
576 	{ pTypeTEMP_HUM, sTypeTH12, "Imagintronix" },
577 	{ pTypeTEMP_HUM, sTypeTH13, "Alecto WS1700" },
578 	{ pTypeTEMP_HUM, sTypeTH14, "Alecto" },
579 	{ pTypeTEMP_HUM, sTypeTH_LC_TC, "LaCrosse TX3" },
580 
581 	{ pTypeTEMP_HUM_BARO, sTypeTHB1, "THB1 - BTHR918, BTHGN129" },
582 	{ pTypeTEMP_HUM_BARO, sTypeTHB2, "THB2 - BTHR918N, BTHR968" },
583 	{ pTypeTEMP_HUM_BARO, sTypeTHBFloat, "Weather Station" },
584 
585 	{ pTypeRAIN, sTypeRAIN1, "RGR126/682/918/928" },
586 	{ pTypeRAIN, sTypeRAIN2, "PCR800" },
587 	{ pTypeRAIN, sTypeRAIN3, "TFA" },
588 	{ pTypeRAIN, sTypeRAIN4, "UPM RG700" },
589 	{ pTypeRAIN, sTypeRAIN5, "LaCrosse WS2300" },
590 	{ pTypeRAIN, sTypeRAIN6, "LaCrosse TX5" },
591 	{ pTypeRAIN, sTypeRAIN7, "Alecto" },
592 	{ pTypeRAIN, sTypeRAIN8, "Davis" },
593 	{ pTypeRAIN, sTypeRAIN9, "TFA 30.3233.01" },
594 	{ pTypeRAIN, sTypeRAINWU, "WWW" },
595 	{ pTypeRAIN, sTypeRAINByRate, "RainByRate" },
596 
597 	{ pTypeWIND, sTypeWIND1, "WTGR800" },
598 	{ pTypeWIND, sTypeWIND2, "WGR800" },
599 	{ pTypeWIND, sTypeWIND3, "STR918/928, WGR918" },
600 	{ pTypeWIND, sTypeWIND4, "TFA" },
601 	{ pTypeWIND, sTypeWIND5, "UPM WDS500" },
602 	{ pTypeWIND, sTypeWIND6, "LaCrosse WS2300" },
603 	{ pTypeWIND, sTypeWIND7, "Alecto WS4500" },
604 	{ pTypeWIND, sTypeWINDNoTemp, "Weather Station" },
605 	{ pTypeWIND, sTypeWINDNoTempNoChill, "Wind" },
606 
607 	{ pTypeUV, sTypeUV1, "UVN128,UV138" },
608 	{ pTypeUV, sTypeUV2, "UVN800" },
609 	{ pTypeUV, sTypeUV3, "TFA" },
610 
611 	{ pTypeWEATHER, sTypeWEATHER1, "Alecto ACH2010" },
612 	{ pTypeWEATHER, sTypeWEATHER2, "Alecto WS5500" },
613 
614 	{ pTypeSOLAR, sTypeSOLAR1, "Davis" },
615 
616 	{ pTypeHunter, sTypeHunterfan, "Hunter Fan" },
617 
618 	{ pTypeLighting1, sTypeX10, "X10" },
619 	{ pTypeLighting1, sTypeARC, "ARC" },
620 	{ pTypeLighting1, sTypeAB400D, "ELRO AB400" },
621 	{ pTypeLighting1, sTypeWaveman, "Waveman" },
622 	{ pTypeLighting1, sTypeEMW200, "EMW200" },
623 	{ pTypeLighting1, sTypeIMPULS, "Impuls" },
624 	{ pTypeLighting1, sTypeRisingSun, "RisingSun" },
625 	{ pTypeLighting1, sTypePhilips, "Philips" },
626 	{ pTypeLighting1, sTypeEnergenie, "Energenie" },
627 	{ pTypeLighting1, sTypeEnergenie5, "Energenie 5-gang" },
628 	{ pTypeLighting1, sTypeGDR2, "COCO GDR2" },
629 	{ pTypeLighting1, sTypeHQ, "HQ COCO-20" },
630 	{ pTypeLighting1, sTypeOase, "Oase Inscenio" },
631 
632 	{ pTypeLighting2, sTypeAC, "AC" },
633 	{ pTypeLighting2, sTypeHEU, "HomeEasy EU" },
634 	{ pTypeLighting2, sTypeANSLUT, "Anslut" },
635 
636 	{ pTypeLighting3, sTypeKoppla, "Ikea Koppla" },
637 
638 	{ pTypeLighting4, sTypePT2262, "PT2262" },
639 
640 	{ pTypeLighting5, sTypeLightwaveRF, "LightwaveRF" },
641 	{ pTypeLighting5, sTypeEMW100, "EMW100" },
642 	{ pTypeLighting5, sTypeBBSB, "BBSB new" },
643 	{ pTypeLighting5, sTypeMDREMOTE, "MDRemote" },
644 	{ pTypeLighting5, sTypeRSL, "Conrad RSL" },
645 	{ pTypeLighting5, sTypeLivolo, "Livolo" },
646 	{ pTypeLighting5, sTypeTRC02, "TRC02 (RGB)" },
647 	{ pTypeLighting5, sTypeTRC02_2, "TRC02_2 (RGB)" },
648 	{ pTypeLighting5, sTypeAoke, "Aoke" },
649 	{ pTypeLighting5, sTypeEurodomest, "Eurodomest" },
650 	{ pTypeLighting5, sTypeLivolo1to10, "Livolo 1 to 10" },
651 	{ pTypeLighting5, sTypeRGB432W, "RGB432W" },
652 	{ pTypeLighting5, sTypeMDREMOTE107, "MDRemote 107" },
653 	{ pTypeLighting5, sTypeLegrandCAD, "Legrand CAD" },
654 	{ pTypeLighting5, sTypeAvantek, "Avantek" },
655 	{ pTypeLighting5, sTypeIT, "Intertek,FA500,PROmax" },
656 	{ pTypeLighting5, sTypeMDREMOTE108, "MDRemote 108" },
657 	{ pTypeLighting5, sTypeKangtai, "Kangtai / Cotech" },
658 
659 	{ pTypeLighting6, sTypeBlyss, "Blyss" },
660 
661 	{ pTypeHomeConfort, sTypeHomeConfortTEL010 , "TEL-010" },
662 
663 	{ pTypeCurtain, sTypeHarrison, "Harrison" },
664 
665 	{ pTypeBlinds, sTypeBlindsT0, "RollerTrol/Hasta" },
666 	{ pTypeBlinds, sTypeBlindsT1, "Hasta old" },
667 	{ pTypeBlinds, sTypeBlindsT2, "A-OK RF01" },
668 	{ pTypeBlinds, sTypeBlindsT3, "A-OK AC114" },
669 	{ pTypeBlinds, sTypeBlindsT4, "RAEX" },
670 	{ pTypeBlinds, sTypeBlindsT5, "Media Mount" },
671 	{ pTypeBlinds, sTypeBlindsT6, "DC106" },
672 	{ pTypeBlinds, sTypeBlindsT7, "Forest" },
673 	{ pTypeBlinds, sTypeBlindsT8, "Chamberlain" },
674 	{ pTypeBlinds, sTypeBlindsT9, "Sunpery" },
675 	{ pTypeBlinds, sTypeBlindsT10, "Dolat DLM-1" },
676 	{ pTypeBlinds, sTypeBlindsT11, "ASP" },
677 	{ pTypeBlinds, sTypeBlindsT12, "Confexx" },
678 	{ pTypeBlinds, sTypeBlindsT13, "Screenline" },
679 	{ pTypeBlinds, sTypeBlindsT14, "Hualite" },
680 	{ pTypeBlinds, sTypeBlindsT15, "RFU" },
681 	{ pTypeBlinds, sTypeBlindsT16, "Zemismart" },
682 	{ pTypeBlinds, sTypeBlindsT17, "Gaposa" },
683 	{ pTypeBlinds, sTypeBlindsT18, "Cherubini" },
684 
685 	{ pTypeSecurity1, sTypeSecX10, "X10 security" },
686 	{ pTypeSecurity1, sTypeSecX10M, "X10 security motion" },
687 	{ pTypeSecurity1, sTypeSecX10R, "X10 security remote" },
688 	{ pTypeSecurity1, sTypeKD101, "KD101 smoke detector" },
689 	{ pTypeSecurity1, sTypePowercodeSensor, "Visonic sensor - primary contact" },
690 	{ pTypeSecurity1, sTypePowercodeMotion, "Visonic motion" },
691 	{ pTypeSecurity1, sTypeCodesecure, "Visonic CodeSecure" },
692 	{ pTypeSecurity1, sTypePowercodeAux, "Visonic sensor - auxiliary contact" },
693 	{ pTypeSecurity1, sTypeMeiantech, "Meiantech/Atlantic/Aidebao" },
694 	{ pTypeSecurity1, sTypeSA30, "Alecto SA30 smoke detector" },
695 	{ pTypeSecurity1, sTypeRM174RF, "Smartwares RM174RF smoke detector" },
696 	{ pTypeSecurity1, sTypeDomoticzSecurity, "Security Panel" },
697 
698 	{ pTypeSecurity2, sTypeSec2Classic, "KeeLoq" },
699 
700 	{ pTypeCamera, sTypeNinja, "Meiantech" },
701 
702 	{ pTypeRemote, sTypeATI, "ATI Remote Wonder" },
703 	{ pTypeRemote, sTypeATIplus, "ATI Remote Wonder Plus" },
704 	{ pTypeRemote, sTypeMedion, "Medion Remote" },
705 	{ pTypeRemote, sTypePCremote, "PC Remote" },
706 	{ pTypeRemote, sTypeATIrw2, "ATI Remote Wonder II" },
707 
708 	{ pTypeThermostat1, sTypeDigimax, "Digimax" },
709 	{ pTypeThermostat1, sTypeDigimaxShort, "Digimax short" },
710 
711 	{ pTypeThermostat2, sTypeHE105, "HE105" },
712 	{ pTypeThermostat2, sTypeRTS10, "RTS10" },
713 
714 	{ pTypeThermostat3, sTypeMertikG6RH4T1, "Mertik G6R-H4T1" },
715 	{ pTypeThermostat3, sTypeMertikG6RH4TB, "Mertik G6R-H4TB" },
716 	{ pTypeThermostat3, sTypeMertikG6RH4TD, "Mertik G6R-H4TD" },
717 	{ pTypeThermostat3, sTypeMertikG6RH4S, "Mertik G6R-H4S" },
718 
719 	{ pTypeThermostat4, sTypeMCZ1, "MCZ 1 fan model" },
720 	{ pTypeThermostat4, sTypeMCZ2, "MCZ 2 fan model" },
721 	{ pTypeThermostat4, sTypeMCZ3, "MCZ 3 fan model" },
722 
723 	{ pTypeRadiator1, sTypeSmartwares, "Smartwares" },
724 	{ pTypeRadiator1, sTypeSmartwaresSwitchRadiator, "Smartwares Mode" },
725 
726 	{ pTypeDT, sTypeDT1, "RTGR328N" },
727 
728 	{ pTypeCURRENT, sTypeELEC1, "CM113, Electrisave" },
729 
730 	{ pTypeENERGY, sTypeELEC2, "CM119 / CM160" },
731 	{ pTypeENERGY, sTypeELEC3, "CM180" },
732 
733 	{ pTypeCURRENTENERGY, sTypeELEC4, "CM180i" },
734 
735 	{ pTypeWEIGHT, sTypeWEIGHT1, "BWR102" },
736 	{ pTypeWEIGHT, sTypeWEIGHT2, "GR101" },
737 
738 	{ pTypeRFXSensor, sTypeRFXSensorTemp, "Temperature" },
739 	{ pTypeRFXSensor, sTypeRFXSensorAD, "A/D" },
740 	{ pTypeRFXSensor, sTypeRFXSensorVolt, "Voltage" },
741 
742 	{ pTypeRFXMeter, sTypeRFXMeterCount, "RFXMeter counter" },
743 
744 	{ pTypeP1Power, sTypeP1Power, "Energy" },
745 	{ pTypeP1Gas, sTypeP1Gas, "Gas" },
746 
747 	{ pTypeYouLess, sTypeYouLess, "YouLess counter" },
748 
749 	{ pTypeRego6XXTemp, sTypeRego6XXTemp, "Rego 6XX" },
750 	{ pTypeRego6XXValue, sTypeRego6XXStatus, "Rego 6XX" },
751 	{ pTypeRego6XXValue, sTypeRego6XXCounter, "Rego 6XX" },
752 
753 	{ pTypeAirQuality, sTypeVoltcraft, "Voltcraft CO-20" },
754 
755 	{ pTypeUsage, sTypeElectric, "Electric" },
756 
757 	{ pTypeTEMP_BARO, sTypeBMP085, "BMP085 I2C" },
758 
759 	{ pTypeLux, sTypeLux, "Lux" },
760 
761 	{ pTypeGeneral, sTypeVisibility, "Visibility" },
762 	{ pTypeGeneral, sTypeSolarRadiation, "Solar Radiation" },
763 	{ pTypeGeneral, sTypeSoilMoisture, "Soil Moisture" },
764 	{ pTypeGeneral, sTypeLeafWetness, "Leaf Wetness" },
765 	{ pTypeGeneral, sTypeSystemTemp, "System temperature" },
766 	{ pTypeGeneral, sTypePercentage, "Percentage" },
767 	{ pTypeGeneral, sTypeFan, "Fan" },
768 	{ pTypeGeneral, sTypeVoltage, "Voltage" },
769 	{ pTypeGeneral, sTypeCurrent, "Current" },
770 	{ pTypeGeneral, sTypePressure, "Pressure" },
771 	{ pTypeGeneral, sTypeBaro, "Barometer" },
772 	{ pTypeGeneral, sTypeSetPoint, "Setpoint" },
773 	{ pTypeGeneral, sTypeTemperature, "Temperature" },
774 	{ pTypeGeneral, sTypeZWaveClock, "Thermostat Clock" },
775 	{ pTypeGeneral, sTypeTextStatus, "Text" },
776 	{ pTypeGeneral, sTypeZWaveThermostatMode, "Thermostat Mode" },
777 	{ pTypeGeneral, sTypeZWaveThermostatFanMode, "Thermostat Fan Mode" },
778 	{ pTypeGeneral, sTypeZWaveThermostatOperatingState, "Thermostat Operating State" },
779 	{ pTypeGeneral, sTypeAlert, "Alert" },
780 	{ pTypeGeneral, sTypeSoundLevel, "Sound Level" },
781 	{ pTypeGeneral, sTypeUV, "UV" },
782 	{ pTypeGeneral, sTypeDistance, "Distance" },
783 	{ pTypeGeneral, sTypeCounterIncremental, "Counter Incremental" },
784 	{ pTypeGeneral, sTypeKwh, "kWh" },
785 	{ pTypeGeneral, sTypeWaterflow, "Waterflow" },
786 	{ pTypeGeneral, sTypeCustom, "Custom Sensor" },
787 	{ pTypeGeneral, sTypeZWaveAlarm, "Alarm" },
788 	{ pTypeGeneral, sTypeManagedCounter, "Managed Counter" },
789 
790 	{ pTypeThermostat, sTypeThermSetpoint, "SetPoint" },
791 	{ pTypeThermostat, sTypeThermTemperature, "Temperature" },
792 
793 	{ pTypeChime, sTypeByronSX, "ByronSX" },
794 	{ pTypeChime, sTypeByronMP001, "Byron MP001" },
795 	{ pTypeChime, sTypeSelectPlus, "SelectPlus" },
796 	{ pTypeChime, sTypeByronBY, "SelectPlus3" },
797 	{ pTypeChime, sTypeEnvivo, "Envivo" },
798 	{ pTypeChime, sTypeAlfawise, "Alfawise" },
799 
800 	{ pTypeFan, sTypeSiemensSF01 , "Siemens SF01" },
801 	{ pTypeFan, sTypeItho , "Itho CVE RFT" },
802 	{ pTypeFan, sTypeLucciAir, "Lucci Air" },
803 	{ pTypeFan, sTypeSeavTXS4, "SEAV TXS4" },
804 	{ pTypeFan, sTypeWestinghouse, "Westinghouse" },
805 	{ pTypeFan, sTypeLucciAirDC, "Lucci Air DC" },
806 	{ pTypeFan, sTypeCasafan, "Casafan" },
807 	{ pTypeFan, sTypeFT1211R, "FT1211R" },
808 	{ pTypeFan, sTypeFalmec, "Falmec" },
809 	{ pTypeFan, sTypeLucciAirDCII, "Lucci Air DC II" },
810 	{ pTypeFan, sTypeIthoECO, "Itho ECO" },
811 	{ pTypeFan, sTypeNovy, "Novy" },
812 
813 	{ pTypeTEMP_RAIN, sTypeTR1, "Alecto WS1200" },
814 
815 	{ pTypeBBQ, sTypeBBQ1, "Maverick ET-732" },
816 
817 	{ pTypePOWER, sTypeELEC5, "Revolt" },
818 
819 	{ pTypeColorSwitch, sTypeColor_RGB_W, "RGBW" },
820 	{ pTypeColorSwitch, sTypeColor_RGB, "RGB" },
821 	{ pTypeColorSwitch, sTypeColor_White, "White" },
822 	{ pTypeColorSwitch, sTypeColor_RGB_CW_WW, "RGBWW" },
823 	{ pTypeColorSwitch, sTypeColor_LivCol, "RGB" },
824 	{ pTypeColorSwitch, sTypeColor_RGB_W_Z, "RGBWZ" },
825 	{ pTypeColorSwitch, sTypeColor_RGB_CW_WW_Z, "RGBWWZ" },
826 	{ pTypeColorSwitch, sTypeColor_CW_WW, "WW" },
827 
828 	{ pTypeRFY, sTypeRFY, "RFY" },
829 	{ pTypeRFY, sTypeRFY2, "RFY2" },
830 	{ pTypeRFY, sTypeRFYext, "RFY-Ext" },
831 	{ pTypeRFY, sTypeASA, "ASA" },
832 
833 	{ pTypeEvohome, sTypeEvohome, "Evohome" },
834 	{ pTypeEvohomeZone, sTypeEvohomeZone, "Zone" },
835 	{ pTypeEvohomeWater, sTypeEvohomeWater, "Hot Water" },
836 	{ pTypeEvohomeRelay, sTypeEvohomeRelay, "Relay" },
837 
838 	{ pTypeFS20, sTypeFS20, "FS20" },
839 	{ pTypeFS20, sTypeFHT8V, "FHT 8V valve" },
840 	{ pTypeFS20, sTypeFHT80, "FHT80 door/window sensor" },
841 
842 	{ pTypeWEATHER, sTypeWEATHER1, "Alecto ACH2010" },
843 	{ pTypeWEATHER, sTypeWEATHER2, "Alecto WS5500" },
844 
845 	{ pTypeSOLAR, sTypeSOLAR1, "Davis" },
846 
847 	{ pTypeGeneralSwitch, sSwitchTypeX10, "X10" },
848 	{ pTypeGeneralSwitch, sSwitchTypeARC, "ARC" },
849 	{ pTypeGeneralSwitch, sSwitchTypeAB400D, "ELRO AB400" },
850 	{ pTypeGeneralSwitch, sSwitchTypeWaveman, "Waveman" },
851 	{ pTypeGeneralSwitch, sSwitchTypeEMW200, "EMW200" },
852 	{ pTypeGeneralSwitch, sSwitchTypeIMPULS, "Impuls" },
853 	{ pTypeGeneralSwitch, sSwitchTypeRisingSun, "RisingSun" },
854 	{ pTypeGeneralSwitch, sSwitchTypePhilips, "Philips" },
855 	{ pTypeGeneralSwitch, sSwitchTypeEnergenie, "Energenie" },
856 	{ pTypeGeneralSwitch, sSwitchTypeEnergenie5, "Energenie 5-gang" },
857 	{ pTypeGeneralSwitch, sSwitchTypeGDR2, "COCO GDR2" },
858 	{ pTypeGeneralSwitch, sSwitchTypeAC, "AC" },
859 	{ pTypeGeneralSwitch, sSwitchTypeHEU, "HomeEasy EU" },
860 	{ pTypeGeneralSwitch, sSwitchTypeANSLUT, "Anslut" },
861 	{ pTypeGeneralSwitch, sSwitchTypeKoppla, "Ikea Koppla" },
862 	{ pTypeGeneralSwitch, sSwitchTypePT2262, "PT2262" },
863 	{ pTypeGeneralSwitch, sSwitchTypeLightwaveRF, "LightwaveRF" },
864 	{ pTypeGeneralSwitch, sSwitchTypeEMW100, "EMW100" },
865 	{ pTypeGeneralSwitch, sSwitchTypeBBSB, "BBSB new" },
866 	{ pTypeGeneralSwitch, sSwitchTypeMDREMOTE, "MDRemote" },
867 	{ pTypeGeneralSwitch, sSwitchTypeRSL, "Conrad RSL" },
868 	{ pTypeGeneralSwitch, sSwitchTypeLivolo, "Livolo" },
869 	{ pTypeGeneralSwitch, sSwitchTypeTRC02, "TRC02 (RGB)" },
870 	{ pTypeGeneralSwitch, sSwitchTypeTRC02_2, "TRC02_2 (RGB)" },
871 	{ pTypeGeneralSwitch, sSwitchTypeAoke, "Aoke" },
872 	{ pTypeGeneralSwitch, sSwitchTypeEurodomest, "Eurodomest" },
873 	{ pTypeGeneralSwitch, sSwitchTypeLivoloAppliance, "Livolo Appliance" },
874 	{ pTypeGeneralSwitch, sSwitchTypeBlyss, "Blyss" },
875 	{ pTypeGeneralSwitch, sSwitchTypeByronSX, "ByronSX" },
876 	{ pTypeGeneralSwitch, sSwitchTypeByronMP001, "Byron MP001" },
877 	{ pTypeGeneralSwitch, sSwitchTypeSelectPlus, "SelectPlus" },
878 	{ pTypeGeneralSwitch, sSwitchTypeSelectPlus3, "SelectPlus3" },
879 	{ pTypeGeneralSwitch, sSwitchTypeFA20, "FA20RF" },
880 	{ pTypeGeneralSwitch, sSwitchTypeChuango, "Chuango" },
881 	{ pTypeGeneralSwitch, sSwitchTypePlieger, "Plieger" },
882 	{ pTypeGeneralSwitch, sSwitchTypeSilvercrest, "SilverCrest" },
883 	{ pTypeGeneralSwitch, sSwitchTypeMertik, "Mertik" },
884 	{ pTypeGeneralSwitch, sSwitchTypeHomeConfort, "HomeConfort" },
885 	{ pTypeGeneralSwitch, sSwitchTypePowerfix, "Powerfix" },
886 	{ pTypeGeneralSwitch, sSwitchTypeTriState, "TriState" },
887 	{ pTypeGeneralSwitch, sSwitchTypeDeltronic, "Deltronic" },
888 	{ pTypeGeneralSwitch, sSwitchTypeFA500, "FA500" },
889 	{ pTypeGeneralSwitch, sSwitchTypeHT12E, "HT12E" },
890 	{ pTypeGeneralSwitch, sSwitchTypeEV1527, "EV1527" },
891 	{ pTypeGeneralSwitch, sSwitchTypeElmes, "Elmes" },
892 	{ pTypeGeneralSwitch, sSwitchTypeAster, "Aster" },
893 	{ pTypeGeneralSwitch, sSwitchTypeSartano, "Sartano" },
894 	{ pTypeGeneralSwitch, sSwitchTypeEurope, "Europe" },
895 	{ pTypeGeneralSwitch, sSwitchTypeAvidsen, "Avidsen" },
896 	{ pTypeGeneralSwitch, sSwitchTypeBofu, "BofuMotor" },
897 	{ pTypeGeneralSwitch, sSwitchTypeBrel, "BrelMotor" },
898 	{ pTypeGeneralSwitch, sSwitchTypeRTS, "RTS" },
899 	{ pTypeGeneralSwitch, sSwitchTypeElroDB, "ElroDB" },
900 	{ pTypeGeneralSwitch, sSwitchTypeDooya, "Dooya" },
901 	{ pTypeGeneralSwitch, sSwitchTypeUnitec, "Unitec" },
902 	{ pTypeGeneralSwitch, sSwitchTypeSelector, "Selector Switch" },
903 	{ pTypeGeneralSwitch, sSwitchTypeMaclean, "Maclean" },
904 	{ pTypeGeneralSwitch, sSwitchTypeR546, "R546" },
905 	{ pTypeGeneralSwitch, sSwitchTypeDiya, "Diya" },
906 	{ pTypeGeneralSwitch, sSwitchTypeX10secu, "X10Secure" },
907 	{ pTypeGeneralSwitch, sSwitchTypeAtlantic, "Atlantic" },
908 	{ pTypeGeneralSwitch, sSwitchTypeSilvercrestDB, "SilvercrestDB" },
909 	{ pTypeGeneralSwitch, sSwitchTypeMedionDB, "MedionDB" },
910 	{ pTypeGeneralSwitch, sSwitchTypeVMC, "VMC" },
911 	{ pTypeGeneralSwitch, sSwitchTypeKeeloq, "Keeloq" },
912 	{ pTypeGeneralSwitch, sSwitchCustomSwitch, "CustomSwitch" },
913 	{ pTypeGeneralSwitch, sSwitchGeneralSwitch, "Switch" },
914 	{ pTypeGeneralSwitch, sSwitchTypeKoch, "Koch" },
915 	{ pTypeGeneralSwitch, sSwitchTypeKingpin, "Kingpin" },
916 	{ pTypeGeneralSwitch, sSwitchTypeFunkbus, "Funkbus" },
917 	{ pTypeGeneralSwitch, sSwitchTypeNice, "Nice" },
918 	{ pTypeGeneralSwitch, sSwitchTypeForest, "Forest" },
919 	{ pTypeGeneralSwitch, sSwitchBlindsT1, "Legrand MyHome Blind Bus" },
920 	{ pTypeGeneralSwitch, sSwitchLightT1, "Legrand MyHome Light Bus" },
921 	{ pTypeGeneralSwitch, sSwitchAuxiliaryT1, "Legrand MyHome Auxiliary Bus" },
922 	{ pTypeGeneralSwitch, sSwitchContactT1, "Legrand MyHome Contact" },
923 	{ pTypeGeneralSwitch, sSwitchMC145026, "MC145026" },
924 	{ pTypeGeneralSwitch, sSwitchLobeco, "Lobeco" },
925 	{ pTypeGeneralSwitch, sSwitchFriedland, "Friedland" },
926 	{ pTypeGeneralSwitch, sSwitchBFT, "BFT" },
927 	{ pTypeGeneralSwitch, sSwitchNovatys, "Novatys" },
928 	{ pTypeGeneralSwitch, sSwitchHalemeier, "Halemeier" },
929 	{ pTypeGeneralSwitch, sSwitchGaposa, "Gaposa" },
930 	{ pTypeGeneralSwitch, sSwitchMiLightv1, "MiLightv1" },
931 	{ pTypeGeneralSwitch, sSwitchMiLightv2, "MiLightv2" },
932 	{ pTypeGeneralSwitch, sSwitchHT6P20, "HT6P20" },
933 	{ pTypeGeneralSwitch, sSwitchTypeDoitrand, "Doitrand" },
934 	{ pTypeGeneralSwitch, sSwitchTypeWarema, "Warema" },
935 	{ pTypeGeneralSwitch, sSwitchTypeAnsluta, "Ansluta" },
936 	{ pTypeGeneralSwitch, sSwitchTypeLivcol, "Livcol" },
937 	{ pTypeGeneralSwitch, sSwitchTypeBosch, "Bosch" },
938 	{ pTypeGeneralSwitch, sSwitchTypeNingbo, "Ningbo" },
939 	{ pTypeGeneralSwitch, sSwitchTypeDitec, "Ditec" },
940 	{ pTypeGeneralSwitch, sSwitchTypeSteffen, "Steffen" },
941 	{ pTypeGeneralSwitch, sSwitchTypeAlectoSA, "AlectoSA" },
942 	{ pTypeGeneralSwitch, sSwitchTypeGPIOset, "GPIOset" },
943 	{ pTypeGeneralSwitch, sSwitchTypeKonigSec, "KonigSec" },
944 	{ pTypeGeneralSwitch, sSwitchTypeRM174RF, "RM174RF" },
945 	{ pTypeGeneralSwitch, sSwitchTypeLiwin, "Liwin" },
946 	{ pTypeGeneralSwitch, sSwitchBlindsT2, "Legrand MyHome Blind Zigbee" },
947 	{ pTypeGeneralSwitch, sSwitchLightT2, "Legrand MyHome Light Zigbee" },
948 	{ pTypeGeneralSwitch, sSwitchTypeYW_Secu, "YW_Secu" },
949 	{ pTypeGeneralSwitch, sSwitchTypeMertik_GV60, "Mertik_GV60" },
950 	{ pTypeGeneralSwitch, sSwitchTypeNingbo64, "Ningbo64" },
951 	{ pTypeGeneralSwitch, sSwitchTypeX2D, "X2D" },
952 	{ pTypeGeneralSwitch, sSwitchTypeHRCMotor, "HRCMotor" },
953 	{ pTypeGeneralSwitch, sSwitchTypeVelleman, "Velleman" },
954 	{ pTypeGeneralSwitch, sSwitchTypeRFCustom, "RFCustom" },
955 	{ pTypeGeneralSwitch, sSwitchTypeYW_Sensor, "YW_Sensor" },
956 	{ pTypeGeneralSwitch, sSwitchTypeLegrandcad, "LEGRANDCAD" },
957 	{ pTypeGeneralSwitch, sSwitchTypeSysfsGpio, "SysfsGpio" },
958 	{ pTypeGeneralSwitch, sSwitchTypeHager, "Hager" },
959 	{ pTypeGeneralSwitch, sSwitchTypeFaber, "Faber" },
960 	{ pTypeGeneralSwitch, sSwitchTypeDrayton, "Drayton" },
961 	{ pTypeGeneralSwitch, sSwitchTypeV2Phoenix, "V2Phoenix" },
962 	{ 0,0,NULL }
963 	};
964 	return findTableID1ID2(Table, dType, sType);
965 }
966 
Media_Player_States(const _eMediaStatus Status)967 const char* Media_Player_States(const _eMediaStatus Status)
968 {
969 	static const STR_TABLE_SINGLE	Table[] =
970 	{
971 		{ MSTAT_OFF, "Off" },
972 	{ MSTAT_ON, "On" },
973 	{ MSTAT_PAUSED, "Paused" },
974 	{ MSTAT_STOPPED, "Stopped" },
975 	{ MSTAT_VIDEO, "Video" },
976 	{ MSTAT_AUDIO, "Audio" },
977 	{ MSTAT_PHOTO, "Photo" },
978 	{ MSTAT_PLAYING, "Playing" },
979 	{ MSTAT_DISCONNECTED, "Disconnected" },
980 	{ MSTAT_SLEEPING, "Sleeping" },
981 	{ MSTAT_UNKNOWN, "Unknown" },
982 	{ 0, NULL, NULL }
983 	};
984 	return findTableIDSingle1(Table, Status);
985 }
986 
ZWave_Clock_Days(const unsigned char Day)987 const char* ZWave_Clock_Days(const unsigned char Day)
988 {
989 	static const STR_TABLE_SINGLE	Table[] =
990 	{
991 		{ 0, "Monday" },
992 	{ 1, "Tuesday" },
993 	{ 2, "Wednesday" },
994 	{ 3, "Thursday" },
995 	{ 4, "Friday" },
996 	{ 5, "Saturday" },
997 	{ 6, "Sunday" },
998 	{ 0, NULL, NULL }
999 	};
1000 	return findTableIDSingle1(Table, Day);
1001 }
1002 /*
1003 const char *ZWave_Thermostat_Modes[] =
1004 {
1005 "Off",
1006 "Heat",
1007 "Cool",
1008 "Auto",
1009 "Aux Heat",
1010 "Resume",
1011 "Fan Only",
1012 "Furnace",
1013 "Dry Air",
1014 "Moist Air",
1015 "Auto Changeover",
1016 "Heat Econ",
1017 "Cool Econ",
1018 "Away",
1019 "Unknown",
1020 NULL
1021 };
1022 */
1023 const char* ZWave_Thermostat_Fan_Modes[] =
1024 {
1025 	"Auto Low",
1026 	"On Low",
1027 	"Auto High",
1028 	"On High",
1029 	"Unknown 4",
1030 	"Unknown 5",
1031 	"Circulate",
1032 	"Unknown",
1033 	NULL
1034 };
1035 
Lookup_ZWave_Thermostat_Modes(const std::vector<std::string> & Modes,const std::string & sMode)1036 int Lookup_ZWave_Thermostat_Modes(const std::vector<std::string>& Modes, const std::string& sMode)
1037 {
1038 	int ii = 0;
1039 	for (const auto& itt : Modes)
1040 	{
1041 		if (itt == sMode)
1042 			return ii;
1043 		ii++;
1044 	}
1045 	return -1;
1046 }
1047 
Lookup_ZWave_Thermostat_Fan_Modes(const std::string & sMode)1048 int Lookup_ZWave_Thermostat_Fan_Modes(const std::string& sMode)
1049 {
1050 	int ii = 0;
1051 	while (ZWave_Thermostat_Fan_Modes[ii] != NULL)
1052 	{
1053 		if (ZWave_Thermostat_Fan_Modes[ii] == sMode)
1054 		{
1055 			return ii;
1056 		}
1057 		ii++;
1058 	}
1059 	return -1;
1060 }
1061 
1062 
GetLightStatus(const unsigned char dType,const unsigned char dSubType,const _eSwitchType switchtype,const unsigned char nValue,const std::string & sValue,std::string & lstatus,int & llevel,bool & bHaveDimmer,int & maxDimLevel,bool & bHaveGroupCmd)1063 void GetLightStatus(
1064 	const unsigned char dType,
1065 	const unsigned char dSubType,
1066 	const _eSwitchType switchtype,
1067 	const unsigned char nValue,
1068 	const std::string& sValue,
1069 	std::string& lstatus,
1070 	int& llevel,
1071 	bool& bHaveDimmer,
1072 	int& maxDimLevel,
1073 	bool& bHaveGroupCmd)
1074 {
1075 	bHaveDimmer = false;
1076 	maxDimLevel = 0;
1077 	bHaveGroupCmd = false;
1078 	lstatus = "";
1079 
1080 	char szTmp[80];
1081 	switch (dType)
1082 	{
1083 	case pTypeLighting1:
1084 		switch (dSubType)
1085 		{
1086 		case sTypeX10:
1087 			bHaveGroupCmd = true;
1088 			switch (nValue)
1089 			{
1090 			case light1_sOff:
1091 				lstatus = "Off";
1092 				break;
1093 			case light1_sOn:
1094 				lstatus = "On";
1095 				break;
1096 			case light1_sDim:
1097 				lstatus = "Dim";
1098 				break;
1099 			case light1_sBright:
1100 				lstatus = "Bright";
1101 				break;
1102 			case light1_sAllOn:
1103 				lstatus = "All On";
1104 				break;
1105 			case light1_sAllOff:
1106 				lstatus = "All Off";
1107 				break;
1108 			}
1109 			break;
1110 		case sTypeARC:
1111 		case sTypePhilips:
1112 		case sTypeEnergenie:
1113 		case sTypeEnergenie5:
1114 		case sTypeGDR2:
1115 		case sTypeHQ:
1116 		case sTypeOase:
1117 			bHaveGroupCmd = true;
1118 			switch (nValue)
1119 			{
1120 			case light1_sOff:
1121 				lstatus = "Off";
1122 				break;
1123 			case light1_sOn:
1124 				lstatus = "On";
1125 				break;
1126 			case light1_sAllOn:
1127 				lstatus = "All On";
1128 				break;
1129 			case light1_sAllOff:
1130 				lstatus = "All Off";
1131 				break;
1132 			case light1_sChime:
1133 				lstatus = "Chime";
1134 				break;
1135 			}
1136 			break;
1137 		case sTypeAB400D:
1138 		case sTypeWaveman:
1139 		case sTypeEMW200:
1140 		case sTypeIMPULS:
1141 		case sTypeRisingSun:
1142 			switch (nValue)
1143 			{
1144 			case light1_sOff:
1145 				lstatus = "Off";
1146 				break;
1147 			case light1_sOn:
1148 				lstatus = "On";
1149 				break;
1150 			}
1151 			break;
1152 		}
1153 		break;
1154 	case pTypeLighting2:
1155 		// Determine max dim level based on switch type
1156 		maxDimLevel = 15;
1157 
1158 		if (switchtype != STYPE_Media) {
1159 			// Calculate % that the light is currently on, taking the maxdimlevel into account.
1160 			llevel = (int)float((100.0f / float(maxDimLevel)) * atof(sValue.c_str()));
1161 		}
1162 
1163 		// Fill in other parameters
1164 		switch (dSubType)
1165 		{
1166 		case sTypeAC:
1167 		case sTypeHEU:
1168 		case sTypeANSLUT:
1169 		case sTypeKambrook:
1170 			bHaveDimmer = true;
1171 			bHaveGroupCmd = true;
1172 			switch (nValue)
1173 			{
1174 			case light2_sOff:
1175 				lstatus = "Off";
1176 				break;
1177 			case light2_sOn:
1178 				lstatus = "On";
1179 				break;
1180 			case light2_sSetLevel:
1181 				sprintf(szTmp, "Set Level: %d %%", llevel);
1182 				if (sValue != "0")
1183 					lstatus = szTmp;
1184 				else
1185 					lstatus = "Off";
1186 				break;
1187 			case light2_sGroupOff:
1188 				lstatus = "Group Off";
1189 				break;
1190 			case light2_sGroupOn:
1191 				lstatus = "Group On";
1192 				break;
1193 			case light2_sSetGroupLevel:
1194 				sprintf(szTmp, "Set Group Level: %d %%", atoi(sValue.c_str()));
1195 				if (sValue != "0")
1196 					lstatus = szTmp;
1197 				else
1198 					lstatus = "Off";
1199 				break;
1200 			case gswitch_sStop:
1201 				lstatus = "Stop";
1202 				break;
1203 			}
1204 			break;
1205 		}
1206 		break;
1207 	case pTypeLighting4:
1208 		switch (nValue)
1209 		{
1210 		case light2_sOff:
1211 			lstatus = "Off";
1212 			break;
1213 		case light2_sOn:
1214 			lstatus = "On";
1215 			break;
1216 		}
1217 		break;
1218 	case pTypeLighting5:
1219 		if (dSubType == sTypeLivolo)
1220 			llevel = int((100.0f / 7.0f) * atof(sValue.c_str()));
1221 		else
1222 			llevel = int((100.0f / 31.0f) * atof(sValue.c_str()));
1223 		switch (dSubType)
1224 		{
1225 		case sTypeLightwaveRF:
1226 			bHaveGroupCmd = true;
1227 			bHaveDimmer = true;
1228 			maxDimLevel = 32;
1229 			llevel = (int)float((100.0f / float(maxDimLevel)) * atof(sValue.c_str()));
1230 			switch (nValue)
1231 			{
1232 			case light5_sOff:
1233 				lstatus = "Off";
1234 				break;
1235 			case light5_sOn:
1236 				lstatus = "On";
1237 				break;
1238 			case light5_sGroupOff:
1239 				lstatus = "Group Off";
1240 				break;
1241 			case light5_sMood1:
1242 				lstatus = "Group Mood 1";
1243 				break;
1244 			case light5_sMood2:
1245 				lstatus = "Group Mood 2";
1246 				break;
1247 			case light5_sMood3:
1248 				lstatus = "Group Mood 3";
1249 				break;
1250 			case light5_sMood4:
1251 				lstatus = "Group Mood 4";
1252 				break;
1253 			case light5_sMood5:
1254 				lstatus = "Group Mood 5";
1255 				break;
1256 			case light5_sUnlock:
1257 				lstatus = "Unlock";
1258 				break;
1259 			case light5_sLock:
1260 				lstatus = "Lock";
1261 				break;
1262 			case light5_sAllLock:
1263 				lstatus = "All lock";
1264 				break;
1265 			case light5_sClose:
1266 				lstatus = "Close inline relay";
1267 				break;
1268 			case light5_sStop:
1269 				lstatus = "Stop inline relay";
1270 				break;
1271 			case light5_sOpen:
1272 				lstatus = "Open inline relay";
1273 				break;
1274 			case light5_sSetLevel:
1275 				sprintf(szTmp, "Set Level: %d %%", llevel);
1276 				if (sValue != "0")
1277 					lstatus = szTmp;
1278 				else
1279 					lstatus = "Off";
1280 				break;
1281 			}
1282 			break;
1283 		case sTypeEMW100:
1284 			switch (nValue)
1285 			{
1286 			case light5_sOff:
1287 				lstatus = "Off";
1288 				break;
1289 			case light5_sOn:
1290 				lstatus = "On";
1291 				break;
1292 			case light5_sLearn:
1293 				lstatus = "Learn";
1294 				break;
1295 			}
1296 			break;
1297 		case sTypeBBSB:
1298 		case sTypeRSL:
1299 		case sTypeKangtai:
1300 			bHaveGroupCmd = true;
1301 			switch (nValue)
1302 			{
1303 			case light5_sOff:
1304 				lstatus = "Off";
1305 				break;
1306 			case light5_sOn:
1307 				lstatus = "On";
1308 				break;
1309 			case light5_sGroupOff:
1310 				lstatus = "Group Off";
1311 				break;
1312 			case light5_sGroupOn:
1313 				lstatus = "Group On";
1314 				break;
1315 			}
1316 			break;
1317 		case sTypeLivolo:
1318 			bHaveGroupCmd = true;
1319 			bHaveDimmer = true;
1320 			maxDimLevel = 7;
1321 			switch (nValue)
1322 			{
1323 			case light5_sOff:
1324 				lstatus = "Off";
1325 				break;
1326 			case light5_sOn:
1327 				lstatus = "On";
1328 				break;
1329 			case light5_sLivoloGang2Toggle:
1330 				lstatus = "Set Level";
1331 				break;
1332 			case light5_sLivoloGang3Toggle:
1333 				lstatus = "Set Level";
1334 				break;
1335 			}
1336 			break;
1337 		case sTypeLivolo1to10:
1338 			bHaveGroupCmd = true;
1339 			switch (nValue)
1340 			{
1341 			case light5_sLivoloAllOff:
1342 				lstatus = "Off";
1343 				break;
1344 			case light5_sLivoloGang1Toggle:
1345 				lstatus = "On";
1346 				break;
1347 			}
1348 			break;
1349 		case sTypeRGB432W:
1350 			switch (nValue)
1351 			{
1352 			case light5_sRGBoff:
1353 				lstatus = "Off";
1354 				break;
1355 			case light5_sRGBon:
1356 				lstatus = "On";
1357 				break;
1358 			case light5_sRGBbright:
1359 				lstatus = "Bright";
1360 				break;
1361 			case light5_sRGBdim:
1362 				lstatus = "Dim";
1363 				break;
1364 			case light5_sRGBcolorplus:
1365 				lstatus = "Color Plus";
1366 				break;
1367 			case light5_sRGBcolormin:
1368 				lstatus = "Color Min";
1369 				break;
1370 			}
1371 			break;
1372 		case sTypeTRC02:
1373 		case sTypeTRC02_2:
1374 			bHaveGroupCmd = true;
1375 			bHaveDimmer = true;
1376 			maxDimLevel = 7;
1377 			switch (nValue)
1378 			{
1379 			case light5_sOff:
1380 				lstatus = "Off";
1381 				break;
1382 			case light5_sOn:
1383 				lstatus = "On";
1384 				break;
1385 			}
1386 			break;
1387 		case sTypeAoke:
1388 			switch (nValue)
1389 			{
1390 			case light5_sOff:
1391 				lstatus = "Off";
1392 				break;
1393 			case light5_sOn:
1394 				lstatus = "On";
1395 				break;
1396 			}
1397 			break;
1398 		case sTypeEurodomest:
1399 			switch (nValue)
1400 			{
1401 			case light5_sOff:
1402 				lstatus = "Off";
1403 				break;
1404 			case light5_sOn:
1405 				lstatus = "On";
1406 				break;
1407 			case light5_sGroupOff:
1408 				lstatus = "Group Off";
1409 				break;
1410 			case light5_sGroupOn:
1411 				lstatus = "Group On";
1412 				break;
1413 			}
1414 			break;
1415 		case sTypeIT:
1416 			maxDimLevel = 9;
1417 			llevel = (int)float((100.0f / float(maxDimLevel)) * atof(sValue.c_str()));
1418 			switch (nValue)
1419 			{
1420 			case light5_sOff:
1421 				lstatus = "Off";
1422 				break;
1423 			case light5_sOn:
1424 				lstatus = "On";
1425 				break;
1426 			case light5_sGroupOff:
1427 				lstatus = "Group Off";
1428 				break;
1429 			case light5_sGroupOn:
1430 				lstatus = "Group On";
1431 				break;
1432 			case light5_sSetLevel:
1433 				sprintf(szTmp, "Set Level: %d %%", llevel);
1434 				if (sValue != "0")
1435 					lstatus = szTmp;
1436 				else
1437 					lstatus = "Off";
1438 				break;
1439 			}
1440 			break;
1441 		}
1442 		break;
1443 	case pTypeLighting6:
1444 		bHaveGroupCmd = true;
1445 		switch (dSubType)
1446 		{
1447 		case sTypeBlyss:
1448 			switch (nValue)
1449 			{
1450 			case light6_sOff:
1451 				lstatus = "Off";
1452 				break;
1453 			case light6_sOn:
1454 				lstatus = "On";
1455 				break;
1456 			case light6_sGroupOff:
1457 				lstatus = "Group Off";
1458 				break;
1459 			case light6_sGroupOn:
1460 				lstatus = "Group On";
1461 				break;
1462 			}
1463 		}
1464 		break;
1465 	case pTypeHomeConfort:
1466 		switch (dSubType)
1467 		{
1468 		case sTypeHomeConfortTEL010:
1469 			bHaveGroupCmd = true;
1470 			switch (nValue)
1471 			{
1472 			case HomeConfort_sOff:
1473 				lstatus = "Off";
1474 				break;
1475 			case HomeConfort_sOn:
1476 				lstatus = "On";
1477 				break;
1478 			case HomeConfort_sGroupOn:
1479 				lstatus = "Group On";
1480 				break;
1481 			case HomeConfort_sGroupOff:
1482 				lstatus = "Group Off";
1483 				break;
1484 			}
1485 			break;
1486 		}
1487 		break;
1488 	case pTypeGeneralSwitch:
1489 		maxDimLevel = 100;
1490 
1491 		// Calculate % that the light is currently on, taking the maxdimlevel into account.
1492 		llevel = (int)float((100.0f / float(maxDimLevel)) * atof(sValue.c_str()));
1493 
1494 		// Fill in other parameters
1495 		switch (dSubType)
1496 		{
1497 		case sSwitchTypeAC:
1498 		case sSwitchTypeHEU:
1499 		case sSwitchTypeANSLUT:
1500 		case sSwitchTypeSelector:
1501 		case sSwitchGeneralSwitch:
1502 			bHaveDimmer = true;
1503 			bHaveGroupCmd = true;
1504 			break;
1505 		}
1506 		switch (nValue)
1507 		{
1508 		case gswitch_sOff:
1509 			lstatus = "Off";
1510 			break;
1511 		case gswitch_sOn:
1512 			lstatus = "On";
1513 			break;
1514 		case gswitch_sSetLevel:
1515 			sprintf(szTmp, "Set Level: %d %%", llevel);
1516 			if (sValue != "0")
1517 				lstatus = szTmp;
1518 			else
1519 				lstatus = "Off";
1520 			break;
1521 		case gswitch_sGroupOff:
1522 			lstatus = "Group Off";
1523 			break;
1524 		case gswitch_sGroupOn:
1525 			lstatus = "Group On";
1526 			break;
1527 		case gswitch_sSetGroupLevel:
1528 			sprintf(szTmp, "Set Group Level: %d %%", atoi(sValue.c_str()));
1529 			if (sValue != "0")
1530 				lstatus = szTmp;
1531 			else
1532 				lstatus = "Group Off";
1533 			break;
1534 		case gswitch_sDim:
1535 			lstatus = "Dim";
1536 			break;
1537 		case gswitch_sBright:
1538 			lstatus = "Bright";
1539 			break;
1540 		case gswitch_sSound0:
1541 			lstatus = "Sound 0";
1542 			break;
1543 		case gswitch_sSound1:
1544 			lstatus = "Sound 1";
1545 			break;
1546 		case gswitch_sSound2:
1547 			lstatus = "Sound 2";
1548 			break;
1549 		case gswitch_sSound3:
1550 			lstatus = "Sound 3";
1551 			break;
1552 		case gswitch_sSound4:
1553 			lstatus = "Sound 4";
1554 			break;
1555 		case gswitch_sSound5:
1556 			lstatus = "Sound 5";
1557 			break;
1558 		case gswitch_sSound6:
1559 			lstatus = "Sound 6";
1560 			break;
1561 		case gswitch_sSound7:
1562 			lstatus = "Sound 7";
1563 			break;
1564 		case gswitch_sSound8:
1565 			lstatus = "Sound 8";
1566 			break;
1567 		case gswitch_sStop:
1568 			lstatus = "Stop";
1569 			break;
1570 		case gswitch_sProgram:
1571 			lstatus = "Program";
1572 			break;
1573 		}
1574 		break;
1575 	case pTypeFS20:
1576 		bHaveGroupCmd = false;
1577 		maxDimLevel = 15;
1578 		switch (nValue)
1579 		{
1580 		case fs20_sOff:
1581 			lstatus = "Off";
1582 			break;
1583 		case fs20_sDimlevel_1:
1584 		case fs20_sDimlevel_2:
1585 		case fs20_sDimlevel_3:
1586 		case fs20_sDimlevel_4:
1587 		case fs20_sDimlevel_5:
1588 		case fs20_sDimlevel_6:
1589 		case fs20_sDimlevel_7:
1590 		case fs20_sDimlevel_8:
1591 		case fs20_sDimlevel_9:
1592 		case fs20_sDimlevel_10:
1593 		case fs20_sDimlevel_11:
1594 		case fs20_sDimlevel_12:
1595 		case fs20_sDimlevel_13:
1596 		case fs20_sDimlevel_14:
1597 		case fs20_sDimlevel_15:
1598 			lstatus = "Set Level";
1599 			bHaveDimmer = 1;
1600 			llevel = nValue - fs20_sDimlevel_1 + 1;
1601 			llevel = (int)float((100.0f / float(maxDimLevel)) * llevel);
1602 			break;
1603 		case fs20_sOn_100:
1604 			lstatus = "On";
1605 			break;
1606 		case fs20_sOn_last_dim:
1607 			lstatus = "OnDim";
1608 			break;
1609 		case fs20_sToggle_On_Off:
1610 			lstatus = "Toggle";
1611 			break;
1612 		case fs20_sBright:
1613 			lstatus = "Bright";
1614 			break;
1615 		case fs20_sDim:
1616 			lstatus = "Dim";
1617 			break;
1618 		case fs20_sStart_dim_cycle:
1619 			lstatus = "StartDim";
1620 			break;
1621 		case fs20_sProgram_timer:
1622 			lstatus = "Program";
1623 			break;
1624 		case fs20_sRequest_status:
1625 			lstatus = "Request";
1626 			break;
1627 		case fs20_sOff_for_time_period:
1628 			lstatus = "OffTime";
1629 			break;
1630 		case fs20_sOn_100_for_time_period:
1631 			lstatus = "OnTime";
1632 			break;
1633 		case fs20_sOn_last_dim_level_period:
1634 			lstatus = "OnDimTime";
1635 			break;
1636 		case fs20_sReset:
1637 			lstatus = "Reset";
1638 			break;
1639 		}
1640 		break;
1641 	case pTypeColorSwitch:
1642 		bHaveDimmer = true;
1643 		maxDimLevel = 100;
1644 
1645 		// Calculate % that the light is currently on, taking the maxdimlevel into account.
1646 		llevel = (int)float((100.0f / float(maxDimLevel)) * atof(sValue.c_str()));
1647 
1648 		switch (nValue)
1649 		{
1650 		case Color_LedOff:
1651 			lstatus = "Off";
1652 			break;
1653 		case Color_LedOn:
1654 			lstatus = "On";
1655 			break;
1656 		case Color_SetBrightnessLevel:
1657 			sprintf(szTmp, "Set Level: %d %%", llevel);
1658 			if (sValue != "0")
1659 				lstatus = szTmp;
1660 			else
1661 				lstatus = "Off";
1662 			break;
1663 		case Color_SetColorToWhite:
1664 			lstatus = "Set to White";
1665 			break;
1666 		case Color_SetColor:
1667 			lstatus = "Set Color";
1668 			break;
1669 		case Color_NightMode:
1670 			lstatus = "NightMode";
1671 			break;
1672 		case Color_DiscoMode_1:
1673 			lstatus = "Disco Mode 1";
1674 			break;
1675 		case Color_DiscoMode_2:
1676 			lstatus = "Disco Mode 2";
1677 			break;
1678 		case Color_DiscoMode_3:
1679 			lstatus = "Disco Mode 3";
1680 			break;
1681 		case Color_DiscoMode_4:
1682 			lstatus = "Disco Mode 4";
1683 			break;
1684 		case Color_DiscoMode_5:
1685 			lstatus = "Disco Mode 5";
1686 			break;
1687 		case Color_DiscoMode_6:
1688 			lstatus = "Disco Mode 6";
1689 			break;
1690 		case Color_DiscoMode_7:
1691 			lstatus = "Disco Mode 7";
1692 			break;
1693 		case Color_DiscoMode_8:
1694 			lstatus = "Disco Mode 8";
1695 			break;
1696 		case Color_DiscoMode_9:
1697 			lstatus = "Disco Mode 9";
1698 			break;
1699 		}
1700 		break;
1701 	case pTypeSecurity1:
1702 		llevel = 0;
1703 		switch (nValue)
1704 		{
1705 		case sStatusNormal:
1706 			lstatus = "Normal";
1707 			break;
1708 		case sStatusNormalDelayed:
1709 			lstatus = "Normal Delayed";
1710 			break;
1711 		case sStatusAlarm:
1712 			lstatus = "Alarm";
1713 			break;
1714 		case sStatusAlarmDelayed:
1715 			lstatus = "Alarm Delayed";
1716 			break;
1717 		case sStatusMotion:
1718 			lstatus = "Motion";
1719 			break;
1720 		case sStatusNoMotion:
1721 			lstatus = "No Motion";
1722 			break;
1723 		case sStatusPanic:
1724 			lstatus = "Panic";
1725 			break;
1726 		case sStatusPanicOff:
1727 			lstatus = "Panic End";
1728 			break;
1729 		case sStatusArmAway:
1730 			lstatus = "Arm Away";
1731 			break;
1732 		case sStatusArmAwayDelayed:
1733 			lstatus = "Arm Away Delayed";
1734 			break;
1735 		case sStatusArmHome:
1736 			lstatus = "Arm Home";
1737 			break;
1738 		case sStatusArmHomeDelayed:
1739 			lstatus = "Arm Home Delayed";
1740 			break;
1741 		case sStatusDisarm:
1742 			lstatus = "Disarm";
1743 			break;
1744 		case sStatusLightOff:
1745 			lstatus = "Light Off";
1746 			break;
1747 		case sStatusLightOn:
1748 			lstatus = "Light On";
1749 			break;
1750 		case sStatusLight2Off:
1751 			lstatus = "Light 2 Off";
1752 			break;
1753 		case sStatusLight2On:
1754 			lstatus = "Light 2 On";
1755 			break;
1756 		case sStatusDark:
1757 			lstatus = "Dark detected";
1758 			break;
1759 		case sStatusLight:
1760 			lstatus = "Light Detected";
1761 			break;
1762 		case sStatusBatLow:
1763 			lstatus = "Battery low MS10 or XX18 sensor";
1764 			break;
1765 		case sStatusPairKD101:
1766 			lstatus = "Pair KD101";
1767 			break;
1768 		case sStatusNormalTamper:
1769 			lstatus = "Normal + Tamper";
1770 			break;
1771 		case sStatusNormalDelayedTamper:
1772 			lstatus = "Normal Delayed + Tamper";
1773 			break;
1774 		case sStatusAlarmTamper:
1775 			lstatus = "Alarm + Tamper";
1776 			break;
1777 		case sStatusAlarmDelayedTamper:
1778 			lstatus = "Alarm Delayed + Tamper";
1779 			break;
1780 		case sStatusMotionTamper:
1781 			lstatus = "Motion + Tamper";
1782 			break;
1783 		case sStatusNoMotionTamper:
1784 			lstatus = "No Motion + Tamper";
1785 			break;
1786 		}
1787 		break;
1788 	case pTypeSecurity2:
1789 		llevel = 0;
1790 		switch (nValue)
1791 		{
1792 		case 0:
1793 			lstatus = "Normal";
1794 			break;
1795 		}
1796 		break;
1797 	case pTypeRego6XXValue:
1798 		switch (nValue)
1799 		{
1800 		case 0:
1801 			lstatus = "Off";
1802 			break;
1803 		case 1:
1804 			lstatus = "On";
1805 			break;
1806 		}
1807 		break;
1808 	case pTypeCurtain:
1809 		switch (nValue)
1810 		{
1811 		case curtain_sOpen:
1812 			lstatus = "Off";
1813 			break;
1814 		case curtain_sClose:
1815 			lstatus = "On";
1816 			break;
1817 		case curtain_sStop:
1818 			lstatus = "Stop";
1819 			break;
1820 		}
1821 		break;
1822 	case pTypeBlinds:
1823 		switch (nValue)
1824 		{
1825 		case blinds_sOpen:
1826 			if (dSubType == sTypeBlindsT10)
1827 				lstatus = "On";
1828 			else
1829 				lstatus = "Off";
1830 			break;
1831 		case blinds_sClose:
1832 			if (dSubType == sTypeBlindsT10)
1833 				lstatus = "Off";
1834 			else
1835 				lstatus = "On";
1836 			break;
1837 		case blinds_sStop:
1838 			lstatus = "Stop";
1839 			break;
1840 		case blinds_sConfirm:
1841 			lstatus = "Confirm";
1842 			break;
1843 		case blinds_sLimit:
1844 			lstatus = "Limit";
1845 			break;
1846 		case blinds_slowerLimit:
1847 			lstatus = "Lower Limit";
1848 			break;
1849 		case blinds_sDeleteLimits:
1850 			lstatus = "Delete Limits";
1851 			break;
1852 		case blinds_sChangeDirection:
1853 			lstatus = "Change Direction";
1854 			break;
1855 		case blinds_sLeft:
1856 			lstatus = "Left";
1857 			break;
1858 		case blinds_sRight:
1859 			lstatus = "Right";
1860 			break;
1861 		}
1862 		break;
1863 	case pTypeRFY:
1864 		if (switchtype == STYPE_OnOff)
1865 		{
1866 			switch (nValue)
1867 			{
1868 			case rfy_sUp:
1869 				lstatus = "On";
1870 				break;
1871 			case rfy_sDown:
1872 				lstatus = "Off";
1873 				break;
1874 			case rfy_sStop:
1875 				lstatus = "Stop";
1876 				break;
1877 			}
1878 		}
1879 		else
1880 		{
1881 			switch (nValue)
1882 			{
1883 			case rfy_sUp:
1884 				lstatus = "Off";
1885 				break;
1886 			case rfy_sDown:
1887 				lstatus = "On";
1888 				break;
1889 			case rfy_sStop:
1890 				lstatus = "Stop";
1891 				break;
1892 			case rfy_s05SecUp:
1893 				if (switchtype == STYPE_VenetianBlindsUS)
1894 				{
1895 					lstatus = "Off";
1896 				}
1897 				break;
1898 			case rfy_s2SecUp:
1899 				if (switchtype == STYPE_VenetianBlindsEU)
1900 				{
1901 					lstatus = "Off";
1902 				}
1903 				break;
1904 			case rfy_s05SecDown:
1905 				if (switchtype == STYPE_VenetianBlindsUS)
1906 				{
1907 					lstatus = "On";
1908 				}
1909 				break;
1910 			case rfy_s2SecDown:
1911 				if (switchtype == STYPE_VenetianBlindsEU)
1912 				{
1913 					lstatus = "On";
1914 				}
1915 				break;
1916 			case rfy_sEnableSunWind:
1917 				lstatus = "SunWindChange";
1918 				break;
1919 			case rfy_sDisableSun:
1920 				lstatus = "SunWindChange";
1921 				break;
1922 			}
1923 		}
1924 		break;
1925 	case pTypeChime:
1926 		lstatus = "On";
1927 		break;
1928 	case pTypeRemote:
1929 		lstatus = "On";
1930 		break;
1931 	case pTypeThermostat2:
1932 		switch (nValue)
1933 		{
1934 		case thermostat2_sOff:
1935 			lstatus = "Off";
1936 			break;
1937 		case thermostat2_sOn:
1938 			lstatus = "On";
1939 			break;
1940 		}
1941 		break;
1942 	case pTypeThermostat3:
1943 		switch (nValue)
1944 		{
1945 		case thermostat3_sOff:
1946 			lstatus = "Off";
1947 			break;
1948 		case thermostat3_sOn:
1949 			lstatus = "On";
1950 			break;
1951 		case thermostat3_sUp:
1952 			lstatus = "Up";
1953 			break;
1954 		case thermostat3_sDown:
1955 			lstatus = "Down";
1956 			break;
1957 		case thermostat3_sRunUp:
1958 			if (dSubType == sTypeMertikG6RH4T1)
1959 				lstatus = "Run Up";
1960 			else
1961 				lstatus = "2nd Off";
1962 			break;
1963 		case thermostat3_sRunDown:
1964 			if (dSubType == sTypeMertikG6RH4T1)
1965 				lstatus = "Run Down";
1966 			else
1967 				lstatus = "2nd On";
1968 			break;
1969 		case thermostat3_sStop:
1970 			lstatus = "Stop";
1971 			break;
1972 		}
1973 		break;
1974 	case pTypeThermostat4:
1975 		switch (nValue)
1976 		{
1977 		case thermostat4_sOff:
1978 			lstatus = "Off";
1979 			break;
1980 		case thermostat4_sManual:
1981 			lstatus = "Manual";
1982 			break;
1983 		case thermostat4_sAuto:
1984 			lstatus = "Auto";
1985 			break;
1986 		case thermostat4_sEco:
1987 			lstatus = "Eco";
1988 			break;
1989 		}
1990 		break;
1991 	case pTypeRadiator1:
1992 		switch (nValue)
1993 		{
1994 		case Radiator1_sNight:
1995 			lstatus = "Off";
1996 			break;
1997 		case Radiator1_sDay:
1998 			lstatus = "On";
1999 			break;
2000 		case Radiator1_sSetTemp:
2001 			lstatus = "On";
2002 			break;
2003 		}
2004 		break;
2005 	case pTypeEvohome:
2006 		llevel = 0;
2007 		lstatus = CEvohomeBase::GetWebAPIModeName(nValue);
2008 		break;
2009 	case pTypeEvohomeRelay:
2010 		bHaveDimmer = true;
2011 		maxDimLevel = 200;
2012 		llevel = int(0.5f * atof(sValue.c_str()));
2013 		switch (nValue)
2014 		{
2015 		case light1_sOff:
2016 			lstatus = "Off";
2017 			break;
2018 		case light1_sOn:
2019 			sprintf(szTmp, "Set Level: %d %%", llevel);
2020 			if (llevel == 100) {
2021 				lstatus = "On";
2022 			}
2023 			else {
2024 				lstatus = szTmp;
2025 			}
2026 			break;
2027 		}
2028 		break;
2029 	case pTypeFan:
2030 		switch (dSubType)
2031 		{
2032 		case sTypeSiemensSF01:
2033 		{
2034 			switch (nValue)
2035 			{
2036 			case fan_sTimer:
2037 				lstatus = "timer";
2038 				break;
2039 			case fan_sPlus:
2040 				lstatus = "+";
2041 				break;
2042 			case fan_sMin:
2043 				lstatus = "-";
2044 				break;
2045 			case fan_sLearn:
2046 				lstatus = "learn";
2047 				break;
2048 			case fan_sConfirm:
2049 				lstatus = "confirm";
2050 				break;
2051 			case fan_sLight:
2052 				lstatus = "light";
2053 				break;
2054 			}
2055 		}
2056 		break;
2057 		case sTypeItho:
2058 		{
2059 			switch (nValue)
2060 			{
2061 			case fan_Itho1:
2062 				lstatus = "1";
2063 				break;
2064 			case fan_Itho2:
2065 				lstatus = "2";
2066 				break;
2067 			case fan_Itho3:
2068 				lstatus = "3";
2069 				break;
2070 			case fan_IthoTimer:
2071 				lstatus = "timer";
2072 				break;
2073 			case fan_IthoNotAtHome:
2074 				lstatus = "notathome";
2075 				break;
2076 			case fan_IthoLearn:
2077 				lstatus = "learn";
2078 				break;
2079 			case fan_IthoEraseAll:
2080 				lstatus = "eraseall";
2081 				break;
2082 			}
2083 		}
2084 		break;
2085 		case sTypeLucciAir:
2086 		case sTypeWestinghouse:
2087 		{
2088 			switch (nValue)
2089 			{
2090 			case fan_LucciHi:
2091 				lstatus = "hi";
2092 				break;
2093 			case fan_LucciMed:
2094 				lstatus = "med";
2095 				break;
2096 			case fan_LucciLow:
2097 				lstatus = "low";
2098 				break;
2099 			case fan_LucciOff:
2100 				lstatus = "off";
2101 				break;
2102 			case fan_LucciLight:
2103 				lstatus = "light";
2104 				break;
2105 			}
2106 		}
2107 		break;
2108 		case sTypeLucciAirDC:
2109 		{
2110 			switch (nValue)
2111 			{
2112 			case fan_LucciDCPower:
2113 				lstatus = "pow";
2114 				break;
2115 			case fan_LucciDCPlus:
2116 				lstatus = "plus";
2117 				break;
2118 			case fan_LucciDCMin:
2119 				lstatus = "min";
2120 				break;
2121 			case fan_LucciDCLight:
2122 				lstatus = "light";
2123 				break;
2124 			case fan_LucciDCReverse:
2125 				lstatus = "rev";
2126 				break;
2127 			case fan_LucciDCNaturalflow:
2128 				lstatus = "nat";
2129 				break;
2130 			}
2131 		}
2132 		break;
2133 		}
2134 		break;
2135 	case pTypeHunter:
2136 		switch (dSubType)
2137 		{
2138 		case sTypeHunterfan:
2139 		{
2140 			switch (nValue)
2141 			{
2142 			case HunterOff:
2143 				lstatus = "off";
2144 				break;
2145 			case HunterLight:
2146 				lstatus = "light";
2147 				break;
2148 			case HunterSpeed1:
2149 				lstatus = "low";
2150 				break;
2151 			case HunterSpeed2:
2152 				lstatus = "med";
2153 				break;
2154 			case HunterSpeed3:
2155 				lstatus = "high";
2156 				break;
2157 			}
2158 		}
2159 		break;
2160 		}
2161 		break;
2162 	}
2163 	//_log.Debug(DEBUG_NORM, "RFXN : GetLightStatus Typ:%2d STyp:%2d nVal:%d sVal:%-4s llvl:%2d isDim:%d maxDim:%2d GrpCmd:%d lstat:%s",
2164 	//dType, dSubType, nValue, sValue.c_str(), llevel, bHaveDimmer, maxDimLevel, bHaveGroupCmd, lstatus.c_str());
2165 }
2166 
2167 /**
2168 * Returns a map associating a level value to its name.
2169 */
GetSelectorSwitchStatuses(const std::map<std::string,std::string> & options,std::map<std::string,std::string> & statuses)2170 void GetSelectorSwitchStatuses(const std::map<std::string, std::string>& options, std::map<std::string, std::string>& statuses) {
2171 	std::map< std::string, std::string >::const_iterator itt = options.find("LevelNames");
2172 	if (itt != options.end()) {
2173 		//_log.Log(LOG_STATUS, "DEBUG : Get selector switch statuses...");
2174 		std::string sOptions = itt->second;
2175 		std::vector<std::string> strarray;
2176 		StringSplit(sOptions, "|", strarray);
2177 		int i = 0;
2178 		std::stringstream ss;
2179 		for (const auto& itt : strarray)
2180 		{
2181 			ss.clear();
2182 			ss.str("");
2183 			ss << i;
2184 			std::string level(ss.str());
2185 			std::string levelName = itt;
2186 			//_log.Log(LOG_STATUS, "DEBUG : Get selector status '%s' for level %s", levelName.c_str(), level.c_str());
2187 			statuses.insert(std::pair<std::string, std::string>(level.c_str(), levelName.c_str()));
2188 			i += 10;
2189 		}
2190 	}
2191 }
2192 
2193 /**
2194 * Returns the level value associated to a name.
2195 */
GetSelectorSwitchLevel(const std::map<std::string,std::string> & options,const std::string & levelName)2196 int GetSelectorSwitchLevel(const std::map<std::string, std::string>& options, const std::string& levelName) {
2197 	int level = -1; // not found
2198 	std::map< std::string, std::string >::const_iterator itt = options.find("LevelNames");
2199 	if (itt != options.end()) {
2200 		//_log.Log(LOG_STATUS, "DEBUG : Get selector switch level...");
2201 		std::string sOptions = itt->second;
2202 		std::vector<std::string> strarray;
2203 		StringSplit(sOptions, "|", strarray);
2204 		int i = 0;
2205 		for (const auto& itt : strarray)
2206 		{
2207 			if (itt == levelName)
2208 			{
2209 				level = i;
2210 				break;
2211 			}
2212 			i += 10;
2213 		}
2214 	}
2215 	return level;
2216 }
2217 
2218 /**
2219 * Returns the action associated with a level
2220 */
GetSelectorSwitchLevelAction(const std::map<std::string,std::string> & options,const int level)2221 std::string GetSelectorSwitchLevelAction(const std::map<std::string, std::string>& options, const int level) {
2222 	std::map< std::string, std::string >::const_iterator itt = options.find("LevelActions");
2223 	if (itt != options.end()) {
2224 		//_log.Log(LOG_STATUS, "DEBUG : Get selector switch level action...");
2225 		std::string sOptions = itt->second;
2226 		std::vector<std::string> strarray;
2227 		StringSplit(sOptions, "|", strarray);
2228 		int i = 0;
2229 		for (const auto& itt : strarray)
2230 		{
2231 			if (i == level)
2232 			{
2233 				return itt;
2234 			}
2235 			i += 10;
2236 		}
2237 	}
2238 	return "";
2239 }
2240 
GetLightCommand(const unsigned char dType,const unsigned char dSubType,_eSwitchType switchtype,std::string switchcmd,unsigned char & cmd,const std::map<std::string,std::string> & options)2241 bool GetLightCommand(
2242 	const unsigned char dType,
2243 	const unsigned char dSubType,
2244 	_eSwitchType switchtype,
2245 	std::string switchcmd,
2246 	unsigned char& cmd,
2247 	const std::map<std::string, std::string>& options
2248 )
2249 {
2250 	if (switchtype == STYPE_Contact && dType != pTypeGeneralSwitch)
2251 		return false;	//we can not (or will not) switch this type
2252 
2253 	switch (dType)
2254 	{
2255 	case pTypeLighting1:
2256 		if (switchtype == STYPE_Doorbell)
2257 		{
2258 			if (dSubType == sTypeARC)
2259 			{
2260 				if ((switchcmd == "On") || (switchcmd == "Group On") || (switchcmd == "Chime"))
2261 				{
2262 					cmd = light1_sChime;
2263 					return true;
2264 				}
2265 			}
2266 			else
2267 			{
2268 				//not sure yet, maybe more devices need the above chime command
2269 				if ((switchcmd == "On") || (switchcmd == "Group On"))
2270 				{
2271 					cmd = light1_sAllOn;
2272 					return true;
2273 				}
2274 			}
2275 			//no other combinations for the door switch
2276 			return false;
2277 		}
2278 		else if (switchtype == STYPE_X10Siren)
2279 		{
2280 			if ((switchcmd == "On") || (switchcmd == "All On"))
2281 			{
2282 				cmd = light1_sAllOn;
2283 				return true;
2284 			}
2285 			else if ((switchcmd == "Off") || (switchcmd == "All Off"))
2286 			{
2287 				cmd = light1_sAllOff;
2288 				return true;
2289 			}
2290 			return false;
2291 		}
2292 		if (switchcmd == "Off")
2293 		{
2294 			cmd = light1_sOff;
2295 			return true;
2296 		}
2297 		else if (switchcmd == "On") {
2298 			cmd = light1_sOn;
2299 			return true;
2300 		}
2301 		else if (switchcmd == "Dim") {
2302 			cmd = light1_sDim;
2303 			return true;
2304 		}
2305 		else if (switchcmd == "Bright") {
2306 			cmd = light1_sBright;
2307 			return true;
2308 		}
2309 		else if (switchcmd == "All On") {
2310 			cmd = light1_sAllOn;
2311 			return true;
2312 		}
2313 		else if (switchcmd == "All Off") {
2314 			cmd = light1_sAllOff;
2315 			return true;
2316 		}
2317 		else if (switchcmd == "Chime") {
2318 			cmd = light1_sChime;
2319 			return true;
2320 		}
2321 		else
2322 			return false;
2323 		break;
2324 	case pTypeLighting2:
2325 		if (switchtype == STYPE_Doorbell)
2326 		{
2327 			if ((switchcmd == "On") || (switchcmd == "Group On"))
2328 			{
2329 				cmd = light2_sGroupOn;
2330 				return true;
2331 			}
2332 			//no other combinations for the door switch
2333 			return false;
2334 		}
2335 		else if (switchtype == STYPE_X10Siren)
2336 		{
2337 			if ((switchcmd == "On") || (switchcmd == "Group On"))
2338 			{
2339 				cmd = light2_sGroupOn;
2340 				return true;
2341 			}
2342 			else if ((switchcmd == "Off") || (switchcmd == "Group Off"))
2343 			{
2344 				cmd = light2_sGroupOff;
2345 				return true;
2346 			}
2347 			return false;
2348 		}
2349 		if (switchcmd == "Off")
2350 		{
2351 			cmd = light2_sOff;
2352 			return true;
2353 		}
2354 		else if (switchcmd == "On")
2355 		{
2356 			cmd = light2_sOn;
2357 			return true;
2358 		}
2359 		else if (switchcmd == "Set Level")
2360 		{
2361 			cmd = light2_sSetLevel;
2362 			return true;
2363 		}
2364 		else if (switchcmd == "Group Off")
2365 		{
2366 			cmd = light2_sGroupOff;
2367 			return true;
2368 		}
2369 		else if (switchcmd == "Group On")
2370 		{
2371 			cmd = light2_sGroupOn;
2372 			return true;
2373 		}
2374 		else if (switchcmd == "Set Group Level")
2375 		{
2376 			cmd = light2_sSetGroupLevel;
2377 			return true;
2378 		}
2379 		else if (switchcmd == "Stop")
2380 		{
2381 			cmd = gswitch_sStop;
2382 			return true;
2383 		}
2384 		else if ((switchcmd == "Paused") || (switchcmd == "Pause"))
2385 		{
2386 			cmd = gswitch_sPause;
2387 			return true;
2388 		}
2389 		else if ((switchcmd == "Playing") || (switchcmd == "Play"))
2390 		{
2391 			cmd = gswitch_sPlay;
2392 			return true;
2393 		}
2394 		else if (switchcmd == "Play Playlist")
2395 		{
2396 			cmd = gswitch_sPlayPlaylist;
2397 			return true;
2398 		}
2399 		else if (switchcmd == "Play Favorites")
2400 		{
2401 			cmd = gswitch_sPlayFavorites;
2402 			return true;
2403 		}
2404 		else if (switchcmd == "Set Volume")
2405 		{
2406 			cmd = gswitch_sSetVolume;
2407 			return true;
2408 		}
2409 		else if (switchcmd == "Execute")
2410 		{
2411 			cmd = gswitch_sExecute;
2412 			return true;
2413 		}
2414 		else
2415 			return false;
2416 		break;
2417 	case pTypeLighting4:
2418 		cmd = light2_sOn;
2419 		return true;
2420 	case pTypeLighting5:
2421 		if (dSubType == sTypeLivolo)
2422 		{
2423 			if (switchcmd == "Set Level")
2424 			{
2425 				cmd = light5_sLivoloGang2Toggle;
2426 				return true;
2427 			}
2428 		}
2429 		else if ((dSubType == sTypeTRC02) || (dSubType == sTypeTRC02_2))
2430 		{
2431 			if (switchcmd == "Set Color")
2432 			{
2433 				cmd = light5_sRGBcolormin + 1; //color set is light5_sRGBcolormin+1 till 255?
2434 				return true;
2435 			}
2436 		}
2437 		else if ((dSubType != sTypeLightwaveRF) && (dSubType != sTypeIT))
2438 		{
2439 			//Only LightwaveRF/IT devices have a set-level
2440 			if (switchcmd == "Set Level")
2441 				switchcmd = "On";
2442 		}
2443 		else if ((dSubType == sTypeLightwaveRF) && (switchtype == STYPE_VenetianBlindsEU))
2444 		{
2445 			// The LightwaveRF inline relay has to be controlled by Venetian blinds logic as it has a stop setting
2446 			if (switchcmd == "On")
2447 				switchcmd = "Close inline relay";
2448 			else if (switchcmd == "Off")
2449 				switchcmd = "Open inline relay";
2450 			else if (switchcmd == "Stop")
2451 				switchcmd = "Stop inline relay";
2452 		}
2453 
2454 		if (switchtype == STYPE_Doorbell)
2455 		{
2456 			if ((switchcmd == "On") || (switchcmd == "Group On"))
2457 			{
2458 				cmd = light5_sGroupOn;
2459 				return true;
2460 			}
2461 			//no other combinations for the door switch
2462 			return false;
2463 		}
2464 		else if (switchtype == STYPE_X10Siren)
2465 		{
2466 			if ((switchcmd == "On") || (switchcmd == "Group On"))
2467 			{
2468 				cmd = light5_sGroupOn;
2469 				return true;
2470 			}
2471 			else if ((switchcmd == "Off") || (switchcmd == "Group Off"))
2472 			{
2473 				cmd = light5_sGroupOff;
2474 				return true;
2475 			}
2476 			return false;
2477 		}
2478 		if (switchcmd == "Off")
2479 		{
2480 			cmd = light5_sOff;
2481 			return true;
2482 		}
2483 		else if (switchcmd == "On")
2484 		{
2485 			cmd = light5_sOn;
2486 			return true;
2487 		}
2488 		else if (switchcmd == "Set Level")
2489 		{
2490 			cmd = light5_sSetLevel;
2491 			return true;
2492 		}
2493 		else if (switchcmd == "Group Off")
2494 		{
2495 			cmd = light5_sGroupOff;
2496 			return true;
2497 		}
2498 		else if (switchcmd == "Group On")
2499 		{
2500 			cmd = light5_sGroupOn;
2501 			return true;
2502 		}
2503 		else if (switchcmd == "Close inline relay")
2504 		{
2505 			cmd = light5_sClose;
2506 			return true;
2507 		}
2508 		else if (switchcmd == "Stop inline relay")
2509 		{
2510 			cmd = light5_sStop;
2511 			return true;
2512 		}
2513 		else if (switchcmd == "Open inline relay")
2514 		{
2515 			cmd = light5_sOpen;
2516 			return true;
2517 		}
2518 		else if (switchcmd == "Group Mood 1")
2519 		{
2520 			cmd = light5_sMood1;
2521 			return true;
2522 		}
2523 		else if (switchcmd == "Group Mood 2")
2524 		{
2525 			cmd = light5_sMood2;
2526 			return true;
2527 		}
2528 		else if (switchcmd == "Group Mood 3")
2529 		{
2530 			cmd = light5_sMood3;
2531 			return true;
2532 		}
2533 		else if (switchcmd == "Group Mood 4")
2534 		{
2535 			cmd = light5_sMood4;
2536 			return true;
2537 		}
2538 		else if (switchcmd == "Group Mood 5")
2539 		{
2540 			cmd = light5_sMood5;
2541 			return true;
2542 		}
2543 		else
2544 			return false;
2545 		break;
2546 	case pTypeLighting6:
2547 		if (switchcmd == "Off")
2548 		{
2549 			cmd = light6_sOff;
2550 			return true;
2551 		}
2552 		else if (switchcmd == "On")
2553 		{
2554 			cmd = light6_sOn;
2555 			return true;
2556 		}
2557 		else if (switchcmd == "Group Off")
2558 		{
2559 			cmd = light6_sGroupOff;
2560 			return true;
2561 		}
2562 		else if (switchcmd == "Group On")
2563 		{
2564 			cmd = light6_sGroupOn;
2565 			return true;
2566 		}
2567 		else
2568 			return false;
2569 		break;
2570 	case pTypeHomeConfort:
2571 		if (switchtype == STYPE_Doorbell)
2572 		{
2573 			if ((switchcmd == "On") || (switchcmd == "Group On"))
2574 			{
2575 				cmd = HomeConfort_sGroupOn;
2576 				return true;
2577 			}
2578 			//no other combinations for the door switch
2579 			return false;
2580 		}
2581 		if (switchcmd == "Off")
2582 		{
2583 			cmd = HomeConfort_sOff;
2584 			return true;
2585 		}
2586 		else if (switchcmd == "On")
2587 		{
2588 			cmd = HomeConfort_sOn;
2589 			return true;
2590 		}
2591 		else if (switchcmd == "Group Off")
2592 		{
2593 			cmd = HomeConfort_sGroupOff;
2594 			return true;
2595 		}
2596 		else if (switchcmd == "Group On")
2597 		{
2598 			cmd = HomeConfort_sGroupOn;
2599 			return true;
2600 		}
2601 		else
2602 			return false;
2603 		break;
2604 	case pTypeFS20:
2605 		if (switchcmd == "Off")
2606 		{
2607 			cmd = fs20_sOff;
2608 			return true;
2609 		}
2610 		if ((switchcmd == "Dim1") || (switchcmd == "Set Level"))
2611 		{
2612 			cmd = fs20_sDimlevel_1;
2613 			return true;
2614 		}
2615 		if (switchcmd == "Dim2")
2616 		{
2617 			cmd = fs20_sDimlevel_2;
2618 			return true;
2619 		}
2620 		if (switchcmd == "Dim3")
2621 		{
2622 			cmd = fs20_sDimlevel_3;
2623 			return true;
2624 		}
2625 		if (switchcmd == "Dim4")
2626 		{
2627 			cmd = fs20_sDimlevel_4;
2628 			return true;
2629 		}
2630 		if (switchcmd == "Dim5")
2631 		{
2632 			cmd = fs20_sDimlevel_5;
2633 			return true;
2634 		}
2635 		if (switchcmd == "Dim6")
2636 		{
2637 			cmd = fs20_sDimlevel_6;
2638 			return true;
2639 		}
2640 		if (switchcmd == "Dim7")
2641 		{
2642 			cmd = fs20_sDimlevel_7;
2643 			return true;
2644 		}
2645 		if (switchcmd == "Dim8")
2646 		{
2647 			cmd = fs20_sDimlevel_8;
2648 			return true;
2649 		}
2650 		if (switchcmd == "Dim9")
2651 		{
2652 			cmd = fs20_sDimlevel_9;
2653 			return true;
2654 		}
2655 		if (switchcmd == "Dim10")
2656 		{
2657 			cmd = fs20_sDimlevel_10;
2658 			return true;
2659 		}
2660 		if (switchcmd == "Dim11")
2661 		{
2662 			cmd = fs20_sDimlevel_11;
2663 			return true;
2664 		}
2665 		if (switchcmd == "Dim12")
2666 		{
2667 			cmd = fs20_sDimlevel_12;
2668 			return true;
2669 		}
2670 		if (switchcmd == "Dim13")
2671 		{
2672 			cmd = fs20_sDimlevel_13;
2673 			return true;
2674 		}
2675 		if (switchcmd == "Dim14")
2676 		{
2677 			cmd = fs20_sDimlevel_14;
2678 			return true;
2679 		}
2680 		if (switchcmd == "Dim15")
2681 		{
2682 			cmd = fs20_sDimlevel_15;
2683 			return true;
2684 		}
2685 		if (switchcmd == "On")
2686 		{
2687 			cmd = fs20_sOn_100;
2688 			return true;
2689 		}
2690 		if (switchcmd == "OnDim")
2691 		{
2692 			cmd = fs20_sOn_last_dim;
2693 			return true;
2694 		}
2695 		if (switchcmd == "Toggle")
2696 		{
2697 			cmd = fs20_sToggle_On_Off;
2698 			return true;
2699 		}
2700 		if (switchcmd == "StartDim")
2701 		{
2702 			cmd = fs20_sStart_dim_cycle;
2703 			return true;
2704 		}
2705 		if (switchcmd == "Program")
2706 		{
2707 			cmd = fs20_sProgram_timer;
2708 			return true;
2709 		}
2710 		if (switchcmd == "Request")
2711 		{
2712 			cmd = fs20_sRequest_status;
2713 			return true;
2714 		}
2715 		if (switchcmd == "OffTime")
2716 		{
2717 			cmd = fs20_sOff_for_time_period;
2718 			return true;
2719 		}
2720 		if (switchcmd == "OnTime")
2721 		{
2722 			cmd = fs20_sOn_100_for_time_period;
2723 			return true;
2724 		}
2725 		if (switchcmd == "OnDimTime")
2726 		{
2727 			cmd = fs20_sOn_last_dim_level_period;
2728 			return true;
2729 		}
2730 		if (switchcmd == "Reset")
2731 		{
2732 			cmd = fs20_sReset;
2733 			return true;
2734 		}
2735 		return false;
2736 		break;
2737 	case pTypeGeneralSwitch:
2738 		if (switchtype == STYPE_Doorbell)
2739 		{
2740 			if ((switchcmd == "On") || (switchcmd == "Group On"))
2741 			{
2742 				cmd = gswitch_sGroupOn;
2743 				return true;
2744 			}
2745 			//no other combinations for the door switch
2746 			return false;
2747 		}
2748 		else if (switchtype == STYPE_X10Siren)
2749 		{
2750 			if ((switchcmd == "On") || (switchcmd == "Group On"))
2751 			{
2752 				cmd = gswitch_sGroupOn;
2753 				return true;
2754 			}
2755 			else if ((switchcmd == "Off") || (switchcmd == "Group Off"))
2756 			{
2757 				cmd = gswitch_sGroupOff;
2758 				return true;
2759 			}
2760 			return false;
2761 		}
2762 		else if (switchtype == STYPE_Selector) {
2763 			if ((switchcmd == "Paused") ||
2764 				(switchcmd == "Pause") ||
2765 				(switchcmd == "Playing") ||
2766 				(switchcmd == "Play") ||
2767 				(switchcmd == "Play Playlist") ||
2768 				(switchcmd == "Play Favorites") ||
2769 				(switchcmd == "Set Volume")) {
2770 				// Not a managed command
2771 				return false;
2772 			}
2773 			int level = GetSelectorSwitchLevel(options, switchcmd);
2774 			if (level > 0) { // not Off but a level name
2775 							 // switchcmd cannot be a level name
2776 				return false;
2777 			}
2778 		}
2779 
2780 		if (switchcmd == "Off")
2781 		{
2782 			cmd = gswitch_sOff;
2783 			return true;
2784 		}
2785 		if (switchcmd == "On")
2786 		{
2787 			cmd = gswitch_sOn;
2788 			return true;
2789 		}
2790 		if (switchcmd == "Set Level")
2791 		{
2792 			cmd = gswitch_sSetLevel;
2793 			return true;
2794 		}
2795 		if (switchcmd == "Group Off")
2796 		{
2797 			cmd = gswitch_sGroupOff;
2798 			return true;
2799 		}
2800 		if (switchcmd == "Group On")
2801 		{
2802 			cmd = gswitch_sGroupOn;
2803 			return true;
2804 		}
2805 		if (switchcmd == "Set Group Level")
2806 		{
2807 			cmd = gswitch_sSetGroupLevel;
2808 			return true;
2809 		}
2810 		if (switchcmd == "Dim")
2811 		{
2812 			cmd = gswitch_sDim;
2813 			return true;
2814 		}
2815 		if (switchcmd == "Bright")
2816 		{
2817 			cmd = gswitch_sBright;
2818 			return true;
2819 		}
2820 		if (switchcmd == "Sound 0")
2821 		{
2822 			cmd = gswitch_sSound0;
2823 			return true;
2824 		}
2825 		if (switchcmd == "Sound 1")
2826 		{
2827 			cmd = gswitch_sSound1;
2828 			return true;
2829 		}
2830 		if (switchcmd == "Sound 2")
2831 		{
2832 			cmd = gswitch_sSound2;
2833 			return true;
2834 		}
2835 		if (switchcmd == "Sound 3")
2836 		{
2837 			cmd = gswitch_sSound3;
2838 			return true;
2839 		}
2840 		if (switchcmd == "Sound 4")
2841 		{
2842 			cmd = gswitch_sSound4;
2843 			return true;
2844 		}
2845 		if (switchcmd == "Sound 5")
2846 		{
2847 			cmd = gswitch_sSound5;
2848 			return true;
2849 		}
2850 		if (switchcmd == "Sound 6")
2851 		{
2852 			cmd = gswitch_sSound6;
2853 			return true;
2854 		}
2855 		if (switchcmd == "Sound 7")
2856 		{
2857 			cmd = gswitch_sSound7;
2858 			return true;
2859 		}
2860 		if (switchcmd == "Sound 8")
2861 		{
2862 			cmd = gswitch_sSound8;
2863 			return true;
2864 		}
2865 		if (switchcmd == "Stop")
2866 		{
2867 			cmd = gswitch_sStop;
2868 			return true;
2869 		}
2870 		if (switchcmd == "Program")
2871 		{
2872 			cmd = gswitch_sProgram;
2873 			return true;
2874 		}
2875 		break;
2876 	case pTypeColorSwitch:
2877 		if (switchcmd == "Off")
2878 		{
2879 			cmd = Color_LedOff;
2880 			return true;
2881 		}
2882 		else if (switchcmd == "On")
2883 		{
2884 			cmd = Color_LedOn;
2885 			return true;
2886 		}
2887 		else if (switchcmd == "Set Color")
2888 		{
2889 			cmd = Color_SetColor;
2890 			return true;
2891 		}
2892 		else if (
2893 			(switchcmd == "Set Brightness") ||
2894 			(switchcmd == "Set Level")
2895 			)
2896 		{
2897 			cmd = Color_SetBrightnessLevel;
2898 			return true;
2899 		}
2900 		else if (switchcmd == "Set White")
2901 		{
2902 			cmd = Color_SetColorToWhite;
2903 			return true;
2904 		}
2905 		else if (switchcmd == "Set Full")
2906 		{
2907 			cmd = Color_SetColorToWhite;
2908 			return true;
2909 		}
2910 		else if (switchcmd == "Set Night")
2911 		{
2912 			cmd = Color_NightMode;
2913 			return true;
2914 		}
2915 		else if (switchcmd == "Bright Up")
2916 		{
2917 			cmd = Color_SetBrightUp;
2918 			return true;
2919 		}
2920 		else if (switchcmd == "Bright Down")
2921 		{
2922 			cmd = Color_SetBrightDown;
2923 			return true;
2924 		}
2925 		else if (switchcmd == "Disco Mode")
2926 		{
2927 			cmd = Color_DiscoMode;
2928 			return true;
2929 		}
2930 		else if (switchcmd == "Disco Mode 1")
2931 		{
2932 			cmd = Color_DiscoMode_1;
2933 			return true;
2934 		}
2935 		else if (switchcmd == "Disco Mode 2")
2936 		{
2937 			cmd = Color_DiscoMode_2;
2938 			return true;
2939 		}
2940 		else if (switchcmd == "Disco Mode 3")
2941 		{
2942 			cmd = Color_DiscoMode_3;
2943 			return true;
2944 		}
2945 		else if (switchcmd == "Disco Mode 4")
2946 		{
2947 			cmd = Color_DiscoMode_4;
2948 			return true;
2949 		}
2950 		else if (switchcmd == "Disco Mode 5")
2951 		{
2952 			cmd = Color_DiscoMode_5;
2953 			return true;
2954 		}
2955 		else if (switchcmd == "Disco Mode 6")
2956 		{
2957 			cmd = Color_DiscoMode_6;
2958 			return true;
2959 		}
2960 		else if (switchcmd == "Disco Mode 7")
2961 		{
2962 			cmd = Color_DiscoMode_7;
2963 			return true;
2964 		}
2965 		else if (switchcmd == "Disco Mode 8")
2966 		{
2967 			cmd = Color_DiscoMode_8;
2968 			return true;
2969 		}
2970 		else if (switchcmd == "Disco Mode 9")
2971 		{
2972 			cmd = Color_DiscoMode_9;
2973 			return true;
2974 		}
2975 		else if (switchcmd == "Disco Up")
2976 		{
2977 			cmd = Color_RGBDiscoNext;
2978 			return true;
2979 		}
2980 		else if (switchcmd == "Disco Down")
2981 		{
2982 			cmd = Color_RGBDiscoPrevious;
2983 			return true;
2984 		}
2985 		else if (switchcmd == "Speed Up")
2986 		{
2987 			cmd = Color_DiscoSpeedFaster;
2988 			return true;
2989 		}
2990 		else if (switchcmd == "Speed Up Long")
2991 		{
2992 			cmd = Color_DiscoSpeedFasterLong;
2993 			return true;
2994 		}
2995 		else if (switchcmd == "Speed Down")
2996 		{
2997 			cmd = Color_DiscoSpeedSlower;
2998 			return true;
2999 		}
3000 		else if (switchcmd == "Speed Minimal")
3001 		{
3002 			cmd = Color_DiscoSpeedMinimal;
3003 			return true;
3004 		}
3005 		else if (switchcmd == "Speed Maximal")
3006 		{
3007 			cmd = Color_DiscoSpeedMaximal;
3008 			return true;
3009 		}
3010 		else if (switchcmd == "Warmer")
3011 		{
3012 			cmd = Color_WarmWhiteIncrease;
3013 			return true;
3014 		}
3015 		else if (switchcmd == "Cooler")
3016 		{
3017 			cmd = Color_CoolWhiteIncrease;
3018 			return true;
3019 		}
3020 		else
3021 			return false;
3022 		break;
3023 	case pTypeSecurity1:
3024 		if (
3025 			(dSubType == sTypeKD101) ||
3026 			(dSubType == sTypeSA30) ||
3027 			(dSubType == sTypeRM174RF)
3028 			)
3029 		{
3030 			if ((switchcmd == "On") || (switchcmd == "All On"))
3031 			{
3032 				cmd = sStatusPanic;
3033 				return true;
3034 			}
3035 			else if (switchcmd == "Off")
3036 			{
3037 				cmd = sStatusNormal;
3038 				return true;
3039 			}
3040 		}
3041 		else if (dSubType == sTypeSecX10M)
3042 		{
3043 			if (switchcmd == "Motion")
3044 			{
3045 				cmd = sStatusMotion;
3046 				return true;
3047 			}
3048 			else if (switchcmd == "No Motion")
3049 			{
3050 				cmd = sStatusNoMotion;
3051 				return true;
3052 			}
3053 		}
3054 		else if ((dSubType == sTypeSecX10R) || (dSubType == sTypeMeiantech))
3055 		{
3056 			if (switchcmd == "On")
3057 			{
3058 				cmd = sStatusArmAway;
3059 				return true;
3060 			}
3061 			else if (switchcmd == "Off")
3062 			{
3063 				cmd = sStatusDisarm;
3064 				return true;
3065 			}
3066 			else if (switchcmd == "Arm Home")
3067 			{
3068 				cmd = sStatusArmHome;
3069 				return true;
3070 			}
3071 			else if (switchcmd == "Arm Away")
3072 			{
3073 				cmd = sStatusArmAway;
3074 				return true;
3075 			}
3076 			else if (switchcmd == "Panic")
3077 			{
3078 				cmd = sStatusPanic;
3079 				return true;
3080 			}
3081 			else if (switchcmd == "Disarm")
3082 			{
3083 				cmd = sStatusDisarm;
3084 				return true;
3085 			}
3086 		}
3087 		else if (dSubType == sTypeSecX10)
3088 		{
3089 			if (switchcmd == "Normal")
3090 			{
3091 				cmd = sStatusNormal;
3092 				return true;
3093 			}
3094 			else if (switchcmd == "Alarm")
3095 			{
3096 				cmd = sStatusAlarm;
3097 				return true;
3098 			}
3099 			else if (switchcmd == "Normal Delayed")
3100 			{
3101 				cmd = sStatusNormalDelayed;
3102 				return true;
3103 			}
3104 			else if (switchcmd == "Alarm Delayed")
3105 			{
3106 				cmd = sStatusAlarmDelayed;
3107 				return true;
3108 			}
3109 			else if (switchcmd == "Arm Home")
3110 			{
3111 				cmd = sStatusArmHome;
3112 				return true;
3113 			}
3114 			else if (switchcmd == "Arm Home Delayed")
3115 			{
3116 				cmd = sStatusArmHomeDelayed;
3117 				return true;
3118 			}
3119 			else if (switchcmd == "Arm Away")
3120 			{
3121 				cmd = sStatusArmAway;
3122 				return true;
3123 			}
3124 			else if (switchcmd == "Arm Away Delayed")
3125 			{
3126 				cmd = sStatusArmAwayDelayed;
3127 				return true;
3128 			}
3129 			else if (switchcmd == "Panic")
3130 			{
3131 				cmd = sStatusPanic;
3132 				return true;
3133 			}
3134 			else if (switchcmd == "Disarm")
3135 			{
3136 				cmd = sStatusDisarm;
3137 				return true;
3138 			}
3139 			else if (switchcmd == "Light On")
3140 			{
3141 				cmd = sStatusLightOn;
3142 				return true;
3143 			}
3144 			else if (switchcmd == "Light Off")
3145 			{
3146 				cmd = sStatusLightOff;
3147 				return true;
3148 			}
3149 			else if (switchcmd == "Light 2 On")
3150 			{
3151 				cmd = sStatusLight2On;
3152 				return true;
3153 			}
3154 			else if (switchcmd == "Light 2 Off")
3155 			{
3156 				cmd = sStatusLight2Off;
3157 				return true;
3158 			}
3159 		}
3160 		break;
3161 	case pTypeSecurity2:
3162 		cmd = 0;
3163 		return true;
3164 		break;
3165 	case pTypeCurtain:
3166 	{
3167 		if (switchcmd == "On")
3168 		{
3169 			cmd = curtain_sClose;
3170 		}
3171 		else if (switchcmd == "Off")
3172 		{
3173 			cmd = curtain_sOpen;
3174 		}
3175 		else
3176 		{
3177 			cmd = curtain_sStop;
3178 		}
3179 		return true;
3180 	}
3181 	break;
3182 	case pTypeBlinds:
3183 	{
3184 		if (switchcmd == "On")
3185 		{
3186 			if (dSubType == sTypeBlindsT10)
3187 				cmd = blinds_sOpen;
3188 			else
3189 				cmd = blinds_sClose;
3190 		}
3191 		else if (switchcmd == "Off")
3192 		{
3193 			if (dSubType == sTypeBlindsT10)
3194 				cmd = blinds_sClose;
3195 			else
3196 				cmd = blinds_sOpen;
3197 		}
3198 		else
3199 		{
3200 			cmd = blinds_sStop;
3201 		}
3202 		return true;
3203 	}
3204 	break;
3205 	case pTypeRFY:
3206 	{
3207 		if (switchtype == STYPE_OnOff)
3208 		{
3209 			/*
3210 			Venetian Blind in US mode:
3211 			-up / down(transmit < 0.5 seconds) : open or close
3212 			-up / down(transmit > 2seconds) : change angle
3213 
3214 			Venetian Blind in Europe mode :
3215 			-up / down(transmit < 0.5 seconds) : change angle
3216 			-up / down(transmit > 2seconds) : open or close
3217 			*/
3218 			if (switchcmd == "On")
3219 			{
3220 				cmd = rfy_sUp;
3221 			}
3222 			else if (switchcmd == "Off")
3223 			{
3224 				cmd = rfy_sDown;
3225 			}
3226 		}
3227 		else
3228 		{
3229 			/*
3230 			Venetian Blind in US mode:
3231 			-up / down(transmit < 0.5 seconds) : open or close
3232 			-up / down(transmit > 2seconds) : change angle
3233 
3234 			Venetian Blind in Europe mode :
3235 			-up / down(transmit < 0.5 seconds) : change angle
3236 			-up / down(transmit > 2seconds) : open or close
3237 			*/
3238 			if (switchcmd == "On")
3239 			{
3240 				if (switchtype == STYPE_VenetianBlindsUS)
3241 				{
3242 					cmd = rfy_s05SecDown;
3243 				}
3244 				else if (switchtype == STYPE_VenetianBlindsEU)
3245 				{
3246 					cmd = rfy_s2SecDown;
3247 				}
3248 				else
3249 				{
3250 					cmd = rfy_sDown;
3251 				}
3252 			}
3253 			else if (switchcmd == "Off")
3254 			{
3255 				if (switchtype == STYPE_VenetianBlindsUS)
3256 				{
3257 					cmd = rfy_s05SecUp;
3258 				}
3259 				else if (switchtype == STYPE_VenetianBlindsEU)
3260 				{
3261 					cmd = rfy_s2SecUp;
3262 				}
3263 				else
3264 				{
3265 					cmd = rfy_sUp;
3266 				}
3267 			}
3268 			else if (switchcmd == "Stop")
3269 			{
3270 				cmd = rfy_sStop;
3271 			}
3272 			else if (switchcmd == "Up")
3273 			{
3274 				cmd = rfy_sUp;
3275 			}
3276 			else if (switchcmd == "UpStop")
3277 			{
3278 				cmd = rfy_sUpStop;
3279 			}
3280 			else if (switchcmd == "Down")
3281 			{
3282 				cmd = rfy_sDown;
3283 			}
3284 			else if (switchcmd == "DownStop")
3285 			{
3286 				cmd = rfy_sDownStop;
3287 			}
3288 			else if (switchcmd == "UpDown")
3289 			{
3290 				cmd = rfy_sUpDown;
3291 			}
3292 			else if (switchcmd == "ListRemotes")
3293 			{
3294 				cmd = rfy_sListRemotes;
3295 			}
3296 			else if (switchcmd == "Program")
3297 			{
3298 				cmd = rfy_sProgram;
3299 			}
3300 			else if (switchcmd == "Program2Seconds")
3301 			{
3302 				cmd = rfy_s2SecProgram;
3303 			}
3304 			else if (switchcmd == "Program7Seconds")
3305 			{
3306 				cmd = rfy_s7SecProgram;
3307 			}
3308 			else if (switchcmd == "Stop2Seconds")
3309 			{
3310 				cmd = rfy_s2SecStop;
3311 			}
3312 			else if (switchcmd == "Stop5Seconds")
3313 			{
3314 				cmd = rfy_s5SecStop;
3315 			}
3316 			else if (switchcmd == "UpDown5Seconds")
3317 			{
3318 				cmd = rfy_s5SecUpDown;
3319 			}
3320 			else if (switchcmd == "EraseThis") //from the RFXtrx
3321 			{
3322 				cmd = rfy_sEraseThis;
3323 			}
3324 			else if (switchcmd == "EraseAll") //from the RFXtrx
3325 			{
3326 				cmd = rfy_sEraseAll;
3327 			}
3328 			else if (switchcmd == "Up05Seconds")
3329 			{
3330 				cmd = rfy_s05SecUp;
3331 			}
3332 			else if (switchcmd == "Down05Seconds")
3333 			{
3334 				cmd = rfy_s05SecDown;
3335 			}
3336 			else if (switchcmd == "Up2Seconds")
3337 			{
3338 				cmd = rfy_s2SecUp;
3339 			}
3340 			else if (switchcmd == "Down2Seconds")
3341 			{
3342 				cmd = rfy_s2SecDown;
3343 			}
3344 			else if (switchcmd == "EnableSunWind")
3345 			{
3346 				cmd = rfy_sEnableSunWind;
3347 			}
3348 			else if (switchcmd == "DisableSunWind")
3349 			{
3350 				cmd = rfy_sDisableSun;
3351 			}
3352 			else
3353 			{
3354 				cmd = rfy_sStop;
3355 			}
3356 		}
3357 		return true;
3358 	}
3359 	break;
3360 	case pTypeRemote:
3361 		cmd = light2_sOn;
3362 		break;
3363 	case pTypeThermostat2:
3364 	{
3365 		if (switchcmd == "On")
3366 		{
3367 			cmd = thermostat2_sOn;
3368 		}
3369 		else if (switchcmd == "Off")
3370 		{
3371 			cmd = thermostat2_sOff;
3372 		}
3373 		else
3374 		{
3375 			cmd = thermostat2_sOff;
3376 		}
3377 		return true;
3378 	}
3379 	break;
3380 	case pTypeThermostat3:
3381 	{
3382 		if (switchcmd == "On")
3383 		{
3384 			cmd = thermostat3_sOn;
3385 		}
3386 		else if (switchcmd == "Off")
3387 		{
3388 			cmd = thermostat3_sOff;
3389 		}
3390 		else if (switchcmd == "Up")
3391 		{
3392 			cmd = thermostat3_sUp;
3393 		}
3394 		else if (switchcmd == "Down")
3395 		{
3396 			cmd = thermostat3_sDown;
3397 		}
3398 		else if (switchcmd == "Run Up")
3399 		{
3400 			cmd = thermostat3_sRunUp;
3401 		}
3402 		else if (switchcmd == "Run Down")
3403 		{
3404 			cmd = thermostat3_sRunDown;
3405 		}
3406 		else if (switchcmd == "Stop")
3407 		{
3408 			cmd = thermostat3_sStop;
3409 		}
3410 		else
3411 		{
3412 			cmd = thermostat3_sOff;
3413 		}
3414 		return true;
3415 	}
3416 	break;
3417 	case pTypeThermostat4:
3418 	{
3419 		if (switchcmd == "Off")
3420 		{
3421 			cmd = thermostat4_sOff;
3422 		}
3423 		else if (switchcmd == "Manual")
3424 		{
3425 			cmd = thermostat4_sManual;
3426 		}
3427 		else if (switchcmd == "Auto")
3428 		{
3429 			cmd = thermostat4_sAuto;
3430 		}
3431 		else if (switchcmd == "Eco")
3432 		{
3433 			cmd = thermostat4_sEco;
3434 		}
3435 		else
3436 		{
3437 			cmd = thermostat3_sOff;
3438 		}
3439 		return true;
3440 	}
3441 	break;
3442 	case pTypeRadiator1:
3443 	{
3444 		if (switchcmd == "On")
3445 		{
3446 			cmd = Radiator1_sDay;
3447 		}
3448 		else if (switchcmd == "Off")
3449 		{
3450 			cmd = Radiator1_sNight;
3451 		}
3452 		else
3453 		{
3454 			cmd = Radiator1_sNight;
3455 		}
3456 		return true;
3457 	}
3458 	case pTypeFan:
3459 	{
3460 		switch (dSubType)
3461 		{
3462 		case sTypeSiemensSF01:
3463 		{
3464 			if (switchcmd == "timer")
3465 			{
3466 				cmd = fan_sTimer;
3467 			}
3468 			else if (switchcmd == "+")
3469 			{
3470 				cmd = fan_sPlus;
3471 			}
3472 			else if (switchcmd == "-")
3473 			{
3474 				cmd = fan_sMin;
3475 			}
3476 			else if (switchcmd == "learn")
3477 			{
3478 				cmd = fan_sLearn;
3479 			}
3480 			else if (switchcmd == "confirm")
3481 			{
3482 				cmd = fan_sConfirm;
3483 			}
3484 			else if (switchcmd == "light")
3485 			{
3486 				cmd = fan_sLight;
3487 			}
3488 		}
3489 		break;
3490 		case sTypeItho:
3491 		{
3492 			if ((switchcmd == "1") || (switchcmd == "On") || (switchcmd == "Off"))
3493 			{
3494 				cmd = fan_Itho1;
3495 			}
3496 			else if (switchcmd == "2")
3497 			{
3498 				cmd = fan_Itho2;
3499 			}
3500 			else if (switchcmd == "3")
3501 			{
3502 				cmd = fan_Itho3;
3503 			}
3504 			else if (switchcmd == "timer")
3505 			{
3506 				cmd = fan_IthoTimer;
3507 			}
3508 			else if (switchcmd == "notathome")
3509 			{
3510 				cmd = fan_IthoNotAtHome;
3511 			}
3512 			else if (switchcmd == "learn")
3513 			{
3514 				cmd = fan_IthoLearn;
3515 			}
3516 			else if (switchcmd == "eraseall")
3517 			{
3518 				cmd = fan_IthoEraseAll;
3519 			}
3520 		}
3521 		break;
3522 		case sTypeLucciAir:
3523 		case sTypeWestinghouse:
3524 		{
3525 			if (switchcmd == "hi")
3526 			{
3527 				cmd = fan_LucciHi;
3528 			}
3529 			else if (switchcmd == "med")
3530 			{
3531 				cmd = fan_LucciMed;
3532 			}
3533 			else if (switchcmd == "low")
3534 			{
3535 				cmd = fan_LucciLow;
3536 			}
3537 			else if (switchcmd == "off")
3538 			{
3539 				cmd = fan_LucciOff;
3540 			}
3541 			else if (switchcmd == "light")
3542 			{
3543 				cmd = fan_LucciLight;
3544 			}
3545 		}
3546 		break;
3547 		case sTypeLucciAirDC:
3548 		{
3549 			if (switchcmd == "pow")
3550 				cmd = fan_LucciDCPower;
3551 			else if (switchcmd == "plus")
3552 				cmd = fan_LucciDCPlus;
3553 			else if (switchcmd == "min")
3554 				cmd = fan_LucciDCMin;
3555 			else if (switchcmd == "light")
3556 				cmd = fan_LucciDCLight;
3557 			else if (switchcmd == "rev")
3558 				cmd = fan_LucciDCReverse;
3559 			else if (switchcmd == "nat")
3560 				cmd = fan_LucciDCNaturalflow;
3561 		}
3562 		break;
3563 		}
3564 		return true;
3565 	}
3566 	break;
3567 	case pTypeHunter:
3568 	{
3569 		switch (dSubType)
3570 		{
3571 		case sTypeHunterfan:
3572 		{
3573 			if (switchcmd == "off")
3574 			{
3575 				cmd = HunterOff;
3576 			}
3577 			else if (switchcmd == "light")
3578 			{
3579 				cmd = HunterLight;
3580 			}
3581 			else if (switchcmd == "low")
3582 			{
3583 				cmd = HunterSpeed1;
3584 			}
3585 			else if (switchcmd == "med")
3586 			{
3587 				cmd = HunterSpeed2;
3588 			}
3589 			else if (switchcmd == "high")
3590 			{
3591 				cmd = HunterSpeed3;
3592 			}
3593 		}
3594 		return true;
3595 		}
3596 		break;
3597 	}
3598 	break;
3599 	}
3600 	//unknown command
3601 	return false;
3602 }
3603 
IsLightSwitchOn(const std::string & lstatus)3604 bool IsLightSwitchOn(const std::string& lstatus)
3605 {
3606 	return (
3607 		(lstatus == "On") ||
3608 		(lstatus == "Group On") ||
3609 		(lstatus == "All On") ||
3610 		(lstatus == "Chime") ||
3611 		(lstatus == "Motion") ||
3612 		(lstatus == "Alarm") ||
3613 		(lstatus == "Panic") ||
3614 		(lstatus == "Light On") ||
3615 		(lstatus == "Light 2 On") ||
3616 		(lstatus == "Set Color") ||
3617 		(lstatus == "Open inline relay") ||
3618 		(lstatus.find("Set Level") != std::string::npos) ||
3619 		(lstatus.find("Set Group Level") != std::string::npos) ||
3620 		(lstatus == "1") || //fan itho
3621 		(lstatus == "2") ||
3622 		(lstatus == "3")
3623 		);
3624 }
3625 
Get_Moisture_Desc(const int moisture)3626 const char* Get_Moisture_Desc(const int moisture)
3627 {
3628 	if (moisture < 10)
3629 		return "saturated";
3630 	else if (moisture < 20)
3631 		return "adequately wet";
3632 	else if (moisture < 60)
3633 		return "irrigation advise";
3634 	else if (moisture < 100)
3635 		return "irrigation";
3636 	else
3637 		return "dangerously dry";
3638 }
3639 
Get_Alert_Desc(const int level)3640 const char* Get_Alert_Desc(const int level)
3641 {
3642 	if (level == 0)
3643 		return "undefined";
3644 	else if (level == 1)
3645 		return "normal";
3646 	else if (level == 2)
3647 		return "warning";
3648 	else if (level == 3)
3649 		return "alert";
3650 	else if (level == 4)
3651 		return "alarm";
3652 	else
3653 		return "unknown level";
3654 }
3655 
IsSerialDevice(const _eHardwareTypes htype)3656 bool IsSerialDevice(const _eHardwareTypes htype)
3657 {
3658 	switch (htype) {
3659 	case HTYPE_RFXtrx315:
3660 	case HTYPE_RFXtrx433:
3661 	case HTYPE_RFXtrx868:
3662 	case HTYPE_P1SmartMeter:
3663 	case HTYPE_Rego6XX:
3664 	case HTYPE_DavisVantage:
3665 	case HTYPE_S0SmartMeterUSB:
3666 	case HTYPE_OpenThermGateway:
3667 	case HTYPE_TeleinfoMeter:
3668 	case HTYPE_OpenZWave:
3669 	case HTYPE_EnOceanESP2:
3670 	case HTYPE_EnOceanESP3:
3671 	case HTYPE_Meteostick:
3672 	case HTYPE_MySensorsUSB:
3673 	case HTYPE_RFLINKUSB:
3674 	case HTYPE_ZIBLUEUSB:
3675 	case HTYPE_KMTronicUSB:
3676 	case HTYPE_KMTronic433:
3677 	case HTYPE_CurrentCostMeter:
3678 	case HTYPE_RAVEn:
3679 	case HTYPE_Comm5Serial:
3680 	case HTYPE_USBtinGateway:
3681 	case HTYPE_DenkoviUSBDevices:
3682 		return true;
3683 	default:
3684 		return false;
3685 	}
3686 }
3687 
IsNetworkDevice(const _eHardwareTypes htype)3688 bool IsNetworkDevice(const _eHardwareTypes htype)
3689 {
3690 	switch (htype) {
3691 	case HTYPE_RFXLAN:
3692 	case HTYPE_P1SmartMeterLAN:
3693 	case HTYPE_YouLess:
3694 	case HTYPE_OpenThermGatewayTCP:
3695 	case HTYPE_LimitlessLights:
3696 	case HTYPE_SolarEdgeTCP:
3697 	case HTYPE_WOL:
3698 	case HTYPE_ECODEVICES:
3699 	case HTYPE_Mochad:
3700 	case HTYPE_MySensorsTCP:
3701 	case HTYPE_MySensorsMQTT:
3702 	case HTYPE_MQTT:
3703 	case HTYPE_FRITZBOX:
3704 	case HTYPE_ETH8020:
3705 	case HTYPE_RelayNet:
3706 	case HTYPE_Sterbox:
3707 	case HTYPE_KMTronicTCP:
3708 	case HTYPE_KMTronicUDP:
3709 	case HTYPE_SOLARMAXTCP:
3710 	case HTYPE_SatelIntegra:
3711 	case HTYPE_RFLINKTCP:
3712 	case HTYPE_Comm5TCP:
3713 	case HTYPE_Comm5SMTCP:
3714 	case HTYPE_CurrentCostMeterLAN:
3715 	case HTYPE_NefitEastLAN:
3716 	case HTYPE_DenkoviHTTPDevices:
3717 	case HTYPE_DenkoviTCPDevices:
3718 	case HTYPE_Ec3kMeterTCP:
3719 	case HTYPE_MultiFun:
3720 	case HTYPE_ZIBLUETCP:
3721 	case HTYPE_OnkyoAVTCP:
3722 	case HTYPE_eHouseTCP:
3723 	case HTYPE_TTN_MQTT:
3724 	case HTYPE_S0SmartMeterTCP:
3725 	case HTYPE_OctoPrint:
3726 		return true;
3727 	default:
3728 		return false;
3729 	}
3730 }
3731 
ConvertToGeneralSwitchType(std::string & devid,int & dtype,int & subtype)3732 void ConvertToGeneralSwitchType(std::string& devid, int& dtype, int& subtype)
3733 {
3734 	if (dtype == pTypeLighting1) {
3735 		dtype = pTypeGeneralSwitch;
3736 		if (subtype == sTypeIMPULS) subtype = sSwitchTypeTriState;
3737 		if (subtype == sTypeAB400D) subtype = sSwitchTypeAB400D;
3738 		if (subtype == sTypeIMPULS) subtype = sSwitchTypeTriState;
3739 		std::stringstream s_strid;
3740 		s_strid << std::hex << atoi(devid.c_str());
3741 		devid = s_strid.str();
3742 		devid = "000000" + devid;
3743 	}
3744 	else if (dtype == pTypeLighting2) {
3745 		dtype = pTypeGeneralSwitch;
3746 		if (subtype == sTypeAC) subtype = sSwitchTypeAC;
3747 		if (subtype == sTypeHEU) { subtype = sSwitchTypeHEU; devid = "7" + devid; }
3748 		if (subtype == sTypeKambrook) subtype = sSwitchTypeKambrook;
3749 		devid = "0" + devid;
3750 	}
3751 	else if (dtype == pTypeLighting3) {
3752 		dtype = pTypeGeneralSwitch;
3753 		if (subtype == sTypeKoppla) subtype = sSwitchTypeKoppla;
3754 	}
3755 	else if (dtype == pTypeLighting4) {
3756 		dtype = pTypeGeneralSwitch;
3757 		subtype = sSwitchTypeTriState;
3758 	}
3759 	else if (dtype == pTypeLighting5) {
3760 		dtype = pTypeGeneralSwitch;
3761 		if (subtype == sTypeEMW100) { subtype = sSwitchTypeEMW100; devid = "00" + devid; }
3762 		if (subtype == sTypeLivolo) { subtype = sSwitchTypeLivolo; devid = "00" + devid; }
3763 		if (subtype == sTypeLightwaveRF) { subtype = sSwitchTypeLightwaveRF; devid = "00" + devid; }
3764 		if (subtype == sTypeLivolo1to10) { subtype = sSwitchTypeLivoloAppliance; devid = "00" + devid; }
3765 		if (subtype == sTypeEurodomest) subtype = sSwitchTypeEurodomest;
3766 	}
3767 	else if (dtype == pTypeLighting6) {
3768 		dtype = pTypeGeneralSwitch;
3769 		subtype = sSwitchTypeBlyss;
3770 	}
3771 	else if (dtype == pTypeChime) {
3772 		dtype = pTypeGeneralSwitch;
3773 		if (subtype == sTypeByronSX) subtype = sSwitchTypeByronSX;
3774 		if (subtype == sTypeSelectPlus) subtype = sSwitchTypeSelectPlus;
3775 		if (subtype == sTypeByronBY) subtype = sSwitchTypeSelectPlus3;
3776 		if (subtype == sTypeByronMP001) subtype = sSwitchTypeByronMP001;
3777 	}
3778 	else if (dtype == pTypeSecurity1) {
3779 		dtype = pTypeGeneralSwitch;
3780 		if (subtype == sTypeSecX10) subtype = sSwitchTypeX10secu;
3781 		if (subtype == sTypeSecX10M) subtype = sSwitchTypeX10secu;
3782 		if (subtype == sTypeSecX10R) subtype = sSwitchTypeX10secu;
3783 	}
3784 	else if (dtype == pTypeHomeConfort) {
3785 		dtype = pTypeGeneralSwitch;
3786 		subtype = sSwitchTypeHomeConfort;
3787 	}
3788 	else if (dtype == pTypeBlinds) {
3789 		dtype = pTypeGeneralSwitch;
3790 		if (subtype == sTypeBlindsT5) subtype = sSwitchTypeBofu;
3791 		else if (subtype == sTypeBlindsT6) subtype = sSwitchTypeBrel;
3792 		else if (subtype == sTypeBlindsT7) subtype = sSwitchTypeDooya;
3793 		else if (subtype == sTypeBlindsT8) subtype = sSwitchTypeBofu;
3794 		else if (subtype == sTypeBlindsT9) subtype = sSwitchTypeBrel;
3795 		else if (subtype == sTypeBlindsT10) subtype = sSwitchTypeDooya;
3796 		std::stringstream s_strid;
3797 		s_strid << std::hex << strtoul(devid.c_str(), NULL, 16);
3798 		unsigned long deviceid = 0;
3799 		s_strid >> deviceid;
3800 		deviceid = (unsigned long)((deviceid & 0xffffff00) >> 8);
3801 		char szTmp[20];
3802 		sprintf(szTmp, "%08lX", deviceid);
3803 		//_log.Log(LOG_ERROR, "RFLink: deviceid: %x", deviceid);
3804 		devid = szTmp;
3805 	}
3806 	else if (dtype == pTypeRFY) {
3807 		dtype = pTypeGeneralSwitch;
3808 		subtype = sSwitchTypeRTS;
3809 	}
3810 }
3811