├── .gitignore ├── sample ├── wydot-filtered-bsm-1512496037271.json └── wydot-filtered-tim-1512415831724.json ├── README.md └── example └── accessing_wydot.ipynb /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | notebooks/.ipynb_checkpoints/Check Folders in sandbox-checkpoint.ipynb 3 | notebooks/Check Folders in sandbox.ipynb 4 | -------------------------------------------------------------------------------- /sample/wydot-filtered-bsm-1512496037271.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "logFileName": "bsmTx_1512491800_fe80::226:adff:fe05:14c1.csv", 4 | "odeReceivedAt": "2017-12-05T17:45:13.736Z[UTC]", 5 | "payloadType": "us.dot.its.jpo.ode.model.OdeBsmPayload", 6 | "recordGeneratedAt": "2017-12-05T16:33:58Z[UTC]", 7 | "recordGeneratedBy": "OBU", 8 | "recordType": "bsmTx", 9 | "sanitized": true, 10 | "schemaVersion": 3, 11 | "serialId": { 12 | "bundleId": 8457, 13 | "bundleSize": 1, 14 | "recordId": 2, 15 | "serialNumber": 0, 16 | "streamId": "9d372bb3-4d23-4877-a760-076cc6018e4f" 17 | }, 18 | "validSignature": true 19 | }, 20 | "payload": { 21 | "data": { 22 | "coreData": { 23 | "accelSet": { 24 | "accelYaw": 0.00 25 | }, 26 | "accuracy": { 27 | "semiMajor": 2.05, 28 | "semiMinor": 3.20 29 | }, 30 | "brakes": { 31 | "abs": "unavailable", 32 | "auxBrakes": "unavailable", 33 | "brakeBoost": "unavailable", 34 | "scs": "unavailable", 35 | "traction": "unavailable", 36 | "wheelBrakes": { 37 | "leftFront": false, 38 | "leftRear": false, 39 | "rightFront": false, 40 | "rightRear": false, 41 | "unavailable": true 42 | } 43 | }, 44 | "heading": 258.6000, 45 | "id": "5B820000", 46 | "msgCnt": 38, 47 | "position": { 48 | "elevation": 2222.0, 49 | "latitude": 41.0997729, 50 | "longitude": -105.1547481 51 | }, 52 | "secMark": 58000, 53 | "size": { 54 | "length": 1190, 55 | "width": 490 56 | }, 57 | "speed": 27.98, 58 | "transmission": "NEUTRAL" 59 | }, 60 | "partII": [ 61 | { 62 | "id": "VehicleSafetyExtensions", 63 | "value": { 64 | "pathHistory": { 65 | "crumbData": [ 66 | { 67 | "elevationOffset": 0.0, 68 | "latOffset": -0.0000192, 69 | "lonOffset": -0.0001306, 70 | "timeOffset": 0.40 71 | }, 72 | { 73 | "elevationOffset": 0.0, 74 | "latOffset": -0.0001563, 75 | "lonOffset": -0.0013271, 76 | "timeOffset": 4.10 77 | }, 78 | { 79 | "elevationOffset": 1.0, 80 | "latOffset": -0.0002405, 81 | "lonOffset": -0.0025387, 82 | "timeOffset": 7.90 83 | } 84 | ] 85 | }, 86 | "pathPrediction": { 87 | "confidence": 70.0, 88 | "radiusOfCurve": -25.4 89 | } 90 | } 91 | }, 92 | { 93 | "id": "SupplementalVehicleExtensions", 94 | "value": { 95 | "classDetails": { 96 | "fuelType": "unknownFuel", 97 | "hpmsType": "none", 98 | "keyType": 0, 99 | "regional": [], 100 | "role": "basicVehicle" 101 | }, 102 | "regional": [], 103 | "vehicleData": { 104 | "height": 3.70 105 | }, 106 | "weatherProbe": {} 107 | } 108 | } 109 | ] 110 | }, 111 | "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735Bsm" 112 | } 113 | } -------------------------------------------------------------------------------- /sample/wydot-filtered-tim-1512415831724.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "logFileName": "rxMsg_1512398557_fe80::226:adff:fe05:14c1.csv", 4 | "odeReceivedAt": "2017-12-04T19:30:05.978Z[UTC]", 5 | "payloadType": "us.dot.its.jpo.ode.model.OdeTimPayload", 6 | "receivedMessageDetails": { 7 | "locationData": { 8 | "elevation": 0, 9 | "heading": 92.1, 10 | "latitude": 41.0986645, 11 | "longitude": -105.1227162, 12 | "speed": 30.2 13 | }, 14 | "rxSource": "RSU" 15 | }, 16 | "recordGeneratedAt": "2017-12-01T13:26:24.497Z[UTC]", 17 | "recordGeneratedBy": "OBU", 18 | "recordType": "rxMsg", 19 | "sanitized": false, 20 | "schemaVersion": 3, 21 | "serialId": { 22 | "bundleId": 13, 23 | "bundleSize": 1, 24 | "recordId": 2, 25 | "serialNumber": 0, 26 | "streamId": "010df2f5-b5b7-4d89-98f9-e46227fb94db" 27 | }, 28 | "validSignature": false 29 | }, 30 | "payload": { 31 | "data": { 32 | "MessageFrame": { 33 | "messageId": 31, 34 | "value": { 35 | "TravelerInformation": { 36 | "dataFrames": { 37 | "TravelerDataFrame": { 38 | "content": { 39 | "exitService": { 40 | "SEQUENCE": { 41 | "item": { 42 | "itis": 7991 43 | } 44 | } 45 | } 46 | }, 47 | "duratonTime": 24520, 48 | "frameType": { 49 | "commercialSignage": "" 50 | }, 51 | "msgId": { 52 | "furtherInfoID": "0000" 53 | }, 54 | "priority": 2, 55 | "regions": { 56 | "GeographicalPath": { 57 | "description": { 58 | "oldRegion": { 59 | "area": { 60 | "regionPointSet": { 61 | "anchor": { 62 | "elevation": 2670, 63 | "lat": 424918451, 64 | "long": -834196504 65 | }, 66 | "nodeList": { 67 | "RegionOffsets": [ 68 | { 69 | "xOffset": -186, 70 | "yOffset": 48 71 | }, 72 | { 73 | "xOffset": 158, 74 | "yOffset": -118 75 | }, 76 | { 77 | "xOffset": 138, 78 | "yOffset": 40 79 | }, 80 | { 81 | "xOffset": 89, 82 | "yOffset": 117 83 | }, 84 | { 85 | "xOffset": -3, 86 | "yOffset": 156 87 | }, 88 | { 89 | "xOffset": -458, 90 | "yOffset": -29 91 | }, 92 | { 93 | "xOffset": 0, 94 | "yOffset": 0 95 | }, 96 | { 97 | "xOffset": 76, 98 | "yOffset": -166 99 | } 100 | ] 101 | } 102 | } 103 | }, 104 | "direction": "0000000000000000" 105 | } 106 | }, 107 | "id": { 108 | "id": 0 109 | } 110 | } 111 | }, 112 | "sspLocationRights": 0, 113 | "sspMsgRights1": 0, 114 | "sspMsgRights2": 0, 115 | "sspTimRights": 0, 116 | "startTime": 487705, 117 | "startYear": 2016 118 | } 119 | }, 120 | "msgCnt": 1, 121 | "packetID": "000000000039F63AA6" 122 | } 123 | } 124 | } 125 | }, 126 | "dataType": "TravelerInformation" 127 | } 128 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Accessing CV Pilots Data From a Public Amazon S3 Bucket 2 | 3 | 4 | **Table of Contents** 5 | 6 | * [Background](#backgound) 7 | * [Related ITS JPO Projects](#related-its-jpo-projects) 8 | * [Getting Started](#getting-started) 9 | * [Prerequisites for using AWS CLI](#prerequisites-for-using-aws-cli) 10 | * [Accessing Files through AWS CLI](#accessing-files-through-aws-cli) 11 | * [Directory Structure](#directory-structure) 12 | * [Downloading from S3](#downloading-from-s3) 13 | * [Data Types](#data-types) 14 | * [Wyoming CV Data](#wyoming-cv-data) 15 | * [Get Involved](#get-involved) 16 | 17 | ## Background 18 | This repository contains information on accessing complete data sets from the United States Department of Transportation (USDOT) Joint Program Office (JPO) data program. It is meant to propose a data folder hierarchy to structure the processed data ingested from the Connected Vehicles (CV) Pilot programs and other streaming data sources. Currently this is a beta system using a folder hierarchy for processed Basic Safety Messages (BSM) and Traveler Information Messages (TIM) from the Wyoming CV Pilot site. 19 | 20 | USDOT JPO is soliciting user feedback on the current folder hierarchy to determine what the best approach is and to help inform future directory hierarchies for other data types. To provide input on the hierarchy or the data please [Open an Issue](https://github.com/usdot-its-jpo-data-portal/sandbox/issues). 21 | 22 | The AWS S3 bucket provides an alternative that is similar to traversing a directory structure. The intention of the hierarchy is to: 23 | 24 | - Provide a consistent structure within a pilot program 25 | - Be easily understood by a human traversing the directories 26 | - Be structured sufficiently so third parties can build software applications using the data 27 | - Be flexible enough to capture different data types. 28 | 29 | The expectation is that different data types will lend themselves to different directory hierarchies. In addition, the pilot sites may have compelling reasons to organize the data in different hierarchies for the same data type. The below hierarchy is intended for processed BSMs from the Wyoming CV Pilot site. 30 | 31 | Additional information about CV data is available at: 32 | 33 | - [ITS JPO Connected Vehicles (CV) Pilot Deployment Program](https://www.its.dot.gov/pilots/cv_pilot_plan.htm)- The pilot deployments are expected to integrate connected vehicle research concepts into practical and effective elements, enhancing existing operational capabilities. 34 | - [J2735 Standard](http://standards.sae.org/j2735_201603/) - Standard for CV data 35 | - [General CV information: Vehicle Based Data and Availability](https://www.its.dot.gov/itspac/october2012/PDF/data_availability.pdf) - General introduction slides on CV data 36 | - [Sample of the WYDOT BSM data](https://data.transportation.gov/Automobiles/Wyoming-CV-Pilot-Basic-Safety-Message-One-Day-Samp/9k4m-a3jc) - Sample of WYDOT BSM data 37 | 38 | ### Related ITS JPO Projects 39 | 40 | - [Operational Data Environment (ODE)](https://github.com/usdot-jpo-ode/jpo-ode) - This ITS JPO Open Source tool is used to collect and process Connected Vehicle data in near real time, and route it to other data repositories, including the Amazon S3 bucket. 41 | - [Privacy Module](https://github.com/usdot-jpo-ode/jpo-cvdp) - This ITS JPO Open source module is used to sanitize the data to ensure no personal information is shared with the public. 42 | - [Connected Vehicles Performance Evaluation Platform (CVPEP)](https://github.com/VolpeUSDOT/CV-PEP) - Limited access Platform for storing raw CV data for evaluation. 43 | - [ITS JPO Data Site ](https://www.its.dot.gov/data/) - ITS JPO data site which allows users to search for various ITS data. 44 | 45 | 46 | ## Getting Started 47 | 48 | There are two ways to access the full data sets on Amazon s3. The first way is through the [Web Interface](http://usdot-its-cvpilot-public-data.s3.amazonaws.com/index.html). This allows the user to browse through the folder structure and click and download individual BSMs. Alternatively, the data can be downloaded programmatically using the Amazon Command Line Interface (CLI) by following the directions below. 49 | 50 | ### Prerequisites for using AWS CLI 51 | 52 | 1) Have your own Free Amazon Web Services account. 53 | 54 | - Create one at http://aws.amazon.com 55 | 56 | 2) Obtain Access Keys: 57 | 58 | - On your Amazon account, go to your profile (at the top right) 59 | 60 | - My Security Credentials > Access Keys > Create New Access Key 61 | 62 | - Record the Access Key ID and Secret Access Key ID (you will need them in step 4) 63 | 64 | 3) Have Amazon Web Services Command Line Interface (AWS CLI) installed on your computer. 65 | 66 | - Installation options can be found at http://aws.amazon.com/cli 67 | 68 | - To run AWS CLI on Windows, navigate to C:\Program Files\Amazon\ and run "aws 69 | --version" to confirm that the program is installed. This should return the version number of aws that you are running. 70 | 71 | 4) Run the following command through AWS CLI: 72 | ``` 73 | aws configure 74 | ``` 75 | and enter the following: 76 | 77 | * Access Key (from step 2) 78 | * Secret Access Key (from step 2) 79 | * Default region name (us-east-1) 80 | * Default output format (ex: json) 81 | 82 | ### Accessing files through AWS CLI 83 | 84 | Now go to your command window. The title of the s3 bucket is: 85 | 86 | * RDE (public access): usdot-its-cvpilot-public-data 87 | 88 | Run the following to check access: 89 | ``` 90 | aws s3 ls s3://{bucket name}/ --recursive --human-readable --summarize --profile {profile_name} 91 | ``` 92 | 93 | For Example: 94 | ``` 95 | aws s3 ls s3://usdot-its-cvpilot-public-data/ --recursive --human-readable --summarize --profile default 96 | ``` 97 | 98 | ### Directory Structure 99 | 100 | The directory structure within the buckets will take the following form: 101 | 102 | {Source_Name}/{Data_Type}/{Year}/{Month}/{Day}/{Hour} 103 | 104 | So for example, accessing Wyoming CV Pilots BSM data for a specific time will look like: 105 | 106 | 107 | wydot/BSM/2017/08/15/23/wydot-filtered-bsm-1501782546127.json 108 | 109 | Where in this example the actual BSM file is titled 'wydot-filtered-bsm-1501782546127.json'. Data prior to January 18, 2018 is one message per file, from that date onwards files will contain multiple messages. 110 | 111 | ### Downloading from S3 112 | 113 | To download all data from the S3 Bucket, enter the following command: 114 | 115 | ``` 116 | aws s3 cp s3://{bucketname}/{local_directory} --recursive 117 | ``` 118 | 119 | For example, to download all BSM data from 2017: 120 | ``` 121 | aws s3 cp s3://usdot-its-cvpilot-public-data/wydot/BSM/2017/ --recursive 122 | ``` 123 | 124 | To limit the data being dowloaded you can use AWS CLI's filtering which is detailed here: http://docs.aws.amazon.com/cli/latest/reference/s3/#use-of-exclude-and-include-filters. 125 | 126 | ## Data Types 127 | 128 | 129 | 130 | ### Wyoming CV Data 131 | 132 | - [Details on Wyoming CV DATA BSMs and TIMs messages and samples](https://github.com/usdot-jpo-ode/jpo-ode/blob/develop/docs/metadata_standards.md) 133 | 134 | #### WYDOT BSM 135 | 136 | - [Single file Sample](https://github.com/usdot-its-jpo-data-portal/sandbox/blob/master/sample/wydot-filtered-bsm-1512496037271.json) 137 | - [Data Set Sample of the WYDOT BSM data](https://data.transportation.gov/Automobiles/Wyoming-CV-Pilot-Basic-Safety-Message-One-Day-Samp/9k4m-a3jc) 138 | 139 | #### WYDOT TIM 140 | 141 | - [Single file Sample](https://github.com/usdot-its-jpo-data-portal/sandbox/blob/master/sample/wydot-filtered-tim-1512415831724.json) 142 | 143 | ## Get Involved 144 | ------------ 145 | 146 | We welcome your feedback and ideas. Here's how to reach us: 147 | 148 | - [Open an Issue](https://github.com/usdot-its-jpo-data-portal/sandbox/issues) 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /example/accessing_wydot.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "### The goal of this notebook is to provide a basic example of how to access the USDOT Intelligent Transportation System (ITS) Joint Program Office (JPO) Wyoming Connected Vehcile Pilot data through the Data Program Sandbox.\n", 10 | "\n", 11 | "Objective of the notebook\n", 12 | "- Show how to access WY CV pilot data on the sandbox\n", 13 | "- Conduct basic analysis with the data\n", 14 | "\n", 15 | "----" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "### Load key libraries for the work \n", 23 | "**You will need to install these libraries before running this notebook**\n", 24 | "- boto3: AWS python library (http://boto3.readthedocs.io/en/latest/)\n", 25 | "- pandas: Python Data Analysis Library (http://pandas.pydata.org)" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "import boto3\n", 35 | "import pandas as pd" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "### Create session and client variable for accessing S3" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 2, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "session = boto3.Session()\n", 52 | "client = session.client('s3')" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "### List subfolders to determine which hours data was received on Nov 20" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 16, 65 | "metadata": {}, 66 | "outputs": [ 67 | { 68 | "name": "stdout", 69 | "output_type": "stream", 70 | "text": [ 71 | "2\n", 72 | "subfolder : wydot/BSM/2017/11/20/12/\n", 73 | "subfolder : wydot/BSM/2017/11/20/13/\n" 74 | ] 75 | } 76 | ], 77 | "source": [ 78 | "result = client.list_objects(Bucket = 'usdot-its-cvpilot-public-data', Delimiter='/', Prefix='wydot/BSM/2017/11/20/')\n", 79 | "\n", 80 | "print(len(result.get('CommonPrefixes')))\n", 81 | "\n", 82 | "if result.get('CommonPrefixes') is not None:\n", 83 | " for o in result.get('CommonPrefixes'):\n", 84 | " print ('subfolder : ', o.get('Prefix'))\n", 85 | "else:\n", 86 | " print('No folder found for that prefix')" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "### Function for pulling file keys from the AWS S3 bucket" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 15, 99 | "metadata": {}, 100 | "outputs": [], 101 | "source": [ 102 | "def dir_keys(client, bucket, prefix='', filekeys=[]):\n", 103 | " \"\"\"\n", 104 | " Lists all file keys from a given prefix in an S3 bucket. If no prefix is given all file keys are returned\n", 105 | "\n", 106 | " :param client: S3 connection object\n", 107 | " :param bucket: Name of bucket to search\n", 108 | " :param prefix: Prefix for a given folder\n", 109 | " :param filekeys: list for filekeys\n", 110 | " :return: updated filekey list with added files from search\n", 111 | " \"\"\"\n", 112 | " paginator = client.get_paginator('list_objects_v2')\n", 113 | " for result in paginator.paginate(Bucket=bucket, Delimiter='/', Prefix=prefix):\n", 114 | " if result.get('Contents') is not None:\n", 115 | " for file in result.get('Contents'):\n", 116 | " if file.get('Key') != 'unknownDataType':\n", 117 | " filekeys.append(file.get('Key'))\n", 118 | " if result.get('CommonPrefixes') is not None:\n", 119 | " for subdir in result.get('CommonPrefixes'):\n", 120 | " dir_keys(client, bucket, subdir.get('Prefix'), filekeys)\n", 121 | " return filekeys\n" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "### Pull all file keys for Nov 20 and determine the number of files" 129 | ] 130 | }, 131 | { 132 | "cell_type": "code", 133 | "execution_count": 17, 134 | "metadata": {}, 135 | "outputs": [ 136 | { 137 | "name": "stdout", 138 | "output_type": "stream", 139 | "text": [ 140 | "Total number of files: 94\n" 141 | ] 142 | } 143 | ], 144 | "source": [ 145 | "filekeys = dir_keys(client, 'usdot-its-cvpilot-public-data', 'wydot/BSM/2017/11/20/')\n", 146 | "print('Total number of files:', str(len(filekeys)))" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "metadata": {}, 152 | "source": [ 153 | "### Create local directory and download files to do analysis on" 154 | ] 155 | }, 156 | { 157 | "cell_type": "code", 158 | "execution_count": 18, 159 | "metadata": {}, 160 | "outputs": [ 161 | { 162 | "name": "stdout", 163 | "output_type": "stream", 164 | "text": [ 165 | "94 Files loaded to /tmp/\n" 166 | ] 167 | } 168 | ], 169 | "source": [ 170 | "# Create local directory\n", 171 | "import os\n", 172 | "cwd = os.getcwd()\n", 173 | "local_directory = cwd + os.sep + 'tmp' + os.sep\n", 174 | "if not os.path.exists(local_directory):\n", 175 | " os.makedirs(local_directory)\n", 176 | "\n", 177 | "# Download Files\n", 178 | "for file in filekeys:\n", 179 | " client.download_file('usdot-its-cvpilot-public-data', file, local_directory + file.split('/')[-1])\n", 180 | "print('{} Files loaded to {}'.format(str(len(os.listdir(local_directory))), '/tmp/'))" 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": {}, 186 | "source": [ 187 | "### Look at one of the raw JSON files" 188 | ] 189 | }, 190 | { 191 | "cell_type": "code", 192 | "execution_count": 22, 193 | "metadata": {}, 194 | "outputs": [ 195 | { 196 | "name": "stdout", 197 | "output_type": "stream", 198 | "text": [ 199 | "{\"metadata\":{\"logFileName\":\"bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv\",\"recordType\":\"bsmTx\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeBsmPayload\",\"serialId\":{\"streamId\":\"5df4d384-dae1-4dcc-b662-95cd7e7bde5f\",\"bundleSize\":1,\"bundleId\":4096,\"recordId\":2,\"serialNumber\":0},\"odeReceivedAt\":\"2017-11-27T12:50:16.377Z[UTC]\",\"schemaVersion\":3,\"recordGeneratedAt\":\"2017-11-20T12:13:36.398Z[UTC]\",\"recordGeneratedBy\":\"OBU\",\"validSignature\":true,\"sanitized\":true},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735Bsm\",\"data\":{\"coreData\":{\"msgCnt\":66,\"id\":\"3DEF0000\",\"secMark\":36400,\"position\":{\"latitude\":41.1135612,\"longitude\":-104.8557380,\"elevation\":1856.8},\"accelSet\":{\"accelYaw\":0.00},\"accuracy\":{\"semiMajor\":1.90,\"semiMinor\":2.90},\"transmission\":\"NEUTRAL\",\"speed\":19.44,\"heading\":259.7250,\"brakes\":{\"wheelBrakes\":{\"leftFront\":false,\"rightFront\":false,\"unavailable\":true,\"leftRear\":false,\"rightRear\":false},\"traction\":\"unavailable\",\"abs\":\"unavailable\",\"scs\":\"unavailable\",\"brakeBoost\":\"unavailable\",\"auxBrakes\":\"unavailable\"},\"size\":{\"width\":490,\"length\":1190}},\"partII\":[{\"id\":\"VehicleSafetyExtensions\",\"value\":{\"pathHistory\":{\"crumbData\":[{\"elevationOffset\":1.2,\"latOffset\":-0.0000820,\"lonOffset\":-0.0004320,\"timeOffset\":1.89},{\"elevationOffset\":2.4,\"latOffset\":-0.0002066,\"lonOffset\":-0.0008232,\"timeOffset\":3.70},{\"elevationOffset\":3.4,\"latOffset\":-0.0003961,\"lonOffset\":-0.0012306,\"timeOffset\":5.70},{\"elevationOffset\":4.1,\"latOffset\":-0.0008211,\"lonOffset\":-0.0019247,\"timeOffset\":9.39}]},\"pathPrediction\":{\"confidence\":30.0,\"radiusOfCurve\":2.7}}},{\"id\":\"SupplementalVehicleExtensions\",\"value\":{\"classDetails\":{\"fuelType\":\"unknownFuel\",\"hpmsType\":\"none\",\"keyType\":0,\"regional\":[],\"role\":\"basicVehicle\"},\"vehicleData\":{\"height\":3.70},\"weatherProbe\":{},\"regional\":[]}}]}}}\n" 200 | ] 201 | } 202 | ], 203 | "source": [ 204 | "with open(\"./tmp/wydot-filtered-bsm-1511788035889.json\") as in_f:\n", 205 | " for line in in_f:\n", 206 | " print(line)" 207 | ] 208 | }, 209 | { 210 | "cell_type": "markdown", 211 | "metadata": {}, 212 | "source": [ 213 | "### Reformat it to make it easier to view" 214 | ] 215 | }, 216 | { 217 | "cell_type": "code", 218 | "execution_count": 23, 219 | "metadata": {}, 220 | "outputs": [ 221 | { 222 | "name": "stdout", 223 | "output_type": "stream", 224 | "text": [ 225 | "{'metadata': {'logFileName': 'bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv',\n", 226 | " 'odeReceivedAt': '2017-11-27T12:50:16.377Z[UTC]',\n", 227 | " 'payloadType': 'us.dot.its.jpo.ode.model.OdeBsmPayload',\n", 228 | " 'recordGeneratedAt': '2017-11-20T12:13:36.398Z[UTC]',\n", 229 | " 'recordGeneratedBy': 'OBU',\n", 230 | " 'recordType': 'bsmTx',\n", 231 | " 'sanitized': True,\n", 232 | " 'schemaVersion': 3,\n", 233 | " 'serialId': {'bundleId': 4096,\n", 234 | " 'bundleSize': 1,\n", 235 | " 'recordId': 2,\n", 236 | " 'serialNumber': 0,\n", 237 | " 'streamId': '5df4d384-dae1-4dcc-b662-95cd7e7bde5f'},\n", 238 | " 'validSignature': True},\n", 239 | " 'payload': {'data': {'coreData': {'accelSet': {'accelYaw': 0.0},\n", 240 | " 'accuracy': {'semiMajor': 1.9,\n", 241 | " 'semiMinor': 2.9},\n", 242 | " 'brakes': {'abs': 'unavailable',\n", 243 | " 'auxBrakes': 'unavailable',\n", 244 | " 'brakeBoost': 'unavailable',\n", 245 | " 'scs': 'unavailable',\n", 246 | " 'traction': 'unavailable',\n", 247 | " 'wheelBrakes': {'leftFront': False,\n", 248 | " 'leftRear': False,\n", 249 | " 'rightFront': False,\n", 250 | " 'rightRear': False,\n", 251 | " 'unavailable': True}},\n", 252 | " 'heading': 259.725,\n", 253 | " 'id': '3DEF0000',\n", 254 | " 'msgCnt': 66,\n", 255 | " 'position': {'elevation': 1856.8,\n", 256 | " 'latitude': 41.1135612,\n", 257 | " 'longitude': -104.855738},\n", 258 | " 'secMark': 36400,\n", 259 | " 'size': {'length': 1190, 'width': 490},\n", 260 | " 'speed': 19.44,\n", 261 | " 'transmission': 'NEUTRAL'},\n", 262 | " 'partII': [{'id': 'VehicleSafetyExtensions',\n", 263 | " 'value': {'pathHistory': {'crumbData': [{'elevationOffset': 1.2,\n", 264 | " 'latOffset': -8.2e-05,\n", 265 | " 'lonOffset': -0.000432,\n", 266 | " 'timeOffset': 1.89},\n", 267 | " {'elevationOffset': 2.4,\n", 268 | " 'latOffset': -0.0002066,\n", 269 | " 'lonOffset': -0.0008232,\n", 270 | " 'timeOffset': 3.7},\n", 271 | " {'elevationOffset': 3.4,\n", 272 | " 'latOffset': -0.0003961,\n", 273 | " 'lonOffset': -0.0012306,\n", 274 | " 'timeOffset': 5.7},\n", 275 | " {'elevationOffset': 4.1,\n", 276 | " 'latOffset': -0.0008211,\n", 277 | " 'lonOffset': -0.0019247,\n", 278 | " 'timeOffset': 9.39}]},\n", 279 | " 'pathPrediction': {'confidence': 30.0,\n", 280 | " 'radiusOfCurve': 2.7}}},\n", 281 | " {'id': 'SupplementalVehicleExtensions',\n", 282 | " 'value': {'classDetails': {'fuelType': 'unknownFuel',\n", 283 | " 'hpmsType': 'none',\n", 284 | " 'keyType': 0,\n", 285 | " 'regional': [],\n", 286 | " 'role': 'basicVehicle'},\n", 287 | " 'regional': [],\n", 288 | " 'vehicleData': {'height': 3.7},\n", 289 | " 'weatherProbe': {}}}]},\n", 290 | " 'dataType': 'us.dot.its.jpo.ode.plugin.j2735.J2735Bsm'}}\n" 291 | ] 292 | } 293 | ], 294 | "source": [ 295 | "import pprint\n", 296 | "import json\n", 297 | "data = json.loads(open(\"./tmp/wydot-filtered-bsm-1511788035889.json\").read())\n", 298 | "pprint.pprint(data)" 299 | ] 300 | }, 301 | { 302 | "cell_type": "markdown", 303 | "metadata": {}, 304 | "source": [ 305 | "### Combine the JSON files into a single JSON file" 306 | ] 307 | }, 308 | { 309 | "cell_type": "code", 310 | "execution_count": 24, 311 | "metadata": {}, 312 | "outputs": [], 313 | "source": [ 314 | "import glob\n", 315 | "\n", 316 | "read_files = glob.glob(local_directory + \"*.json\")\n", 317 | "with open(local_directory + \"merged_file.json\", \"w\") as outfile:\n", 318 | " data = []\n", 319 | " for f in read_files:\n", 320 | " data.append(open(f, \"r\").read())\n", 321 | " outfile.write(\"[\" + ','.join(data[1:]) + \"]\")" 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": {}, 327 | "source": [ 328 | "### Load file into data structure\n", 329 | "*Data is in J2735 format http://standards.sae.org/j2735_201603/*" 330 | ] 331 | }, 332 | { 333 | "cell_type": "code", 334 | "execution_count": 27, 335 | "metadata": {}, 336 | "outputs": [ 337 | { 338 | "data": { 339 | "text/html": [ 340 | "
\n", 341 | "\n", 354 | "\n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | "
metadata.logFileNamemetadata.odeReceivedAtmetadata.payloadTypemetadata.recordGeneratedAtmetadata.recordGeneratedBymetadata.recordTypemetadata.sanitizedmetadata.schemaVersionmetadata.serialId.bundleIdmetadata.serialId.bundleSize...payload.data.coreData.position.elevationpayload.data.coreData.position.latitudepayload.data.coreData.position.longitudepayload.data.coreData.secMarkpayload.data.coreData.size.lengthpayload.data.coreData.size.widthpayload.data.coreData.speedpayload.data.coreData.transmissionpayload.data.partIIpayload.dataType
0bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv2017-11-27T12:50:16.377Z[UTC]us.dot.its.jpo.ode.model.OdeBsmPayload2017-11-20T12:14:06.393Z[UTC]OBUbsmTxTrue340961...1865.741.115620-104.8623686400119049022.68NEUTRAL[{'id': 'VehicleSafetyExtensions', 'value': {'...us.dot.its.jpo.ode.plugin.j2735.J2735Bsm
1bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv2017-11-27T12:50:16.377Z[UTC]us.dot.its.jpo.ode.model.OdeBsmPayload2017-11-20T12:14:35.797Z[UTC]OBUbsmTxTrue340961...1872.041.117003-104.87062835800119049024.86NEUTRAL[{'id': 'VehicleSafetyExtensions', 'value': {'...us.dot.its.jpo.ode.plugin.j2735.J2735Bsm
2bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv2017-11-27T12:50:16.377Z[UTC]us.dot.its.jpo.ode.model.OdeBsmPayload2017-11-20T12:15:03.496Z[UTC]OBUbsmTxTrue340961...1885.641.116972-104.8786693500119049023.62NEUTRAL[{'id': 'VehicleSafetyExtensions', 'value': {'...us.dot.its.jpo.ode.plugin.j2735.J2735Bsm
3bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv2017-11-27T12:50:16.377Z[UTC]us.dot.its.jpo.ode.model.OdeBsmPayload2017-11-20T12:15:36.395Z[UTC]OBUbsmTxTrue340961...1900.841.116942-104.88776636400119049024.30NEUTRAL[{'id': 'VehicleSafetyExtensions', 'value': {'...us.dot.its.jpo.ode.plugin.j2735.J2735Bsm
4bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv2017-11-27T12:50:16.377Z[UTC]us.dot.its.jpo.ode.model.OdeBsmPayload2017-11-20T12:16:06.394Z[UTC]OBUbsmTxTrue340961...1903.941.116909-104.8969646400119049027.38NEUTRAL[{'id': 'VehicleSafetyExtensions', 'value': {'...us.dot.its.jpo.ode.plugin.j2735.J2735Bsm
\n", 504 | "

5 rows × 41 columns

\n", 505 | "
" 506 | ], 507 | "text/plain": [ 508 | " metadata.logFileName \\\n", 509 | "0 bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv \n", 510 | "1 bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv \n", 511 | "2 bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv \n", 512 | "3 bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv \n", 513 | "4 bsmTx_1511786692_fe80::226:adff:fe05:14c1.csv \n", 514 | "\n", 515 | " metadata.odeReceivedAt metadata.payloadType \\\n", 516 | "0 2017-11-27T12:50:16.377Z[UTC] us.dot.its.jpo.ode.model.OdeBsmPayload \n", 517 | "1 2017-11-27T12:50:16.377Z[UTC] us.dot.its.jpo.ode.model.OdeBsmPayload \n", 518 | "2 2017-11-27T12:50:16.377Z[UTC] us.dot.its.jpo.ode.model.OdeBsmPayload \n", 519 | "3 2017-11-27T12:50:16.377Z[UTC] us.dot.its.jpo.ode.model.OdeBsmPayload \n", 520 | "4 2017-11-27T12:50:16.377Z[UTC] us.dot.its.jpo.ode.model.OdeBsmPayload \n", 521 | "\n", 522 | " metadata.recordGeneratedAt metadata.recordGeneratedBy \\\n", 523 | "0 2017-11-20T12:14:06.393Z[UTC] OBU \n", 524 | "1 2017-11-20T12:14:35.797Z[UTC] OBU \n", 525 | "2 2017-11-20T12:15:03.496Z[UTC] OBU \n", 526 | "3 2017-11-20T12:15:36.395Z[UTC] OBU \n", 527 | "4 2017-11-20T12:16:06.394Z[UTC] OBU \n", 528 | "\n", 529 | " metadata.recordType metadata.sanitized metadata.schemaVersion \\\n", 530 | "0 bsmTx True 3 \n", 531 | "1 bsmTx True 3 \n", 532 | "2 bsmTx True 3 \n", 533 | "3 bsmTx True 3 \n", 534 | "4 bsmTx True 3 \n", 535 | "\n", 536 | " metadata.serialId.bundleId metadata.serialId.bundleSize \\\n", 537 | "0 4096 1 \n", 538 | "1 4096 1 \n", 539 | "2 4096 1 \n", 540 | "3 4096 1 \n", 541 | "4 4096 1 \n", 542 | "\n", 543 | " ... \\\n", 544 | "0 ... \n", 545 | "1 ... \n", 546 | "2 ... \n", 547 | "3 ... \n", 548 | "4 ... \n", 549 | "\n", 550 | " payload.data.coreData.position.elevation \\\n", 551 | "0 1865.7 \n", 552 | "1 1872.0 \n", 553 | "2 1885.6 \n", 554 | "3 1900.8 \n", 555 | "4 1903.9 \n", 556 | "\n", 557 | " payload.data.coreData.position.latitude \\\n", 558 | "0 41.115620 \n", 559 | "1 41.117003 \n", 560 | "2 41.116972 \n", 561 | "3 41.116942 \n", 562 | "4 41.116909 \n", 563 | "\n", 564 | " payload.data.coreData.position.longitude payload.data.coreData.secMark \\\n", 565 | "0 -104.862368 6400 \n", 566 | "1 -104.870628 35800 \n", 567 | "2 -104.878669 3500 \n", 568 | "3 -104.887766 36400 \n", 569 | "4 -104.896964 6400 \n", 570 | "\n", 571 | " payload.data.coreData.size.length payload.data.coreData.size.width \\\n", 572 | "0 1190 490 \n", 573 | "1 1190 490 \n", 574 | "2 1190 490 \n", 575 | "3 1190 490 \n", 576 | "4 1190 490 \n", 577 | "\n", 578 | " payload.data.coreData.speed payload.data.coreData.transmission \\\n", 579 | "0 22.68 NEUTRAL \n", 580 | "1 24.86 NEUTRAL \n", 581 | "2 23.62 NEUTRAL \n", 582 | "3 24.30 NEUTRAL \n", 583 | "4 27.38 NEUTRAL \n", 584 | "\n", 585 | " payload.data.partII \\\n", 586 | "0 [{'id': 'VehicleSafetyExtensions', 'value': {'... \n", 587 | "1 [{'id': 'VehicleSafetyExtensions', 'value': {'... \n", 588 | "2 [{'id': 'VehicleSafetyExtensions', 'value': {'... \n", 589 | "3 [{'id': 'VehicleSafetyExtensions', 'value': {'... \n", 590 | "4 [{'id': 'VehicleSafetyExtensions', 'value': {'... \n", 591 | "\n", 592 | " payload.dataType \n", 593 | "0 us.dot.its.jpo.ode.plugin.j2735.J2735Bsm \n", 594 | "1 us.dot.its.jpo.ode.plugin.j2735.J2735Bsm \n", 595 | "2 us.dot.its.jpo.ode.plugin.j2735.J2735Bsm \n", 596 | "3 us.dot.its.jpo.ode.plugin.j2735.J2735Bsm \n", 597 | "4 us.dot.its.jpo.ode.plugin.j2735.J2735Bsm \n", 598 | "\n", 599 | "[5 rows x 41 columns]" 600 | ] 601 | }, 602 | "execution_count": 27, 603 | "metadata": {}, 604 | "output_type": "execute_result" 605 | } 606 | ], 607 | "source": [ 608 | "from pandas.io.json import json_normalize\n", 609 | "\n", 610 | "file_json = json.load(open(local_directory + \"merged_file.json\",\"r\"))\n", 611 | "\n", 612 | "result = json_normalize(data=file_json, meta=['metadata', ['payload', 'data']])\n", 613 | "result.head()" 614 | ] 615 | }, 616 | { 617 | "cell_type": "markdown", 618 | "metadata": {}, 619 | "source": [ 620 | "### Do some basic analysis on the speed" 621 | ] 622 | }, 623 | { 624 | "cell_type": "code", 625 | "execution_count": 28, 626 | "metadata": {}, 627 | "outputs": [ 628 | { 629 | "data": { 630 | "text/plain": [ 631 | "count 93.000000\n", 632 | "mean 25.503656\n", 633 | "std 4.656846\n", 634 | "min 5.620000\n", 635 | "25% 22.380000\n", 636 | "50% 27.020000\n", 637 | "75% 28.600000\n", 638 | "max 33.380000\n", 639 | "Name: payload.data.coreData.speed, dtype: float64" 640 | ] 641 | }, 642 | "execution_count": 28, 643 | "metadata": {}, 644 | "output_type": "execute_result" 645 | } 646 | ], 647 | "source": [ 648 | "result['payload.data.coreData.speed'].describe()" 649 | ] 650 | }, 651 | { 652 | "cell_type": "markdown", 653 | "metadata": {}, 654 | "source": [ 655 | "### Convert time by removing UTC and setting to time value" 656 | ] 657 | }, 658 | { 659 | "cell_type": "code", 660 | "execution_count": 31, 661 | "metadata": {}, 662 | "outputs": [ 663 | { 664 | "data": { 665 | "text/plain": [ 666 | "0 2017-11-20 12:14:06.393\n", 667 | "1 2017-11-20 12:14:35.797\n", 668 | "2 2017-11-20 12:15:03.496\n", 669 | "3 2017-11-20 12:15:36.395\n", 670 | "4 2017-11-20 12:16:06.394\n", 671 | "5 2017-11-20 12:16:36.399\n", 672 | "6 2017-11-20 12:17:06.392\n", 673 | "7 2017-11-20 12:17:36.391\n", 674 | "8 2017-11-20 12:18:06.386\n", 675 | "9 2017-11-20 12:18:36.388\n", 676 | "10 2017-11-20 12:19:03.225\n", 677 | "11 2017-11-20 12:19:36.389\n", 678 | "12 2017-11-20 12:20:06.395\n", 679 | "13 2017-11-20 12:20:36.386\n", 680 | "14 2017-11-20 12:21:06.424\n", 681 | "15 2017-11-20 12:21:36.395\n", 682 | "16 2017-11-20 12:22:04.396\n", 683 | "17 2017-11-20 12:22:36.391\n", 684 | "18 2017-11-20 12:23:06.394\n", 685 | "19 2017-11-20 12:23:36.390\n", 686 | "20 2017-11-20 12:24:06.398\n", 687 | "21 2017-11-20 12:24:36.386\n", 688 | "22 2017-11-20 12:25:36.390\n", 689 | "23 2017-11-20 12:26:06.400\n", 690 | "24 2017-11-20 12:26:36.394\n", 691 | "25 2017-11-20 12:27:06.395\n", 692 | "26 2017-11-20 12:27:36.396\n", 693 | "27 2017-11-20 12:28:06.395\n", 694 | "28 2017-11-20 12:28:36.394\n", 695 | "29 2017-11-20 12:29:06.393\n", 696 | " ... \n", 697 | "63 2017-11-20 12:48:06.394\n", 698 | "64 2017-11-20 12:48:32.200\n", 699 | "65 2017-11-20 12:55:01.000\n", 700 | "66 2017-11-20 12:55:31.100\n", 701 | "67 2017-11-20 12:56:01.100\n", 702 | "68 2017-11-20 12:56:31.110\n", 703 | "69 2017-11-20 12:57:01.000\n", 704 | "70 2017-11-20 12:57:31.101\n", 705 | "71 2017-11-20 12:58:01.099\n", 706 | "72 2017-11-20 12:58:31.105\n", 707 | "73 2017-11-20 12:58:58.302\n", 708 | "74 2017-11-20 12:59:31.107\n", 709 | "75 2017-11-20 13:00:01.101\n", 710 | "76 2017-11-20 13:00:31.106\n", 711 | "77 2017-11-20 13:01:01.101\n", 712 | "78 2017-11-20 13:01:31.099\n", 713 | "79 2017-11-20 13:02:01.102\n", 714 | "80 2017-11-20 13:02:31.098\n", 715 | "81 2017-11-20 13:02:57.499\n", 716 | "82 2017-11-20 13:03:31.103\n", 717 | "83 2017-11-20 13:04:01.100\n", 718 | "84 2017-11-20 13:04:31.098\n", 719 | "85 2017-11-20 13:05:01.104\n", 720 | "86 2017-11-20 13:05:30.584\n", 721 | "87 2017-11-20 13:06:01.100\n", 722 | "88 2017-11-20 13:06:31.099\n", 723 | "89 2017-11-20 13:07:01.102\n", 724 | "90 2017-11-20 13:07:31.100\n", 725 | "91 2017-11-20 13:08:01.125\n", 726 | "92 2017-11-20 13:10:20.110\n", 727 | "Name: metadata.recordGeneratedAt, Length: 93, dtype: datetime64[ns]" 728 | ] 729 | }, 730 | "execution_count": 31, 731 | "metadata": {}, 732 | "output_type": "execute_result" 733 | } 734 | ], 735 | "source": [ 736 | "result['metadata.recordGeneratedAt']= result['metadata.recordGeneratedAt'].str[:-5]\n", 737 | "result['metadata.recordGeneratedAt'] = pd.to_datetime(result['metadata.recordGeneratedAt'])\n", 738 | "result['metadata.recordGeneratedAt']" 739 | ] 740 | }, 741 | { 742 | "cell_type": "markdown", 743 | "metadata": {}, 744 | "source": [ 745 | "### Plot time vs speed" 746 | ] 747 | }, 748 | { 749 | "cell_type": "code", 750 | "execution_count": 33, 751 | "metadata": {}, 752 | "outputs": [ 753 | { 754 | "data": { 755 | "text/plain": [ 756 | "[]" 757 | ] 758 | }, 759 | "execution_count": 33, 760 | "metadata": {}, 761 | "output_type": "execute_result" 762 | }, 763 | { 764 | "data": { 765 | "image/png": "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\n", 766 | "text/plain": [ 767 | "" 768 | ] 769 | }, 770 | "metadata": {}, 771 | "output_type": "display_data" 772 | } 773 | ], 774 | "source": [ 775 | "import matplotlib.pyplot as plt\n", 776 | "%matplotlib inline\n", 777 | "\n", 778 | "plt.plot(result['metadata.recordGeneratedAt'], result['payload.data.coreData.speed'])" 779 | ] 780 | } 781 | ], 782 | "metadata": { 783 | "kernelspec": { 784 | "display_name": "Python 3", 785 | "language": "python", 786 | "name": "python3" 787 | }, 788 | "language_info": { 789 | "codemirror_mode": { 790 | "name": "ipython", 791 | "version": 3 792 | }, 793 | "file_extension": ".py", 794 | "mimetype": "text/x-python", 795 | "name": "python", 796 | "nbconvert_exporter": "python", 797 | "pygments_lexer": "ipython3", 798 | "version": "3.6.3" 799 | } 800 | }, 801 | "nbformat": 4, 802 | "nbformat_minor": 1 803 | } 804 | --------------------------------------------------------------------------------