Difference between revisions of "Climate Plugin"

From LinuxMCE
Jump to: navigation, search
(Description)
Line 4: Line 4:
  
 
Climate plugin takes care of climate devices. Handles commands, events and sets according device states. It also gives content to Orbiter plugin when it renders Climate devices on Orbiter's floorplans.
 
Climate plugin takes care of climate devices. Handles commands, events and sets according device states. It also gives content to Orbiter plugin when it renders Climate devices on Orbiter's floorplans.
 +
 +
== Important Code snippets ==
 +
 +
 +
=== Climate_Plugin::GetFloorplanDeviceInfo ===
 +
This method determines what group of commands will be shown on right column beside floorplan. In the last if, it also determines what will be displayed on floorplan (OSD string is the content that will be displayed on floorplan)... It also determines the color of object on floorplan. But since state of climate device is something like QQ/WW/XX/YY/(ZZ) where :
 +
#QQ      means ON or OFF state of device
 +
#WW      means mode of operation for instance Thermostat: AUTO,HEAT,COOL,FAN_ONLY
 +
#XX      means Fan mode: AUTO,HIGH
 +
#YY      means Set point (usually desired temperature setting): integer number
 +
#ZZ      means current temperature as reported by sensor, can be decimal number
 +
 +
By default in
 +
if( (OSD=pDeviceData_Router->m_sState_get())=="OFF" )
 +
OSD is set to show all state info on floorplan. Also I think (need some guidance?) that state will never be just "OFF", so all devices will be drawn with whole states and cold blue color on floorplans - but I could be missing something...
 +
 +
 +
 +
Code of highlighted method:
 +
 +
<pre>
 +
void Climate_Plugin::GetFloorplanDeviceInfo(DeviceData_Router *pDeviceData_Router,EntertainArea *pEntertainArea,int iFloorplanObjectType,int &iPK_FloorplanObjectType_Color,int &Color,string &sDescription,string &OSD,int &PK_DesignObj_Toolbar)
 +
{
 +
switch(iFloorplanObjectType)
 +
{
 +
case FLOORPLANOBJECTTYPE_CLIMATE_THERMOSTAT_CONST:
 +
PK_DesignObj_Toolbar=DESIGNOBJ_grpThermostatControls_CONST;
 +
break;
 +
case FLOORPLANOBJECTTYPE_CLIMATE_THERMOMETER_CONST:
 +
PK_DesignObj_Toolbar=0;
 +
break;
 +
case FLOORPLANOBJECTTYPE_CLIMATE_WEATHER_STATION_CONST:
 +
PK_DesignObj_Toolbar=0;
 +
break;
 +
case FLOORPLANOBJECTTYPE_CLIMATE_DAMPER_CONST:
 +
PK_DesignObj_Toolbar=0;
 +
break;
 +
case FLOORPLANOBJECTTYPE_CLIMATE_POOL_CONST:
 +
PK_DesignObj_Toolbar=DESIGNOBJ_grpPoolControls_CONST;
 +
break;
 +
case FLOORPLANOBJECTTYPE_CLIMATE_SPRINKLER_CONST:
 +
PK_DesignObj_Toolbar=DESIGNOBJ_grpSprinklerControls_CONST;
 +
break;
 +
};
 +
if( (OSD=pDeviceData_Router->m_sState_get())=="OFF" )
 +
iPK_FloorplanObjectType_Color = FLOORPLANOBJECTTYPE_COLOR_CLIMATE_THERMOSTAT_OFF_CONST;
 +
else
 +
iPK_FloorplanObjectType_Color = FLOORPLANOBJECTTYPE_COLOR_CLIMATE_THERMOSTAT_COOLING_CONST;
 +
}</pre>
 +
 +
=== Climate_Plugin::PreprocessClimateMessage ===
 +
 +
This one processes received messages/events. It can beclearly seen that currently following commands :
 +
<pre>
 +
if( pMessage->m_dwID==COMMAND_Set_Level_CONST )
 +
if( pMessage->m_dwID==COMMAND_Generic_On_CONST )
 +
else if( pMessage->m_dwID==COMMAND_Generic_Off_CONST )
 +
else if( pMessage->m_dwID==COMMAND_Set_HeatCool_CONST )
 +
if( sState=="H" )
 +
else if( sState=="C" )
 +
else if( sState=="F" )
 +
else
 +
else if( pMessage->m_dwID == COMMAND_Set_Fan_CONST )
 +
</pre>
 +
and events
 +
<pre>
 +
if( pMessage->m_dwID == EVENT_Temperature_Changed_CONST )
 +
else if( pMessage->m_dwID == EVENT_Thermostat_Set_Point_Chan_CONST )
 +
else if( pMessage->m_dwID == EVENT_Fan_Mode_Changed_CONST )
 +
else if( pMessage->m_dwID == EVENT_Thermostat_Mode_Changed_CONST )
 +
</pre>
 +
are processed.
 +
 +
 +
Code of highlighted method:
 +
<pre>
 +
void Climate_Plugin::PreprocessClimateMessage(DeviceData_Router *pDevice,Message *pMessage)
 +
{
 +
if( !pDevice || !pMessage || !pDevice->WithinCategory(DEVICECATEGORY_Climate_Device_CONST) )
 +
return;
 +
 +
string sOn;
 +
string sMode;
 +
string sFan;
 +
string sSetPoint;
 +
string sTemp;
 +
GetStateVar(pDevice, sOn, sMode, sFan, sSetPoint, sTemp);
 +
 +
// The State is in the format ON|OFF/SET TEMP (CURRENT TEMP)
 +
if( pMessage->m_dwMessage_Type==MESSAGETYPE_COMMAND )
 +
{
 +
if( pMessage->m_dwID==COMMAND_Set_Level_CONST )
 +
{
 +
string sLevel = pMessage->m_mapParameters[COMMANDPARAMETER_Level_CONST];
 +
if( sLevel.size()==0 )
 +
pMessage->m_dwID=COMMAND_Generic_Off_CONST;
 +
else
 +
{
 +
int iLevel = atoi(sLevel.c_str());
 +
if( sLevel[0]=='+' )
 +
iLevel = min(100, GetClimateLevel(pDevice,0)+iLevel);
 +
else if( sLevel[0]=='-' )
 +
iLevel = max(0, GetClimateLevel(pDevice,0)+iLevel);
 +
 +
if( iLevel==0 )
 +
pMessage->m_dwID=COMMAND_Generic_Off_CONST;
 +
else
 +
{
 +
pDevice->m_sState_set("ON/" + StringUtils::itos(iLevel) + GetTemperature(pDevice));
 +
pMessage->m_mapParameters[COMMANDPARAMETER_Level_CONST] = StringUtils::itos(iLevel);
 +
}
 +
}
 +
}
 +
 +
if( pMessage->m_dwID==COMMAND_Generic_On_CONST )
 +
SetStateValue(pDevice, "ON", sMode, sFan, sSetPoint, sTemp);
 +
else if( pMessage->m_dwID==COMMAND_Generic_Off_CONST )
 +
SetStateValue(pDevice, "OFF", sMode, sFan, sSetPoint, sTemp);
 +
else if( pMessage->m_dwID==COMMAND_Set_HeatCool_CONST )
 +
{
 +
LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: COMMAND_Set_HeatCool_CONST !");
 +
string sState = pMessage->m_mapParameters[COMMANDPARAMETER_OnOff_CONST];
 +
if( sState=="H" )
 +
SetStateValue(pDevice, sOn, "HEAT", sFan, sSetPoint, sTemp);
 +
else if( sState=="C" )
 +
SetStateValue(pDevice, sOn, "COOL", sFan, sSetPoint, sTemp);
 +
else if( sState=="F" )
 +
SetStateValue(pDevice, sOn, "FAN_ONLY", sFan, sSetPoint, sTemp);
 +
else
 +
SetStateValue(pDevice, sOn, "AUTO", sFan, sSetPoint, sTemp);
 +
}
 +
else if( pMessage->m_dwID == COMMAND_Set_Fan_CONST )
 +
{
 +
LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: COMMAND_Set_Fan_CONST !");
 +
string sState = pMessage->m_mapParameters[COMMANDPARAMETER_OnOff_CONST];
 +
if( 1 == atoi(sState.c_str()) )
 +
{
 +
SetStateValue(pDevice, sOn, "FAN_ONLY", "HIGH", sSetPoint, sTemp);
 +
}
 +
else
 +
{
 +
SetStateValue(pDevice, sOn, "AUTO", "AUTO", sSetPoint, sTemp);
 +
}
 +
}
 +
}
 +
else if( pMessage->m_dwMessage_Type == MESSAGETYPE_EVENT )
 +
{
 +
if( pMessage->m_dwID == EVENT_Temperature_Changed_CONST )
 +
{
 +
LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: EVENT_Temperature_Changed_CONST !");
 +
// Replace the current temp
 +
string sLevel = pMessage->m_mapParameters[EVENTPARAMETER_Value_CONST];
 +
SetStateValue(pDevice, sOn, sMode, sFan, sSetPoint, sLevel);
 +
}
 +
else if( pMessage->m_dwID == EVENT_Thermostat_Set_Point_Chan_CONST )
 +
{
 +
LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: EVENT_Thermostat_Set_Point_Chan_CONST !");
 +
// Replace the current temp
 +
string sLevel = pMessage->m_mapParameters[EVENTPARAMETER_Value_CONST];
 +
SetStateValue(pDevice, sOn, sMode, sFan, sLevel, sTemp);
 +
}
 +
else if( pMessage->m_dwID == EVENT_Fan_Mode_Changed_CONST )
 +
{
 +
LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: EVENT_Thermostat_Set_Point_Chan_CONST !");
 +
// Replace the current temp
 +
string sLevel = pMessage->m_mapParameters[EVENTPARAMETER_Value_CONST];
 +
int iMode = atoi(sLevel.c_str());
 +
switch(iMode)
 +
{
 +
default:
 +
case 0:
 +
case 1:
 +
SetStateValue(pDevice, sOn, sMode, "AUTO", sSetPoint, sTemp);
 +
break;
 +
 +
case 2:
 +
case 3:
 +
SetStateValue(pDevice, sOn, sMode, "HIGH", sSetPoint, sTemp);
 +
break;
 +
}
 +
}
 +
else if( pMessage->m_dwID == EVENT_Thermostat_Mode_Changed_CONST )
 +
{
 +
LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: EVENT_Thermostat_Set_Point_Chan_CONST !");
 +
// Replace the current temp
 +
string sLevel = pMessage->m_mapParameters[EVENTPARAMETER_Value_CONST];
 +
 +
int iMode = atoi(sLevel.c_str());
 +
switch(iMode)
 +
{
 +
default:
 +
case 10:
 +
SetStateValue(pDevice, sOn, "AUTO", sFan, sSetPoint, sTemp);
 +
break;
 +
 +
case 1:
 +
SetStateValue(pDevice, sOn, "HEAT", sFan, sSetPoint, sTemp);
 +
break;
 +
 +
case 2:
 +
SetStateValue(pDevice, sOn, "COOL", sFan, sSetPoint, sTemp);
 +
break;
 +
 +
case 6:
 +
SetStateValue(pDevice, sOn, "FAN_ONLY", sFan, sSetPoint, sTemp);
 +
break;
 +
}
 +
}
 +
}
 +
}
 +
</pre>
  
 
== How to use Climate devices in Orbiter ==
 
== How to use Climate devices in Orbiter ==
 +
 +
== Potential problems with current content of Climate Plugin ==
 +
 +
 +
 +
 +
''''My personal comment(Bulek):
 +
 +
''I think that Climate_Plugin::GetFloorplanDeviceInfo seems a bit unfinished. IT also displays all devices with all state info in same coldblue color, cause state is probably never just "OFF" as if clause is checking.
 +
IMHO this is not convenient,it's not necessary to show all that info for instance for temperature sensors. This would be fairly easy to achieve.
 +
 +
'''My plans:
 +
 +
*''I plan to correct that behaviour, if leading developers confirm, that this won't break anything else.
 +
 +
*''I also plan to support use of more already defined colors like:
 +
Open CLIMATE_DAMPER_OPEN -256 yellow
 +
Closed CLIMATE_DAMPER_CLOSED -4144960  bright gray
 +
Off CLIMATE_THERMOSTAT_OFF -16777216              black
 +
Fan CLIMATE_THERMOSTAT_FAN -4144960  bright gray
 +
Heating CLIMATE_THERMOSTAT_HEATING -65536 red
 +
Cooling CLIMATE_THERMOSTAT_COOLING -16744256 cold blue
 +
 +
On CLIMATE_SPRINKLER_ON -256 yellow
 +
Off CLIMATE_SPRINKLER_OFF -8355712 dark gray
 +
 +
*''More complicated to do opinion: I think that Thermostat is too complex including Heating,Cooling and Fan control. Maybe we also need some simpler devices like only heating thermostat and separate fan (ventilation control)...

Revision as of 14:44, 2 December 2008

Description

Climate plugin takes care of climate devices. Handles commands, events and sets according device states. It also gives content to Orbiter plugin when it renders Climate devices on Orbiter's floorplans.

Important Code snippets

Climate_Plugin::GetFloorplanDeviceInfo

This method determines what group of commands will be shown on right column beside floorplan. In the last if, it also determines what will be displayed on floorplan (OSD string is the content that will be displayed on floorplan)... It also determines the color of object on floorplan. But since state of climate device is something like QQ/WW/XX/YY/(ZZ) where :

  1. QQ means ON or OFF state of device
  2. WW means mode of operation for instance Thermostat: AUTO,HEAT,COOL,FAN_ONLY
  3. XX means Fan mode: AUTO,HIGH
  4. YY means Set point (usually desired temperature setting): integer number
  5. ZZ means current temperature as reported by sensor, can be decimal number

By default in

if( (OSD=pDeviceData_Router->m_sState_get())=="OFF" )

OSD is set to show all state info on floorplan. Also I think (need some guidance?) that state will never be just "OFF", so all devices will be drawn with whole states and cold blue color on floorplans - but I could be missing something...


Code of highlighted method:

void Climate_Plugin::GetFloorplanDeviceInfo(DeviceData_Router *pDeviceData_Router,EntertainArea *pEntertainArea,int iFloorplanObjectType,int &iPK_FloorplanObjectType_Color,int &Color,string &sDescription,string &OSD,int &PK_DesignObj_Toolbar)
{
	switch(iFloorplanObjectType)
	{
	case FLOORPLANOBJECTTYPE_CLIMATE_THERMOSTAT_CONST:
		PK_DesignObj_Toolbar=DESIGNOBJ_grpThermostatControls_CONST;
		break;
	case FLOORPLANOBJECTTYPE_CLIMATE_THERMOMETER_CONST:
		PK_DesignObj_Toolbar=0;
		break;
	case FLOORPLANOBJECTTYPE_CLIMATE_WEATHER_STATION_CONST:
		PK_DesignObj_Toolbar=0;
		break;
	case FLOORPLANOBJECTTYPE_CLIMATE_DAMPER_CONST:
		PK_DesignObj_Toolbar=0;
		break;
	case FLOORPLANOBJECTTYPE_CLIMATE_POOL_CONST:
		PK_DesignObj_Toolbar=DESIGNOBJ_grpPoolControls_CONST;
		break;
	case FLOORPLANOBJECTTYPE_CLIMATE_SPRINKLER_CONST:
		PK_DesignObj_Toolbar=DESIGNOBJ_grpSprinklerControls_CONST;
		break;
	};
	if( (OSD=pDeviceData_Router->m_sState_get())=="OFF" )
		iPK_FloorplanObjectType_Color = FLOORPLANOBJECTTYPE_COLOR_CLIMATE_THERMOSTAT_OFF_CONST;
	else
		iPK_FloorplanObjectType_Color = FLOORPLANOBJECTTYPE_COLOR_CLIMATE_THERMOSTAT_COOLING_CONST;
}

Climate_Plugin::PreprocessClimateMessage

This one processes received messages/events. It can beclearly seen that currently following commands :

		if( pMessage->m_dwID==COMMAND_Set_Level_CONST )
		if( pMessage->m_dwID==COMMAND_Generic_On_CONST )
		else if( pMessage->m_dwID==COMMAND_Generic_Off_CONST )
		else if( pMessage->m_dwID==COMMAND_Set_HeatCool_CONST )
			if( sState=="H" )
			else if( sState=="C" )
			else if( sState=="F" )
			else
		else if( pMessage->m_dwID == COMMAND_Set_Fan_CONST )

and events

		if( pMessage->m_dwID == EVENT_Temperature_Changed_CONST )
		else if( pMessage->m_dwID == EVENT_Thermostat_Set_Point_Chan_CONST )
		else if( pMessage->m_dwID == EVENT_Fan_Mode_Changed_CONST )
		else if( pMessage->m_dwID == EVENT_Thermostat_Mode_Changed_CONST )

are processed.


Code of highlighted method:

void Climate_Plugin::PreprocessClimateMessage(DeviceData_Router *pDevice,Message *pMessage)
{
	if( !pDevice || !pMessage || !pDevice->WithinCategory(DEVICECATEGORY_Climate_Device_CONST) )
		return;

	string sOn;
	string sMode;
	string sFan;
	string sSetPoint;
	string sTemp;
	GetStateVar(pDevice, sOn, sMode, sFan, sSetPoint, sTemp);
	
	// The State is in the format ON|OFF/SET TEMP (CURRENT TEMP)
	if( pMessage->m_dwMessage_Type==MESSAGETYPE_COMMAND )
	{
		if( pMessage->m_dwID==COMMAND_Set_Level_CONST )
		{
			string sLevel = pMessage->m_mapParameters[COMMANDPARAMETER_Level_CONST];
			if( sLevel.size()==0 )
				pMessage->m_dwID=COMMAND_Generic_Off_CONST;
			else
			{
				int iLevel = atoi(sLevel.c_str());
				if( sLevel[0]=='+' )
					iLevel = min(100, GetClimateLevel(pDevice,0)+iLevel);
				else if( sLevel[0]=='-' )
					iLevel = max(0, GetClimateLevel(pDevice,0)+iLevel);

				if( iLevel==0 )
					pMessage->m_dwID=COMMAND_Generic_Off_CONST;
				else
				{
					pDevice->m_sState_set("ON/" + StringUtils::itos(iLevel) + GetTemperature(pDevice));
					pMessage->m_mapParameters[COMMANDPARAMETER_Level_CONST] = StringUtils::itos(iLevel);
				}
			}
		}

		if( pMessage->m_dwID==COMMAND_Generic_On_CONST )
			SetStateValue(pDevice, "ON", sMode, sFan, sSetPoint, sTemp);
		else if( pMessage->m_dwID==COMMAND_Generic_Off_CONST )
			SetStateValue(pDevice, "OFF", sMode, sFan, sSetPoint, sTemp);
		else if( pMessage->m_dwID==COMMAND_Set_HeatCool_CONST )
		{
			LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: COMMAND_Set_HeatCool_CONST !");
			string sState = pMessage->m_mapParameters[COMMANDPARAMETER_OnOff_CONST];
			if( sState=="H" )
				SetStateValue(pDevice, sOn, "HEAT", sFan, sSetPoint, sTemp);
			else if( sState=="C" )
				SetStateValue(pDevice, sOn, "COOL", sFan, sSetPoint, sTemp);
			else if( sState=="F" )
				SetStateValue(pDevice, sOn, "FAN_ONLY", sFan, sSetPoint, sTemp);
			else
				SetStateValue(pDevice, sOn, "AUTO", sFan, sSetPoint, sTemp);
		}
		else if( pMessage->m_dwID == COMMAND_Set_Fan_CONST )
		{
			LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: COMMAND_Set_Fan_CONST !");
			string sState = pMessage->m_mapParameters[COMMANDPARAMETER_OnOff_CONST];
			if( 1 == atoi(sState.c_str()) )
			{
				SetStateValue(pDevice, sOn, "FAN_ONLY", "HIGH", sSetPoint, sTemp);
			}
			else
			{
				SetStateValue(pDevice, sOn, "AUTO", "AUTO", sSetPoint, sTemp);
			}
		}
	}
	else if( pMessage->m_dwMessage_Type == MESSAGETYPE_EVENT )
	{
		if( pMessage->m_dwID == EVENT_Temperature_Changed_CONST )
		{
			LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: EVENT_Temperature_Changed_CONST !");
			// Replace the current temp
			string sLevel = pMessage->m_mapParameters[EVENTPARAMETER_Value_CONST];
			SetStateValue(pDevice, sOn, sMode, sFan, sSetPoint, sLevel);
		}
		else if( pMessage->m_dwID == EVENT_Thermostat_Set_Point_Chan_CONST )
		{
			LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: EVENT_Thermostat_Set_Point_Chan_CONST !");
			// Replace the current temp
			string sLevel = pMessage->m_mapParameters[EVENTPARAMETER_Value_CONST];
			SetStateValue(pDevice, sOn, sMode, sFan, sLevel, sTemp);
		}
		else if( pMessage->m_dwID == EVENT_Fan_Mode_Changed_CONST )
		{
			LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: EVENT_Thermostat_Set_Point_Chan_CONST !");
			// Replace the current temp
			string sLevel = pMessage->m_mapParameters[EVENTPARAMETER_Value_CONST];
			int iMode = atoi(sLevel.c_str());
			switch(iMode)
			{
				default:
				case 0:
				case 1:
					SetStateValue(pDevice, sOn, sMode, "AUTO", sSetPoint, sTemp);
					break;
					
				case 2:
				case 3:
					SetStateValue(pDevice, sOn, sMode, "HIGH", sSetPoint, sTemp);
					break;
			}
		}
		else if( pMessage->m_dwID == EVENT_Thermostat_Mode_Changed_CONST )
		{
			LoggerWrapper::GetInstance()->Write(LV_CRITICAL,"Climate_Plugin: EVENT_Thermostat_Set_Point_Chan_CONST !");
			// Replace the current temp
			string sLevel = pMessage->m_mapParameters[EVENTPARAMETER_Value_CONST];
				
			int iMode = atoi(sLevel.c_str());
			switch(iMode)
			{
				default:
				case 10:
					SetStateValue(pDevice, sOn, "AUTO", sFan, sSetPoint, sTemp);
					break;
			
				case 1:
					SetStateValue(pDevice, sOn, "HEAT", sFan, sSetPoint, sTemp);
					break;
			
				case 2:
					SetStateValue(pDevice, sOn, "COOL", sFan, sSetPoint, sTemp);
					break;
			
				case 6:
					SetStateValue(pDevice, sOn, "FAN_ONLY", sFan, sSetPoint, sTemp);
					break;
			}
		}
	}
}

How to use Climate devices in Orbiter

Potential problems with current content of Climate Plugin

'My personal comment(Bulek):

I think that Climate_Plugin::GetFloorplanDeviceInfo seems a bit unfinished. IT also displays all devices with all state info in same coldblue color, cause state is probably never just "OFF" as if clause is checking. IMHO this is not convenient,it's not necessary to show all that info for instance for temperature sensors. This would be fairly easy to achieve.

My plans:

  • I plan to correct that behaviour, if leading developers confirm, that this won't break anything else.
  • I also plan to support use of more already defined colors like:
Open 	CLIMATE_DAMPER_OPEN 		-256 			yellow
Closed 	CLIMATE_DAMPER_CLOSED 	-4144960  		bright gray
Off 	CLIMATE_THERMOSTAT_OFF 		-16777216               black
Fan 	CLIMATE_THERMOSTAT_FAN 		-4144960  		bright gray
Heating CLIMATE_THERMOSTAT_HEATING 	-65536 			red
Cooling CLIMATE_THERMOSTAT_COOLING 	-16744256 		cold blue
On 	CLIMATE_SPRINKLER_ON 		-256 			yellow
Off 	CLIMATE_SPRINKLER_OFF 		-8355712 		dark gray
  • More complicated to do opinion: I think that Thermostat is too complex including Heating,Cooling and Fan control. Maybe we also need some simpler devices like only heating thermostat and separate fan (ventilation control)...