diff options
author | Magnus <mfeuer@jaguarlandrover.com> | 2014-08-14 15:19:54 -0700 |
---|---|---|
committer | Magnus <mfeuer@jaguarlandrover.com> | 2014-08-14 15:19:54 -0700 |
commit | d6c91161c84b752d1ef32895c8852cd9d0eaa5c0 (patch) | |
tree | 8112e808fcbc95360d9f21ed6c579a394441db9f | |
parent | df443db87b48dd35f511399f001ec757e420af83 (diff) | |
download | rvi_core-d6c91161c84b752d1ef32895c8852cd9d0eaa5c0.tar.gz |
Split mobile and ivi emulator into two parts
Signed-off-by: Magnus <mfeuer@jaguarlandrover.com>
-rwxr-xr-x | hvac_demo/hvac_ivi_emulator.py | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/hvac_demo/hvac_ivi_emulator.py b/hvac_demo/hvac_ivi_emulator.py new file mode 100755 index 0000000..fa9fb7a --- /dev/null +++ b/hvac_demo/hvac_ivi_emulator.py @@ -0,0 +1,191 @@ +#!/usr/bin/python + +# +# Copyright (C) 2014, Jaguar Land Rover +# +# This program is licensed under the terms and conditions of the +# Mozilla Public License, version 2.0. The full text of the +# Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ +# + +# +# Emulate a mobile device or an IVI. +# +# This emulator connects to an RVI Service Edge as a service and +# simulates an IVI unit installed in a vehicle. +# +# The emulator connects to the Service Edge of locally accessible RVI +# node and subscribes to updates from one or more mobile +# devices. Local updates, simulating GUI input on the HVAC screen, +# can be entered at the command line and will be distributed to the +# phone(s) subscribing to updates from the IVI. +# +# Any HVAC values updated on the command line are sent to the +# service jlr.com/backend/hvac/subscription_service/publish. This +# service will look up VIN targeted by the update and send out the +# same data to all services that are subscribing to that VIN. +# +# In mobile device mode, the emulator will subscribe to updated +# values published to to the VIN value "ivi_[vin]" where vin is the +# VIN number of the IVI. When a emulator, still in mobile device +# mode, sends out an updated value (entered in the python console), +# it will publish the value using the vin "mobile_[vin]" +# +# Converesely, an emulator in IVI mode will sbuscribe to +# "mobile_[vin]", and publish to "ivi_[vin]". +# +# This setup allows the mobile device emulator to receive updates +# entered on the IVI HVAC screen (sent out by the IVI to +# "ivi_[vin]"), while the IVI emulator receives updates entered on +# the mobile device screen (sent out by the mobile device to +# "mobile_[vin]". +# +# When the emulator connects in IVI mode to an RVI node, the +# node's configured service prefix (see priv/ivi.config, +# node_service_prefix) will have the VIN number as a part of the +# prefix. The emulator will thus register its service as /hvac/publish, +# which, prefixed with the node service prefix, gives it a complete name +# of jlr.com/vin/[vin]/hvac/publish. +# +# +# Example: +# python hvac_mobile_emulator.pyh 9491231234 http://127.0.0.1:8811 +# +import sys +from rvi_json_rpc_server import RVIJSONRPCServer +import jsonrpclib +import random +import threading + +# The subscriber service (MQTT server equivalent), that +# manages subscriptions and distributes received publish commands to +# the relevant subscribers. +# +SUBSCRIPTION_SERVICE_BASE='jlr.com/backend/subscription_service' +SUBSCRIBE_SERVICE=SUBSCRIPTION_SERVICE_BASE+'/subscribe' +PUBLISH_SERVICE=SUBSCRIPTION_SERVICE_BASE+'/publish' + +# +# Publish command is invoked by the +# subscriber server above when it receives a publish command +# from a VIN that this emulator subscribes to. +# +def publish(vin, key, value): + print + print "Publish invoked!" + print "vin:", vin + print "key:", key + print "value:", value + print + sys.stdout.write("Enter <key> <val> or q to quit: ") + sys.stdout.flush() + return ['ok'] + +def usage(): + print "Usage:", sys.argv[0], "<rvi_url>" + print " <rvi_url> URL of Service Edge on a local RVI node" + print + print "The RVI Service Edge URL can be found in" + print "priv/[backend,ivi].config as" + print "env -> rvi -> components -> service_edge -> url" + print + print "The Service Edge URL is also logged as a notice when the" + print "RVI node is started." + sys.exit(255) + + +# Setup self's server that we will receive incoming calls from service edge on. + +# +# Setup a localhost URL, using a random port, that we will listen to +# incoming JSON-RPC publish calls on, delivered by our RVI service +# edge (specified by rvi_url). +# +emulator_service_host = 'localhost' +emulator_service_port = random.randint(20001, 59999) +emulator_service_url = 'http://'+emulator_service_host + ':' + str(emulator_service_port) + +# +# Check that we have the correct arguments +# +if len(sys.argv) != 2: + usage() + +# Grab the URL to use +[ progname, rvi_url ] = sys.argv + + +# setup the service name we will register with +# The complete service name will be: jlr.com/vin/<vin>/hvac/publish +emulator_service_name = '/hvac/publish' + +# Setup an outbound JSON-RPC connection to the RVI Service Edeg. +rvi_server = jsonrpclib.Server(rvi_url) + +# Register our HVAC IVI emulator service with the RVI Service Edge, +# allowing the RVI to forward requests to the service name to the +# given network addresss (URL): +res = rvi_server.register_service(service = emulator_service_name, + network_address = emulator_service_url) + +# The returned full service name contains the VIN number that we want: +# jlr.com/vin/<vin>/hvac/publish +# We need to dig out the <vin> bit +full_emulator_service_name = res['service'] + +[ t1, t2, vin, t3, t4] = full_emulator_service_name.split('/') + +# We are in mobile device mode. Setup the vin numbers for publish +pub_vin = "ivi_"+vin +sub_vin = "mobile_"+vin + +print "IVI Emulator." +print "IVI RVI node URL: ", rvi_url +print "Emulator URL: ", emulator_service_url +print "VIN: ", vin +print "Full service name ", full_emulator_service_name + +# Regsiter self's service with the backend server RVI node +# See rvi_json_rpc_server.py._dispatch() for details on how +# incoming JSON-RPC requests are mapped to local funcitons. +# +emulator_service = RVIJSONRPCServer(addr=((emulator_service_host, emulator_service_port)), logRequests=False) +emulator_service.register_function(publish, emulator_service_name) + +# Send of a subscribe to the subscription service running on the +# backend. See hvac_subscription_service.py.subscribe() for details. + +rvi_server.message(calling_service = emulator_service_name, + target = SUBSCRIBE_SERVICE, + timeout = 0, + parameters = [{ u'vin': sub_vin, + u'subscribing_service': full_emulator_service_name}]) + +# Create a thread to handle incoming stuff so that we can do input +# in order to get new values +thr = threading.Thread(target=emulator_service.serve_forever) +thr.start() + +while True: + line = raw_input('Enter <key> <val> or "q" for quit: ') + if line == 'q': + emulator_service.shutdown() + sys.exit(0) + + # Read a line and split it into a key val pair + lst = line.split(' ') + if len(lst) != 2: + print "Nope", len(lst), lst + continue + + [k, v] = line.split(' ') + + # Send out update to the subscriber + rvi_server.message(calling_service= emulator_service_name, + target = PUBLISH_SERVICE, + timeout = 0, + parameters = [{ u'vin': pub_vin, + u'key': k, + u'value': v}]) + + print('Key {} set to {} for vin{}'. format(k, v, vin)) |