blob: f56b4870c4e228aee1beddb10f96299597c6d771 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.car.kitchensink.hvac;
import static java.lang.Integer.toHexString;
import android.car.CarNotConnectedException;
import android.car.hardware.CarPropertyConfig;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.hvac.CarHvacManager;
import android.hardware.automotive.vehicle.V2_0.VehicleAreaSeat;
import android.hardware.automotive.vehicle.V2_0.VehicleAreaWindow;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.ToggleButton;
import androidx.fragment.app.Fragment;
import com.google.android.car.kitchensink.KitchenSinkActivity;
import com.google.android.car.kitchensink.R;
import java.util.ArrayList;
import java.util.List;
public class HvacTestFragment extends Fragment {
private final boolean DBG = true;
private final String TAG = "HvacTestFragment";
private RadioButton mRbFanPositionFace;
private RadioButton mRbFanPositionFloor;
private RadioButton mRbFanPositionFaceAndFloor;
private RadioButton mRbFanPositionDefrost;
private RadioButton mRbFanPositionDefrostAndFloor;
private ToggleButton mTbAc;
private ToggleButton mTbAuto;
private ToggleButton mTbDefrostFront;
private ToggleButton mTbDefrostRear;
private ToggleButton mTbDual;
private ToggleButton mTbMaxAc;
private ToggleButton mTbMaxDefrost;
private ToggleButton mTbRecirc;
private TextView mTvFanSpeed;
private TextView mTvDTemp;
private TextView mTvPTemp;
private TextView mTvOutsideTemp;
private int mCurFanSpeed;
private int mMinFanSpeed;
private int mMaxFanSpeed;
private float mCurDTemp;
private float mCurPTemp;
private float mMinTemp;
private float mMaxTemp;
private float mTempStep;
private CarHvacManager mCarHvacManager;
private int mZoneForAcOn;
private int mZoneForSetTempD;
private int mZoneForSetTempP;
private int mZoneForFanSpeed;
private int mZoneForFanPosition;
private List<CarPropertyConfig> mCarPropertyConfigs;
private View mHvacView;
private final CarHvacManager.CarHvacEventCallback mHvacCallback =
new CarHvacManager.CarHvacEventCallback () {
@Override
public void onChangeEvent(final CarPropertyValue value) {
int zones = value.getAreaId();
switch(value.getPropertyId()) {
case CarHvacManager.ID_OUTSIDE_AIR_TEMP:
mTvOutsideTemp.setText(String.valueOf(value.getValue()));
break;
case CarHvacManager.ID_ZONED_DUAL_ZONE_ON:
mTbDual.setChecked((boolean)value.getValue());
break;
case CarHvacManager.ID_ZONED_AC_ON:
mTbAc.setChecked((boolean)value.getValue());
break;
case CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON:
mTbAuto.setChecked((boolean)value.getValue());
break;
case CarHvacManager.ID_ZONED_FAN_DIRECTION:
switch((int)value.getValue()) {
case CarHvacManager.FAN_DIRECTION_FACE:
mRbFanPositionFace.setChecked(true);
break;
case CarHvacManager.FAN_DIRECTION_FLOOR:
mRbFanPositionFloor.setChecked(true);
break;
case (CarHvacManager.FAN_DIRECTION_FACE |
CarHvacManager.FAN_DIRECTION_FLOOR):
mRbFanPositionFaceAndFloor.setChecked(true);
break;
case CarHvacManager.FAN_DIRECTION_DEFROST:
mRbFanPositionDefrost.setChecked(true);
break;
case (CarHvacManager.FAN_DIRECTION_DEFROST |
CarHvacManager.FAN_DIRECTION_FLOOR):
mRbFanPositionDefrostAndFloor.setChecked(true);
break;
default:
if (DBG) {
Log.e(TAG, "Unknown fan position: " + value.getValue());
}
break;
}
break;
case CarHvacManager.ID_ZONED_MAX_AC_ON:
mTbMaxAc.setChecked((boolean)value.getValue());
break;
case CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON:
mTbRecirc.setChecked((boolean)value.getValue());
break;
case CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT:
if ((zones & mZoneForFanSpeed) == mZoneForFanSpeed) {
mCurFanSpeed = (int)value.getValue();
mTvFanSpeed.setText(String.valueOf(mCurFanSpeed));
}
break;
case CarHvacManager.ID_ZONED_TEMP_SETPOINT:
if ((zones & mZoneForSetTempD) == mZoneForSetTempD) {
mCurDTemp = (float)value.getValue();
mTvDTemp.setText(String.valueOf(mCurDTemp));
}
if ((zones & mZoneForSetTempP) == mZoneForSetTempP) {
mCurPTemp = (float)value.getValue();
mTvPTemp.setText(String.valueOf(mCurPTemp));
}
break;
case CarHvacManager.ID_ZONED_MAX_DEFROST_ON:
mTbMaxDefrost.setChecked((boolean)value.getValue());
break;
case CarHvacManager.ID_WINDOW_DEFROSTER_ON:
if((zones & VehicleAreaWindow.FRONT_WINDSHIELD) ==
VehicleAreaWindow.FRONT_WINDSHIELD) {
mTbDefrostFront.setChecked((boolean)value.getValue());
}
if((zones & VehicleAreaWindow.REAR_WINDSHIELD) ==
VehicleAreaWindow.REAR_WINDSHIELD) {
mTbDefrostRear.setChecked((boolean)value.getValue());
}
break;
default:
Log.d(TAG, "onChangeEvent(): unknown property id = " + value
.getPropertyId());
}
}
@Override
public void onErrorEvent(final int propertyId, final int zone) {
Log.w(TAG, "Error: propertyId=0x" + toHexString(propertyId)
+ ", zone=0x" + toHexString(zone));
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onDestroy() {
super.onDestroy();
mCarHvacManager.unregisterCallback(mHvacCallback);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstance) {
mHvacView = inflater.inflate(R.layout.hvac_test, container, false);
final Runnable r = () -> {
mCarHvacManager = ((KitchenSinkActivity) getActivity()).getHvacManager();
try {
mCarHvacManager.registerCallback(mHvacCallback);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Car is not connected!");
}
try {
mCarPropertyConfigs = mCarHvacManager.getPropertyList();
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to get list of properties", e);
mCarPropertyConfigs = new ArrayList<>();
}
for (CarPropertyConfig prop : mCarPropertyConfigs) {
int propId = prop.getPropertyId();
if (DBG) {
Log.d(TAG, prop.toString());
}
switch(propId) {
case CarHvacManager.ID_OUTSIDE_AIR_TEMP:
configureOutsideTemp(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_DUAL_ZONE_ON:
configureDualOn(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_AC_ON:
configureAcOn(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_FAN_DIRECTION:
configureFanPosition(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT:
configureFanSpeed(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_TEMP_SETPOINT:
configureTempSetpoint(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON:
configureAutoModeOn(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON:
configureRecircOn(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_MAX_AC_ON:
configureMaxAcOn(mHvacView, prop);
break;
case CarHvacManager.ID_ZONED_MAX_DEFROST_ON:
configureMaxDefrostOn(mHvacView, prop);
break;
case CarHvacManager.ID_WINDOW_DEFROSTER_ON:
configureDefrosterOn(mHvacView, prop);
break;
default:
Log.w(TAG, "propertyId " + propId + " is not handled");
break;
}
}
mTvFanSpeed = (TextView) mHvacView.findViewById(R.id.tvFanSpeed);
mTvFanSpeed.setText(String.valueOf(mCurFanSpeed));
mTvDTemp = (TextView) mHvacView.findViewById(R.id.tvDTemp);
mTvDTemp.setText(String.valueOf(mCurDTemp));
mTvPTemp = (TextView) mHvacView.findViewById(R.id.tvPTemp);
mTvPTemp.setText(String.valueOf(mCurPTemp));
mTvOutsideTemp = (TextView) mHvacView.findViewById(R.id.tvOutsideTemp);
mTvOutsideTemp.setText("N/A");
};
((KitchenSinkActivity) getActivity()).requestRefreshManager(r,
new Handler(getContext().getMainLooper()));
if(DBG) {
Log.d(TAG, "Starting HvacTestFragment");
}
return mHvacView;
}
private void configureOutsideTemp(View v, CarPropertyConfig prop) {
// Do nothing
}
private void configureDualOn(View v, CarPropertyConfig prop) {
int temp = prop.getFirstAndOnlyAreaId();
mTbDual = (ToggleButton)v.findViewById(R.id.tbDual);
mTbDual.setEnabled(true);
mTbDual.setOnClickListener(view -> {
// TODO handle zone properly
try {
mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_DUAL_ZONE_ON,temp,
mTbDual.isChecked());
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC boolean property", e);
}
});
}
private void configureAcOn(View v, CarPropertyConfig prop) {
mZoneForAcOn = prop.getFirstAndOnlyAreaId();
mTbAc = (ToggleButton)v.findViewById(R.id.tbAc);
mTbAc.setEnabled(true);
mTbAc.setOnClickListener(view -> {
// TODO handle zone properly
try {
mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_AC_ON, mZoneForAcOn,
mTbAc.isChecked());
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC boolean property", e);
}
});
}
private void configureAutoModeOn(View v, CarPropertyConfig prop) {
int temp = prop.getFirstAndOnlyAreaId();
mTbAuto = (ToggleButton)v.findViewById(R.id.tbAuto);
mTbAuto.setEnabled(true);
mTbAuto.setOnClickListener(view -> {
// TODO handle zone properly
try {
mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON,temp,
mTbAuto.isChecked());
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC boolean property", e);
}
});
}
private void configureFanPosition(View v, CarPropertyConfig prop) {
mZoneForFanPosition = prop.getFirstAndOnlyAreaId();
RadioGroup rg = (RadioGroup)v.findViewById(R.id.rgFanPosition);
rg.setOnCheckedChangeListener((group, checkedId) -> {
int position;
switch(checkedId) {
case R.id.rbPositionFace:
position = CarHvacManager.FAN_DIRECTION_FACE;
break;
case R.id.rbPositionFloor:
position = CarHvacManager.FAN_DIRECTION_FLOOR;
break;
case R.id.rbPositionFaceAndFloor:
position = (CarHvacManager.FAN_DIRECTION_FACE |
CarHvacManager.FAN_DIRECTION_FLOOR);
break;
case R.id.rbPositionDefrost:
position = CarHvacManager.FAN_DIRECTION_DEFROST;
break;
case R.id.rbPositionDefrostAndFloor:
position = (CarHvacManager.FAN_DIRECTION_DEFROST |
CarHvacManager.FAN_DIRECTION_FLOOR);
break;
default:
throw new IllegalStateException("Unexpected fan position: " + checkedId);
}
try {
mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_DIRECTION,
mZoneForFanPosition,
position);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC integer property", e);
}
});
mRbFanPositionFace = (RadioButton)v.findViewById(R.id.rbPositionFace);
mRbFanPositionFace.setClickable(true);
mRbFanPositionFloor = (RadioButton)v.findViewById(R.id.rbPositionFloor);
mRbFanPositionFloor.setClickable(true);
mRbFanPositionFaceAndFloor = (RadioButton)v.findViewById(R.id.rbPositionFaceAndFloor);
mRbFanPositionFaceAndFloor.setClickable(true);
mRbFanPositionDefrost = (RadioButton)v.findViewById(R.id.rbPositionDefrost);
mRbFanPositionDefrost.setClickable(true);
mRbFanPositionDefrostAndFloor = (RadioButton)v.findViewById(R.id.rbPositionDefrostAndFloor);
mRbFanPositionDefrostAndFloor.setClickable(true);
}
private void configureFanSpeed(View v, CarPropertyConfig prop) {
mMinFanSpeed = ((Integer)prop.getMinValue()).intValue();
mMaxFanSpeed = ((Integer)prop.getMaxValue()).intValue();
mZoneForFanSpeed = prop.getFirstAndOnlyAreaId();
try {
mCurFanSpeed = mCarHvacManager.getIntProperty(
CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
mZoneForFanSpeed);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to get HVAC int property", e);
}
Button btnFanSpeedUp = (Button) v.findViewById(R.id.btnFanSpeedUp);
btnFanSpeedUp.setEnabled(true);
btnFanSpeedUp.setOnClickListener(view -> {
if (mCurFanSpeed < mMaxFanSpeed) {
mCurFanSpeed++;
mTvFanSpeed.setText(String.valueOf(mCurFanSpeed));
try {
mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
mZoneForFanSpeed, mCurFanSpeed);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC int property", e);
}
}
});
Button btnFanSpeedDn = (Button) v.findViewById(R.id.btnFanSpeedDn);
btnFanSpeedDn.setEnabled(true);
btnFanSpeedDn.setOnClickListener(view -> {
if (mCurFanSpeed > mMinFanSpeed) {
mCurFanSpeed--;
mTvFanSpeed.setText(String.valueOf(mCurFanSpeed));
try {
mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
mZoneForFanSpeed, mCurFanSpeed);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC fan speed property", e);
}
}
});
}
private void configureTempSetpoint(View v, CarPropertyConfig prop) {
mMinTemp = ((Float)prop.getMinValue()).floatValue();
mMaxTemp = ((Float)prop.getMaxValue()).floatValue();
if (mMaxTemp > 50) {
// Assume it's Fahrenheit
mTempStep = 1.0f;
} else {
// Assume it's Celsius
mTempStep = 0.5f;
}
mZoneForSetTempD = 0;
if (prop.hasArea(VehicleAreaSeat.ROW_1_LEFT | VehicleAreaSeat.ROW_2_LEFT
| VehicleAreaSeat.ROW_2_CENTER)) {
mZoneForSetTempD = VehicleAreaSeat.ROW_1_LEFT | VehicleAreaSeat.ROW_2_LEFT
| VehicleAreaSeat.ROW_2_CENTER;
}
mZoneForSetTempP = 0;
if (prop.hasArea(VehicleAreaSeat.ROW_1_RIGHT | VehicleAreaSeat.ROW_2_RIGHT)) {
mZoneForSetTempP = VehicleAreaSeat.ROW_1_RIGHT | VehicleAreaSeat.ROW_2_RIGHT;
}
int[] areas = prop.getAreaIds();
if (mZoneForSetTempD == 0 && areas.length > 1) {
mZoneForSetTempD = areas[0];
}
if (mZoneForSetTempP == 0 && areas.length > 2) {
mZoneForSetTempP = areas[1];
}
Button btnDTempUp = (Button) v.findViewById(R.id.btnDTempUp);
if (mZoneForSetTempD != 0) {
try {
mCurDTemp = mCarHvacManager.getFloatProperty(
CarHvacManager.ID_ZONED_TEMP_SETPOINT,
mZoneForSetTempD);
if (mCurDTemp < mMinTemp) {
mCurDTemp = mMinTemp;
} else if (mCurDTemp > mMaxTemp) {
mCurDTemp = mMaxTemp;
}
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to get HVAC zoned temp property", e);
}
btnDTempUp.setEnabled(true);
btnDTempUp.setOnClickListener(view -> {
if(mCurDTemp < mMaxTemp) {
mCurDTemp += mTempStep;
mTvDTemp.setText(String.valueOf(mCurDTemp));
try {
mCarHvacManager.setFloatProperty(
CarHvacManager.ID_ZONED_TEMP_SETPOINT,
mZoneForSetTempD, mCurDTemp);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC zoned temp property", e);
}
}
});
Button btnDTempDn = (Button) v.findViewById(R.id.btnDTempDn);
btnDTempDn.setEnabled(true);
btnDTempDn.setOnClickListener(view -> {
if(mCurDTemp > mMinTemp) {
mCurDTemp -= mTempStep;
mTvDTemp.setText(String.valueOf(mCurDTemp));
try {
mCarHvacManager.setFloatProperty(
CarHvacManager.ID_ZONED_TEMP_SETPOINT,
mZoneForSetTempD, mCurDTemp);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC zoned temp property", e);
}
}
});
} else {
btnDTempUp.setEnabled(false);
}
Button btnPTempUp = (Button) v.findViewById(R.id.btnPTempUp);
if (mZoneForSetTempP !=0 ) {
try {
mCurPTemp = mCarHvacManager.getFloatProperty(
CarHvacManager.ID_ZONED_TEMP_SETPOINT,
mZoneForSetTempP);
if (mCurPTemp < mMinTemp) {
mCurPTemp = mMinTemp;
} else if (mCurPTemp > mMaxTemp) {
mCurPTemp = mMaxTemp;
}
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to get HVAC zoned temp property", e);
}
btnPTempUp.setEnabled(true);
btnPTempUp.setOnClickListener(view -> {
if (mCurPTemp < mMaxTemp) {
mCurPTemp += mTempStep;
mTvPTemp.setText(String.valueOf(mCurPTemp));
try {
mCarHvacManager.setFloatProperty(
CarHvacManager.ID_ZONED_TEMP_SETPOINT,
mZoneForSetTempP, mCurPTemp);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC zoned temp property", e);
}
}
});
Button btnPTempDn = (Button) v.findViewById(R.id.btnPTempDn);
btnPTempDn.setEnabled(true);
btnPTempDn.setOnClickListener(view -> {
if (mCurPTemp > mMinTemp) {
mCurPTemp -= mTempStep;
mTvPTemp.setText(String.valueOf(mCurPTemp));
try {
mCarHvacManager.setFloatProperty(
CarHvacManager.ID_ZONED_TEMP_SETPOINT,
mZoneForSetTempP, mCurPTemp);
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC zoned temp property", e);
}
}
});
} else {
btnPTempUp.setEnabled(false);
}
}
private void configureDefrosterOn(View v, CarPropertyConfig prop1) {
if (prop1.hasArea(VehicleAreaWindow.FRONT_WINDSHIELD)) {
mTbDefrostFront = (ToggleButton) v.findViewById(R.id.tbDefrostFront);
mTbDefrostFront.setEnabled(true);
mTbDefrostFront.setOnClickListener(view -> {
try {
mCarHvacManager.setBooleanProperty(CarHvacManager.ID_WINDOW_DEFROSTER_ON,
VehicleAreaWindow.FRONT_WINDSHIELD,
mTbDefrostFront.isChecked());
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC window defroster property", e);
}
});
}
if (prop1.hasArea(VehicleAreaWindow.REAR_WINDSHIELD)) {
mTbDefrostRear = (ToggleButton) v.findViewById(R.id.tbDefrostRear);
mTbDefrostRear.setEnabled(true);
mTbDefrostRear.setOnClickListener(view -> {
try {
mCarHvacManager.setBooleanProperty(CarHvacManager.ID_WINDOW_DEFROSTER_ON,
VehicleAreaWindow.REAR_WINDSHIELD,
mTbDefrostRear.isChecked());
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC window defroster property", e);
}
});
}
}
private void configureRecircOn(View v, CarPropertyConfig prop) {
int temp = prop.getFirstAndOnlyAreaId();
mTbRecirc = (ToggleButton)v.findViewById(R.id.tbRecirc);
mTbRecirc.setEnabled(true);
mTbRecirc.setOnClickListener(view -> {
// TODO handle zone properly
try {
mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON,
temp, mTbRecirc.isChecked());
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC boolean property", e);
}
});
}
private void configureMaxAcOn(View v, CarPropertyConfig prop) {
int temp = prop.getFirstAndOnlyAreaId();
mTbMaxAc = (ToggleButton)v.findViewById(R.id.tbMaxAc);
mTbMaxAc.setEnabled(true);
mTbMaxAc.setOnClickListener(view -> {
// TODO handle zone properly
try {
mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_MAX_AC_ON,temp,
mTbMaxAc.isChecked());
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC boolean property", e);
}
});
}
private void configureMaxDefrostOn(View v, CarPropertyConfig prop) {
int temp = prop.getFirstAndOnlyAreaId();
mTbMaxDefrost = (ToggleButton)v.findViewById(R.id.tbMaxDefrost);
mTbMaxDefrost.setEnabled(true);
mTbMaxDefrost.setOnClickListener(view -> {
// TODO handle zone properly
try {
mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_MAX_DEFROST_ON,temp,
mTbMaxDefrost.isChecked());
} catch (CarNotConnectedException e) {
Log.e(TAG, "Failed to set HVAC boolean property", e);
}
});
}
}