Home | History | Annotate | Download | only in hvac
      1 /*
      2  * Copyright (c) 2016, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.car.hvac;
     17 
     18 import android.os.SystemClock;
     19 import android.util.SparseArray;
     20 import android.util.SparseBooleanArray;
     21 import android.util.SparseIntArray;
     22 import android.util.SparseLongArray;
     23 
     24 import java.util.concurrent.TimeUnit;
     25 import javax.annotation.concurrent.GuardedBy;
     26 
     27 /**
     28  * The hvac unit can be controller from two places, the ui and the hardware buttons. Each of these
     29  * request updates to the current state from different threads. Moreover, there can be conditions
     30  * where the hvac could send spurious updates so this class routes everything through and coalesces
     31  * them, keeping the application's view of the world sane.
     32  */
     33 public class DataStore {
     34     private static final long COALESCE_TIME_MS = TimeUnit.SECONDS.toMillis(2);
     35 
     36     @GuardedBy("mTemperature")
     37     private SparseArray<Float> mTemperature = new SparseArray<Float>();
     38     @GuardedBy("mFanSpeed")
     39     private Integer mFanSpeed = 0;
     40     @GuardedBy("mAirflow")
     41     private SparseIntArray mAirflow = new SparseIntArray();
     42     @GuardedBy("mDefrosterState")
     43     private SparseBooleanArray mDefrosterState = new SparseBooleanArray();
     44     @GuardedBy("mAcState")
     45     private Boolean mAcState = false;
     46     @GuardedBy("mSeatWarmerLevel")
     47     private SparseIntArray mSeatWarmerLevel = new SparseIntArray();
     48     @GuardedBy("mAirCirculationState")
     49     private Boolean mAirCirculationState = false;
     50     @GuardedBy("mAutoModeState")
     51     private Boolean mAutoModeState = false;
     52     @GuardedBy("mHvacPowerState")
     53     private Boolean mHvacPowerState = false;
     54 
     55     @GuardedBy("mTemperature")
     56     private SparseLongArray mLastTemperatureSet = new SparseLongArray();
     57     @GuardedBy("mFanSpeed")
     58     private long mLastFanSpeedSet;
     59     @GuardedBy("mAirflow")
     60     private SparseLongArray mLastAirflowSet = new SparseLongArray();
     61     @GuardedBy("mDefrosterState")
     62     private SparseLongArray mLastDefrosterSet = new SparseLongArray();
     63     @GuardedBy("mAcState")
     64     private long mLastAcSet;
     65     @GuardedBy("mSeatWarmerLevel")
     66     private SparseLongArray mLastSeatWarmerLevel = new SparseLongArray();
     67     @GuardedBy("mAirCirculationState")
     68     private long mAirCirculationLastSet;
     69     @GuardedBy("mAutoModeState")
     70     private long mAutoModeLastSet;
     71     @GuardedBy("mHvacPowerState")
     72     private long mHvacPowerLastSet;
     73 
     74 
     75     public float getTemperature(int zone) {
     76         synchronized (mTemperature) {
     77             return mTemperature.get(zone);
     78         }
     79     }
     80 
     81     public void setTemperature(int zone, float temperature) {
     82         synchronized (mTemperature) {
     83             mTemperature.put(zone, temperature);
     84             mLastTemperatureSet.put(zone, SystemClock.uptimeMillis());
     85         }
     86     }
     87 
     88     public boolean shouldPropagateTempUpdate(int zone, float temperature) {
     89         synchronized (mTemperature) {
     90             if (SystemClock.uptimeMillis() - mLastTemperatureSet.get(zone) < COALESCE_TIME_MS) {
     91                 return false;
     92             }
     93             mTemperature.put(zone, temperature);
     94         }
     95         return true;
     96     }
     97 
     98     public boolean getDefrosterState(int zone) {
     99         synchronized (mDefrosterState) {
    100             return mDefrosterState.get(zone);
    101         }
    102     }
    103 
    104     public void setDefrosterState(int zone, boolean state) {
    105         synchronized (mDefrosterState) {
    106             mDefrosterState.put(zone, state);
    107             mLastDefrosterSet.put(zone, SystemClock.uptimeMillis());
    108         }
    109     }
    110 
    111     public boolean shouldPropagateDefrosterUpdate(int zone, boolean defrosterState) {
    112         synchronized (mDefrosterState) {
    113             if (SystemClock.uptimeMillis() - mLastDefrosterSet.get(zone) < COALESCE_TIME_MS) {
    114                 return false;
    115             }
    116             mDefrosterState.put(zone, defrosterState);
    117         }
    118         return true;
    119     }
    120 
    121     public int getFanSpeed() {
    122         synchronized (mFanSpeed) {
    123             return mFanSpeed;
    124         }
    125     }
    126 
    127     public void setFanSpeed(int speed) {
    128         synchronized (mFanSpeed) {
    129             mFanSpeed = speed;
    130             mLastFanSpeedSet = SystemClock.uptimeMillis();
    131         }
    132     }
    133 
    134     public boolean shouldPropagateFanSpeedUpdate(int zone, int speed) {
    135         // TODO: We ignore fan speed zones for now because we dont have a multi zone car.
    136         synchronized (mFanSpeed) {
    137             if (SystemClock.uptimeMillis() - mLastFanSpeedSet < COALESCE_TIME_MS) {
    138                 return false;
    139             }
    140             mFanSpeed = speed;
    141         }
    142         return true;
    143     }
    144 
    145     public boolean getAcState() {
    146         synchronized (mAcState) {
    147             return mAcState;
    148         }
    149     }
    150 
    151     public void setAcState(boolean acState) {
    152         synchronized (mAcState) {
    153             mAcState = acState;
    154             mLastAcSet = SystemClock.uptimeMillis();
    155         }
    156     }
    157 
    158     public boolean shouldPropagateAcUpdate(boolean acState) {
    159         synchronized (mAcState) {
    160             if (SystemClock.uptimeMillis() - mLastAcSet < COALESCE_TIME_MS) {
    161                 return false;
    162             }
    163             mAcState = acState;
    164         }
    165         return true;
    166     }
    167 
    168     public int getAirflow(int zone) {
    169         synchronized (mAirflow) {
    170             return mAirflow.get(zone);
    171         }
    172     }
    173 
    174     public void setAirflow(int zone, int index) {
    175         synchronized (mAirflow) {
    176             mAirflow.put(zone, index);
    177             mLastAirflowSet.put(zone, SystemClock.uptimeMillis());
    178         }
    179     }
    180 
    181     public boolean shouldPropagateFanPositionUpdate(int zone, int index) {
    182         synchronized (mAirflow) {
    183             if (SystemClock.uptimeMillis() - mLastAirflowSet.get(zone) < COALESCE_TIME_MS) {
    184                 return false;
    185             }
    186             mAirflow.put(zone, index);
    187         }
    188         return true;
    189     }
    190 
    191     public float getSeatWarmerLevel(int zone) {
    192         synchronized (mSeatWarmerLevel) {
    193             return mSeatWarmerLevel.get(zone);
    194         }
    195     }
    196 
    197     public void setSeatWarmerLevel(int zone, int level) {
    198         synchronized (mSeatWarmerLevel) {
    199             mSeatWarmerLevel.put(zone, level);
    200             mLastSeatWarmerLevel.put(zone, SystemClock.uptimeMillis());
    201         }
    202     }
    203 
    204     public boolean shouldPropagateSeatWarmerLevelUpdate(int zone, int level) {
    205         synchronized (mSeatWarmerLevel) {
    206             if (SystemClock.uptimeMillis() - mLastSeatWarmerLevel.get(zone) < COALESCE_TIME_MS) {
    207                 return false;
    208             }
    209             mSeatWarmerLevel.put(zone, level);
    210         }
    211         return true;
    212     }
    213 
    214     public boolean getAirCirculationState() {
    215         synchronized (mAirCirculationState) {
    216             return mAirCirculationState;
    217         }
    218     }
    219 
    220     public void setAirCirculationState(boolean airCirculationState) {
    221         synchronized (mAirCirculationState) {
    222             mAirCirculationState = airCirculationState;
    223             mAirCirculationLastSet = SystemClock.uptimeMillis();
    224         }
    225     }
    226 
    227     public boolean shouldPropagateAirCirculationUpdate(boolean airCirculationState) {
    228         synchronized (mAirCirculationState) {
    229             if (SystemClock.uptimeMillis() - mAirCirculationLastSet < COALESCE_TIME_MS) {
    230                 return false;
    231             }
    232             mAcState = airCirculationState;
    233         }
    234         return true;
    235     }
    236 
    237     public boolean getAutoModeState() {
    238         synchronized (mAutoModeState) {
    239             return mAutoModeState;
    240         }
    241     }
    242 
    243     public void setAutoModeState(boolean autoModeState) {
    244         synchronized (mAutoModeState) {
    245             mAutoModeState = autoModeState;
    246             mAutoModeLastSet = SystemClock.uptimeMillis();
    247         }
    248     }
    249 
    250     public boolean shouldPropagateAutoModeUpdate(boolean autoModeState) {
    251         synchronized (mAutoModeState) {
    252             if (SystemClock.uptimeMillis() - mAutoModeLastSet < COALESCE_TIME_MS) {
    253                 return false;
    254             }
    255             mAcState = autoModeState;
    256         }
    257         return true;
    258     }
    259 
    260     public boolean getHvacPowerState() {
    261         synchronized (mHvacPowerState) {
    262             return mHvacPowerState;
    263         }
    264     }
    265 
    266     public void setHvacPowerState(boolean hvacPowerState) {
    267         synchronized (mHvacPowerState) {
    268             mHvacPowerState = hvacPowerState;
    269             mHvacPowerLastSet = SystemClock.uptimeMillis();
    270         }
    271     }
    272 
    273     public boolean shouldPropagateHvacPowerUpdate(boolean hvacPowerState) {
    274         synchronized (mHvacPowerState) {
    275             if (SystemClock.uptimeMillis() - mHvacPowerLastSet < COALESCE_TIME_MS) {
    276                 return false;
    277             }
    278             mHvacPowerState = hvacPowerState;
    279         }
    280         return true;
    281     }
    282 }
    283