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