# Copyright (C) 2017 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. # import time import vhal_consts_2_0 as c # A list of user actions as a subset of VHAL properties to simulate userActions = [ c.VEHICLEPROPERTY_HVAC_POWER_ON, c.VEHICLEPROPERTY_HVAC_TEMPERATURE_SET, c.VEHICLEPROPERTY_HVAC_FAN_SPEED, c.VEHICLEPROPERTY_HVAC_FAN_DIRECTION, c.VEHICLEPROPERTY_HVAC_AUTO_ON, c.VEHICLEPROPERTY_HVAC_RECIRC_ON, c.VEHICLEPROPERTY_HVAC_AC_ON, c.VEHICLEPROPERTY_HVAC_DEFROSTER ] propDesc = { c.VEHICLEPROPERTY_HVAC_POWER_ON: 'HVAC_POWER_ON', c.VEHICLEPROPERTY_HVAC_TEMPERATURE_SET: 'HVAC_TEMPERATURE_SET', c.VEHICLEPROPERTY_HVAC_FAN_SPEED: 'HVAC_FAN_SPEED', c.VEHICLEPROPERTY_HVAC_FAN_DIRECTION: 'HVAC_FAN_DIRECTION', c.VEHICLEPROPERTY_HVAC_AUTO_ON: 'HVAC_AUTO_ON', c.VEHICLEPROPERTY_HVAC_RECIRC_ON: 'HVAC_AUTO_RECIRC_ON', c.VEHICLEPROPERTY_HVAC_AC_ON: 'HVAC_AC_ON', c.VEHICLEPROPERTY_HVAC_DEFROSTER: 'HVAC_DEFROSTER' } SHORT_SLEEP_TIME_SEC = 2 LONG_SLEEP_TIME_SEC = 30 MIN_TEMPERATURE_C = 22 MAX_TEMPERATURE_C = 28 MIN_FAN_SPEED = 1 MAX_FAN_SPEED = 5 class ActionPropConfig(object): """ A configuration class that parse the vhal property config message and hold the configuration values """ def __init__(self, vhalConfig): self.supportedAreas = self._getSupportedAreas(vhalConfig) self.areaConfigs = self._getAreaConfigs(vhalConfig, self.supportedAreas, vhalConfig.value_type) def _getSupportedAreas(self, vhalConfig): supportedAreas = [] for config in vhalConfig.area_configs: supportedAreas.append(config.area_id) return supportedAreas def _getAreaConfigs(self, vhalConfig, supportedAreas, valueType): areaConfigs = {} configs = vhalConfig.area_configs if not configs: return None if len(configs) == 1: for area in supportedAreas: areaConfigs[area] = AreaConfig(configs[0], valueType) else: for config in configs: areaConfigs[config.area_id] = AreaConfig(config, valueType) return areaConfigs class AreaConfig(object): """ A configuration class is representing an area config of a vhal property. """ def __init__(self, vhalAreaConfig, valueType): """ The class is initialized by parsing the vhal area config object """ if valueType == c.VEHICLEPROPERTYTYPE_INT32: self.min = vhalAreaConfig.min_int32_value self.max = vhalAreaConfig.max_int32_value elif valueType == c.VEHICLEPROPERTYTYPE_INT64: self.min = vhalAreaConfig.min_int64_value self.max = vhalAreaConfig.max_int64_value elif valueType == c.VEHICLEPROPERTYTYPE_FLOAT: self.min = vhalAreaConfig.min_float_value self.max = vhalAreaConfig.max_float_value else: self.min = None self.max = None class UserActionGenerator(object): """ A class generate user action related vhal properties in a deterministic algorithm based on pre-fetched vhal configuration """ def __init__(self, vhal): self.configs = self._getConfig(vhal) def _getConfig(self, vhal): """ Get vhal configuration for properties that need to be simulated """ vhalConfig = {} for actionProp in userActions: vhal.getConfig(actionProp) vhalConfig[actionProp] = ActionPropConfig(vhal.rxMsg().config[0]) return vhalConfig def _adjustContinuousProperty(self, prop, begin, end, listener): """ The method generate continuous property value from "begin" value to "end" value (exclusive). """ config = self.configs[prop] for area in config.supportedAreas: areaConfig = config.areaConfigs[area] if begin < end: begin = areaConfig.min if begin < areaConfig.min else begin end = areaConfig.max if end > areaConfig.max else end else: begin = areaConfig.max if begin > areaConfig.max else begin end = areaConfig.min if end < areaConfig.min else end for value in self._range(begin, end): listener.handle(prop, area, value, propDesc[prop]) time.sleep(0.2) def _setProperty(self, prop, value, listener): """ This method generates single property value (e.g. boolean or integer value) """ config = self.configs[prop] for area in config.supportedAreas: listener.handle(prop, area, value, propDesc[prop]) time.sleep(1) def _range(self, begin, end): if begin < end: i = begin while i < end: yield i i += 1 else: i = begin while i > end: yield i i += -1 def generate(self, listener): """ Main method that simulate user in-car actions such as HVAC """ # Turn on HVAC only for front seats listener.handle(c.VEHICLEPROPERTY_HVAC_POWER_ON, c.VEHICLEAREASEAT_ROW_1_LEFT, 1, 'HVAC_POWER_ON') listener.handle(c.VEHICLEPROPERTY_HVAC_POWER_ON, c.VEHICLEAREASEAT_ROW_1_RIGHT, 1, 'HVAC_POWER_ON') time.sleep(SHORT_SLEEP_TIME_SEC) while True: self._setProperty(c.VEHICLEPROPERTY_HVAC_AC_ON, 1, listener) time.sleep(SHORT_SLEEP_TIME_SEC) self._setProperty(c.VEHICLEPROPERTY_HVAC_FAN_DIRECTION, c.VEHICLEHVACFANDIRECTION_FACE, listener) time.sleep(SHORT_SLEEP_TIME_SEC) self._adjustContinuousProperty(c.VEHICLEPROPERTY_HVAC_TEMPERATURE_SET, MAX_TEMPERATURE_C, MIN_TEMPERATURE_C, listener) time.sleep(SHORT_SLEEP_TIME_SEC) self._adjustContinuousProperty(c.VEHICLEPROPERTY_HVAC_FAN_SPEED, MIN_FAN_SPEED, MAX_FAN_SPEED, listener) time.sleep(LONG_SLEEP_TIME_SEC) self._setProperty(c.VEHICLEPROPERTY_HVAC_AUTO_ON, 1, listener) time.sleep(LONG_SLEEP_TIME_SEC) self._setProperty(c.VEHICLEPROPERTY_HVAC_AUTO_ON, 0, listener) time.sleep(SHORT_SLEEP_TIME_SEC) self._setProperty(c.VEHICLEPROPERTY_HVAC_FAN_DIRECTION, c.VEHICLEHVACFANDIRECTION_FACE, listener) time.sleep(LONG_SLEEP_TIME_SEC) self._setProperty(c.VEHICLEPROPERTY_HVAC_DEFROSTER, 1, listener) time.sleep(SHORT_SLEEP_TIME_SEC) self._setProperty(c.VEHICLEPROPERTY_HVAC_FAN_DIRECTION, c.VEHICLEHVACFANDIRECTION_DEFROST, listener) time.sleep(SHORT_SLEEP_TIME_SEC) self._adjustContinuousProperty(c.VEHICLEPROPERTY_HVAC_TEMPERATURE_SET, MIN_TEMPERATURE_C, MAX_TEMPERATURE_C, listener) time.sleep(SHORT_SLEEP_TIME_SEC) self._adjustContinuousProperty(c.VEHICLEPROPERTY_HVAC_FAN_SPEED, MAX_FAN_SPEED, MIN_FAN_SPEED, listener) time.sleep(LONG_SLEEP_TIME_SEC) self._setProperty(c.VEHICLEPROPERTY_HVAC_AC_ON, 0, listener) time.sleep(SHORT_SLEEP_TIME_SEC)