10eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer/* 20eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * Copyright (c) 2016, The Android Open Source Project 30eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * 40eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * Licensed under the Apache License, Version 2.0 (the "License"); 50eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * you may not use this file except in compliance with the License. 60eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * You may obtain a copy of the License at 70eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * 80eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * http://www.apache.org/licenses/LICENSE-2.0 90eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * 100eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * Unless required by applicable law or agreed to in writing, software 110eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * distributed under the License is distributed on an "AS IS" BASIS, 120eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * See the License for the specific language governing permissions and 140eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * limitations under the License. 150eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer */ 160eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerpackage com.android.car.hvac; 170eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 180eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.os.SystemClock; 199e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granataimport android.util.Log; 200eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.util.SparseArray; 210eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.util.SparseBooleanArray; 220eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.util.SparseIntArray; 230eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport android.util.SparseLongArray; 240eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 250eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport java.util.concurrent.TimeUnit; 260eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerimport javax.annotation.concurrent.GuardedBy; 270eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 280eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer/** 290eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * The hvac unit can be controller from two places, the ui and the hardware buttons. Each of these 300eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * request updates to the current state from different threads. Moreover, there can be conditions 310eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * where the hvac could send spurious updates so this class routes everything through and coalesces 320eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer * them, keeping the application's view of the world sane. 330eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer */ 340eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyerpublic class DataStore { 350eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private static final long COALESCE_TIME_MS = TimeUnit.SECONDS.toMillis(2); 360eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 370eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mTemperature") 380eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private SparseArray<Float> mTemperature = new SparseArray<Float>(); 399e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata @GuardedBy("mTemperatureAvailable") 409e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata private SparseBooleanArray mTemperatureAvailable = new SparseBooleanArray(); 410eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mFanSpeed") 420eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private Integer mFanSpeed = 0; 430eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mAirflow") 440eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private SparseIntArray mAirflow = new SparseIntArray(); 450eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mDefrosterState") 460eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private SparseBooleanArray mDefrosterState = new SparseBooleanArray(); 470eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mAcState") 480eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private Boolean mAcState = false; 490eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mSeatWarmerLevel") 500eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private SparseIntArray mSeatWarmerLevel = new SparseIntArray(); 510eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mAirCirculationState") 520eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private Boolean mAirCirculationState = false; 530eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mAutoModeState") 540eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private Boolean mAutoModeState = false; 550eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mHvacPowerState") 560eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private Boolean mHvacPowerState = false; 570eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 580eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mTemperature") 590eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private SparseLongArray mLastTemperatureSet = new SparseLongArray(); 600eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mFanSpeed") 610eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private long mLastFanSpeedSet; 620eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mAirflow") 630eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private SparseLongArray mLastAirflowSet = new SparseLongArray(); 640eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mDefrosterState") 650eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private SparseLongArray mLastDefrosterSet = new SparseLongArray(); 660eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mAcState") 670eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private long mLastAcSet; 680eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mSeatWarmerLevel") 690eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private SparseLongArray mLastSeatWarmerLevel = new SparseLongArray(); 700eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mAirCirculationState") 710eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private long mAirCirculationLastSet; 720eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mAutoModeState") 730eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private long mAutoModeLastSet; 740eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer @GuardedBy("mHvacPowerState") 750eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer private long mHvacPowerLastSet; 760eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 770eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 780eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public float getTemperature(int zone) { 790eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mTemperature) { 800eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mTemperature.get(zone); 810eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 820eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 830eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 849e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata public void setTemperature(int zone, float temperature, boolean available) { 850eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mTemperature) { 869e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata synchronized (mTemperatureAvailable) { 879e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata Log.d("HvacDataStore", "setTemperature(" + zone + ", " + temperature + ")"); 889e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata mTemperature.put(zone, temperature); 899e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata mTemperatureAvailable.put(zone, available); 909e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata mLastTemperatureSet.put(zone, SystemClock.uptimeMillis()); 919e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata } 920eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 930eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 940eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 959e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata public boolean shouldPropagateTempUpdate(int zone, float temperature, boolean available) { 960eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mTemperature) { 979e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata synchronized (mTemperatureAvailable) { 989e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata if (SystemClock.uptimeMillis() - mLastTemperatureSet.get(zone) < COALESCE_TIME_MS) { 999e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata if (available == mTemperatureAvailable.get(zone)) { 1009e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata return false; 1019e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata } 1029e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata } 1030eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1049e5e6b74668dd7e5143eca428ab61bec6033f57bEnrico Granata setTemperature(zone, temperature, available); 1050eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1060eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 1070eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1080eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1090eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean getDefrosterState(int zone) { 1100eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mDefrosterState) { 1110eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mDefrosterState.get(zone); 1120eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1130eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1140eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1150eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public void setDefrosterState(int zone, boolean state) { 1160eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mDefrosterState) { 1170eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mDefrosterState.put(zone, state); 1180eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mLastDefrosterSet.put(zone, SystemClock.uptimeMillis()); 1190eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1200eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1210eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1220eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean shouldPropagateDefrosterUpdate(int zone, boolean defrosterState) { 1230eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mDefrosterState) { 1240eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer if (SystemClock.uptimeMillis() - mLastDefrosterSet.get(zone) < COALESCE_TIME_MS) { 1250eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return false; 1260eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1270eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mDefrosterState.put(zone, defrosterState); 1280eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1290eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 1300eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1310eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1320eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public int getFanSpeed() { 1330eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mFanSpeed) { 1340eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mFanSpeed; 1350eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1360eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1370eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1380eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public void setFanSpeed(int speed) { 1390eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mFanSpeed) { 1400eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mFanSpeed = speed; 1410eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mLastFanSpeedSet = SystemClock.uptimeMillis(); 1420eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1430eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1440eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1450eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean shouldPropagateFanSpeedUpdate(int zone, int speed) { 1460eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer // TODO: We ignore fan speed zones for now because we dont have a multi zone car. 1470eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mFanSpeed) { 1480eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer if (SystemClock.uptimeMillis() - mLastFanSpeedSet < COALESCE_TIME_MS) { 1490eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return false; 1500eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1510eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mFanSpeed = speed; 1520eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1530eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 1540eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1550eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1560eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean getAcState() { 1570eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAcState) { 1580eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mAcState; 1590eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1600eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1610eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1620eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public void setAcState(boolean acState) { 1630eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAcState) { 1640eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAcState = acState; 1650eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mLastAcSet = SystemClock.uptimeMillis(); 1660eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1670eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1680eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1690eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean shouldPropagateAcUpdate(boolean acState) { 1700eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAcState) { 1710eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer if (SystemClock.uptimeMillis() - mLastAcSet < COALESCE_TIME_MS) { 1720eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return false; 1730eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1740eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAcState = acState; 1750eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1760eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 1770eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1780eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1790eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public int getAirflow(int zone) { 1800eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAirflow) { 1810eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mAirflow.get(zone); 1820eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1830eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1840eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1850eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public void setAirflow(int zone, int index) { 1860eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAirflow) { 1870eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAirflow.put(zone, index); 1880eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mLastAirflowSet.put(zone, SystemClock.uptimeMillis()); 1890eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1900eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1910eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 1920eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean shouldPropagateFanPositionUpdate(int zone, int index) { 1930eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAirflow) { 1940eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer if (SystemClock.uptimeMillis() - mLastAirflowSet.get(zone) < COALESCE_TIME_MS) { 1950eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return false; 1960eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1970eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAirflow.put(zone, index); 1980eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 1990eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 2000eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2010eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2020eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public float getSeatWarmerLevel(int zone) { 2030eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mSeatWarmerLevel) { 2040eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mSeatWarmerLevel.get(zone); 2050eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2060eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2070eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2080eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public void setSeatWarmerLevel(int zone, int level) { 2090eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mSeatWarmerLevel) { 2100eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mSeatWarmerLevel.put(zone, level); 2110eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mLastSeatWarmerLevel.put(zone, SystemClock.uptimeMillis()); 2120eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2130eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2140eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2150eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean shouldPropagateSeatWarmerLevelUpdate(int zone, int level) { 2160eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mSeatWarmerLevel) { 2170eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer if (SystemClock.uptimeMillis() - mLastSeatWarmerLevel.get(zone) < COALESCE_TIME_MS) { 2180eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return false; 2190eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2200eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mSeatWarmerLevel.put(zone, level); 2210eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2220eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 2230eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2240eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2250eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean getAirCirculationState() { 2260eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAirCirculationState) { 2270eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mAirCirculationState; 2280eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2290eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2300eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2310eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public void setAirCirculationState(boolean airCirculationState) { 2320eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAirCirculationState) { 2330eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAirCirculationState = airCirculationState; 2340eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAirCirculationLastSet = SystemClock.uptimeMillis(); 2350eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2360eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2370eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2380eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean shouldPropagateAirCirculationUpdate(boolean airCirculationState) { 2390eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAirCirculationState) { 2400eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer if (SystemClock.uptimeMillis() - mAirCirculationLastSet < COALESCE_TIME_MS) { 2410eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return false; 2420eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2430eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAcState = airCirculationState; 2440eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2450eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 2460eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2470eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2480eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean getAutoModeState() { 2490eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAutoModeState) { 2500eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mAutoModeState; 2510eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2520eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2530eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2540eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public void setAutoModeState(boolean autoModeState) { 2550eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAutoModeState) { 2560eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAutoModeState = autoModeState; 2570eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAutoModeLastSet = SystemClock.uptimeMillis(); 2580eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2590eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2600eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2610eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean shouldPropagateAutoModeUpdate(boolean autoModeState) { 2620eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mAutoModeState) { 2630eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer if (SystemClock.uptimeMillis() - mAutoModeLastSet < COALESCE_TIME_MS) { 2640eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return false; 2650eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2660eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mAcState = autoModeState; 2670eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2680eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 2690eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2700eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2710eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean getHvacPowerState() { 2720eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mHvacPowerState) { 2730eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return mHvacPowerState; 2740eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2750eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2760eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2770eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public void setHvacPowerState(boolean hvacPowerState) { 2780eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mHvacPowerState) { 2790eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mHvacPowerState = hvacPowerState; 2800eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mHvacPowerLastSet = SystemClock.uptimeMillis(); 2810eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2820eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2830eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer 2840eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer public boolean shouldPropagateHvacPowerUpdate(boolean hvacPowerState) { 2850eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer synchronized (mHvacPowerState) { 2860eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer if (SystemClock.uptimeMillis() - mHvacPowerLastSet < COALESCE_TIME_MS) { 2870eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return false; 2880eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2890eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer mHvacPowerState = hvacPowerState; 2900eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2910eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer return true; 2920eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer } 2930eecb13879c6f0abaf3d4c64fd19941777200eaeRakesh Iyer} 294