Climate Plugin

From LinuxMCE
Jump to: navigation, search
Version Status Date Updated Updated By
710 Unknown N/A N/A
810 Unknown N/A N/A
1004 Unknown N/A N/A
1204 Unknown N/A N/A
1404 Unknown N/A N/A
Usage Information

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 correct.

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)...

Description of enhanced 710 plugin and ability to control displayed info on floorplans

Currently, I've done this to enhance Climate Plugin under 710 (with the goal that changes will be in 810 too, when stable and finished)...I've come up with quite flexible idea of controlling what is displayed on floorplans for Climate devices (this could be easily extended to all rendering plugins)...I'll be happy to hear your opinions (please post to coresponding thread in Developers forum).


I've done this:

- by default behaviour stays the same as before
- if you add Extra parameters data to certain device, then you can control info displayed on floorplan by its content:

Explanation:

State for Climate devices consists of following parts ($x x=1..5, represents each part of current state information):

OSD display format for Orbiter floorplan ($1=ON/OFF,$2=HEAT|COOL|FAN_ONLY|AUTO,$3=HIGH|AUTO,$4=SET TEMP ($5=CURRENT TEMP))

for instance: default string value for displaying exactly the same info as it is know is :

'$1/$2/$3/$4 ($5)'   - omit quotes when entering into Extra parameters!

Climate device has a state consisting of five components: Active($1), Mode($2), FanMode($3),Setpoint($4),ActualTemp($5) and by default everything is displayed on floorplan... Now by changing this string you can easily control/select and add text info to floorplan - few examples :

'Outside ($5)'     will display text Outside and then ActualTemp
'$2 ($4)'            this is probably the thing for actual thermostat without fan....

OSD string is changed from default - computed :

- only if Extra parameters string exists
- if they exist, $1..$5 are replaced by actual values one by one
- everything else is intact...

I've tried to do this on my 710 system and must admit that now my floorplan is getting more user friendly and informative....

What do you think about solution ?

I also have an idea for further possible replacement of hardcoded states that are displayed on floorplans: - for instance what if you don't like HEAT/COOL/AUTO, then you could set an replacement for them -something like

'$1/$2/$3/$4 ($5) ?$3|HEAT|High?$3|COOL|Low'   - omit quotes!

String consists of parts, determined by '?' character. First part (obligatory) determines how will be values displayed on floorplan, remaining parts determine potential substitutions of predefined states to text that will be displayed on floorplan. In mentioned case, when evaluating $3, state of 'HEAT' is replaced by custom 'High' and 'COOL' is replaced by custom 'Low'...

I'll try to code this in next few days, although will be happy if someone more c++ experienced will give a hand...


Bulek 15:10, 2 December 2008 (CET)