17861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik#!/usr/bin/env python 27861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# -*- coding: utf-8 -*- 37861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# 47861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Copyright 2016 Google Inc. 57861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# 67861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Licensed under the Apache License, Version 2.0 (the "License"); 77861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# you may not use this file except in compliance with the License. 87861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# You may obtain a copy of the License at 97861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# 107861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# http://www.apache.org/licenses/LICENSE-2.0 117861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# 127861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Unless required by applicable law or agreed to in writing, software 137861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# distributed under the License is distributed on an "AS IS" BASIS, 147861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 157861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# See the License for the specific language governing permissions and 167861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# limitations under the License. 177861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# 187861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 197861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik""" 207861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik This module provides a vhal class which sends and receives messages to the vehicle HAL module 217861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik on an Android Auto device. It uses port forwarding via ADB to communicted with the Android 227861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik device. 237861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 247861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Example Usage: 257861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 267861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik import vhal_consts_1_0 as c 277861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik from vhal_emulator import Vhal 287861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 297861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Create an instance of vhal class. Need to pass the vhal_types constants. 307861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik v = Vhal(c.vhal_types_1_0) 317861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 327861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Get the property config (if desired) 337861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik v.getConfig(c.VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET) 347861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 357861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Get the response message to getConfig() 367861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik reply = v.rxMsg() 377861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik print reply 387861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 397861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Set left temperature to 70 degrees 407861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik v.setProperty(c.VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET, c.VEHICLE_ZONE_ROW_1_LEFT, 70) 417861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 427861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Get the response message to setProperty() 437861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik reply = v.rxMsg() 447861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik print reply 457861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 467861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Get the left temperature value 477861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik v.getProperty(c.VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET, c.VEHICLE_ZONE_ROW_1_LEFT) 487861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 497861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Get the response message to getProperty() 507861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik reply = v.rxMsg() 517861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik print reply 527861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 537861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik NOTE: The rxMsg() is a blocking call, so it may be desirable to set up a separate RX thread 547861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik to handle any asynchronous messages coming from the device. 557861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 567861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Example for creating RX thread (assumes vhal has already been instantiated): 577861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 587861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik from threading import Thread 597861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 607861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Define a simple thread that receives messags from a vhal object (v) and prints them 617861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def rxThread(v): 627861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik while(1): 637861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik print v.rxMsg() 647861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 657861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik rx = Thread(target=rxThread, args=(v,)) 667861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik rx.start() 677861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 687861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Protocol Buffer: 697861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik This module relies on VehicleHalProto_pb2.py being in sync with the protobuf in the VHAL. 707861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik If the VehicleHalProto.proto file has changed, re-generate the python version using: 717861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 727861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik protoc -I=<proto_dir> --python_out=<out_dir> <proto_dir>/VehicleHalProto.proto 737861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik""" 747861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 757861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Suppress .pyc files 767861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport sys 777861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paiksys.dont_write_bytecode = True 787861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 797861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport socket 807861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport struct 817861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport subprocess 827861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 837861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# Generate the protobuf file from vendor/auto/embedded/lib/vehicle_hal: 847861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik# protoc -I=proto --python_out=proto proto/VehicleHalProto.proto 857861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikimport VehicleHalProto_pb2 867861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 877861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 887861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paikclass Vhal: 897861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 907861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Dictionary of prop_id to value_type. Used by setProperty() to properly format data. 917861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 927861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik _propToType = {} 937861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 947861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik ### Private Functions 957861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def _txCmd(self, cmd): 967861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 977861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Transmits a protobuf to Android Auto device. Should not be called externally. 987861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 997861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Serialize the protobuf into a string 1007861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik msgStr = cmd.SerializeToString() 1017861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik msgLen = len(msgStr) 1027861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Convert the message length into int32 byte array 1037861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik msgHdr = struct.pack('!I', msgLen) 1047861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Send the message length first 1057861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self.sock.send(msgHdr) 1067861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Then send the protobuf 1077861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self.sock.send(msgStr) 1087861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 1097861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik ### Public Functions 1107861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def printHex(self, data): 1117861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1127861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik For debugging, print the protobuf message string in hex. 1137861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1147861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik print "len = ", len(data), "str = ", ":".join("{:02x}".format(ord(d)) for d in data) 1157861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 1167861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def openSocket(self): 1177861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1187861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Connects to an Android Auto device running a Vehicle HAL with simulator. 1197861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1207861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Hard-coded socket port needs to match the one in DefaultVehicleHal 1217861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik portNumber = 33452 1227861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Setup ADB port forwarding 1237861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik subprocess.call("adb forward tcp:%d tcp:%d" % (portNumber, portNumber), shell=True) 1247861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Open the socket and connect 1257861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 1267861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self.sock.connect(('localhost', portNumber)) 1277861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 1287861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def rxMsg(self): 1297861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1307861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Receive a message over the socket. This function blocks if a message is not available. 1317861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik May want to wrap this function inside of an rx thread to also collect asynchronous 1327861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik messages generated by the device. 1337861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1347861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Receive the message length (int32) first 1357861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik b = self.sock.recv(4) 1367861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik if (len(b) == 4): 1377861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik msgLen, = struct.unpack('!I', b) 1387861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik if (msgLen > 0): 1397861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Receive the actual message 1407861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik b = self.sock.recv(msgLen) 1417861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik if (len(b) == msgLen): 1427861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Unpack the protobuf 1437861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik msg = VehicleHalProto_pb2.EmulatorMessage() 1447861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik msg.ParseFromString(b) 1457861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik return msg 1467861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 1477861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def getConfig(self, prop): 1487861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1497861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Sends a getConfig message for the specified property. 1507861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1517861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd = VehicleHalProto_pb2.EmulatorMessage() 1527861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd.msg_type = VehicleHalProto_pb2.GET_CONFIG_CMD 1537861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propGet = cmd.prop.add() 1547861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propGet.prop = prop 1557861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self._txCmd(cmd) 1567861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 1577861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def getConfigAll(self): 1587861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1597861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Sends a getConfigAll message to the host. This will return all configs avaialable. 1607861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1617861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd = VehicleHalProto_pb2.EmulatorMessage() 1627861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd.msg_type = VehicleHalProto_pb2.GET_CONFIG_ALL_CMD 1637861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self._txCmd(cmd) 1647861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 1657861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def getProperty(self, prop, area_id): 1667861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1677861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Sends a getProperty command for the specified property ID and area ID. 1687861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1697861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd = VehicleHalProto_pb2.EmulatorMessage() 1707861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd.msg_type = VehicleHalProto_pb2.GET_PROPERTY_CMD 1717861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propGet = cmd.prop.add() 1727861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propGet.prop = prop 1737861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propGet.area_id = area_id 1747861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self._txCmd(cmd) 1757861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 1767861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def getPropertyAll(self): 1777861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1787861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Sends a getPropertyAll message to the host. This will return all properties avaialable. 1797861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1807861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd = VehicleHalProto_pb2.EmulatorMessage() 1817861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd.msg_type = VehicleHalProto_pb2.GET_PROPERTY_ALL_CMD 1827861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self._txCmd(cmd) 1837861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 1847861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def setProperty(self, prop, area_id, value): 1857861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1867861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik Sends a setProperty command for the specified property ID, area ID, and value. 1877861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik This function chooses the proper value field to populate based on the config for the 1887861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik property. It is the caller's responsibility to ensure the value data is the proper 1897861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik type. 1907861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik """ 1917861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd = VehicleHalProto_pb2.EmulatorMessage() 1927861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik cmd.msg_type = VehicleHalProto_pb2.SET_PROPERTY_CMD 1937861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue = cmd.value.add() 1947861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.prop = prop 1957861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Insert value into the proper area 1967861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.area_id = area_id 1977861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Determine the value_type and populate the correct value field in protoBuf 1987861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik try: 1997861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik valType = self._propToType[prop] 2007861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik except KeyError: 2017861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik raise ValueError('propId is invalid:', prop) 2027861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik return 2037861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.value_type = valType 2047861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik if valType in self._types.TYPE_STRING: 2057861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.string_value = value 2067861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik elif valType in self._types.TYPE_BYTES: 2077861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.bytes_value = value 2087861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik elif valType in self._types.TYPE_INT32: 2097861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.int32_values.append(value) 2107861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik elif valType in self._types.TYPE_INT64: 2117861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.int64_values.append(value) 2127861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik elif valType in self._types.TYPE_FLOAT: 2137861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.float_values.append(value) 2147861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik elif valType in self._types.TYPE_INT32S: 2157861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.int32_values.extend(value) 2167861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik elif valType in self._types.TYPE_FLOATS: 2177861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik propValue.float_values.extend(value) 2187861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik else: 2197861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik raise ValueError('value type not recognized:', valType) 2207861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik return 2217861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self._txCmd(cmd) 2227861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 2237861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik def __init__(self, types): 2247861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Save the list of types constants 2257861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self._types = types 2267861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Open the socket 2277861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self.openSocket() 2287861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Get the list of configs 2297861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self.getConfigAll() 2307861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik msg = self.rxMsg() 2317861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik # Parse the list of configs to generate a dictionary of prop_id to type 2327861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik for cfg in msg.config: 2337861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik self._propToType[cfg.prop] = cfg.value_type 2347861f4ef37a73f8ef84c0a68b03a4fbf7d039d2cSteve Paik 235