|
2 | 2 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3 | 3 | # SPDX-License-Identifier: Apache-2.0
|
4 | 4 |
|
| 5 | +import argparse |
5 | 6 | import json
|
6 | 7 | import sys
|
7 | 8 |
|
8 | 9 | import cantools
|
9 | 10 |
|
10 |
| -if len(sys.argv) < 2: |
11 |
| - print("Usage: python3 " + sys.argv[0] + " <INPUT_DBC_FILE> [<OUTPUT_JSON_FILE>]") |
12 |
| - exit(-1) |
| 11 | +default_interface_id = "1" |
| 12 | +parser = argparse.ArgumentParser( |
| 13 | + description=( |
| 14 | + "Converts a DBC file to AWS IoT FleetWise 'decoders' format for use with " |
| 15 | + "CreateDecoderManifest" |
| 16 | + ) |
| 17 | +) |
| 18 | +parser.add_argument( |
| 19 | + "-p", |
| 20 | + "--permissive", |
| 21 | + action="store_true", |
| 22 | + help="Apply the cantools strict=False option when loading the DBC file", |
| 23 | +) |
| 24 | +parser.add_argument( |
| 25 | + "-i", |
| 26 | + "--interface-id", |
| 27 | + default=default_interface_id, |
| 28 | + help=( |
| 29 | + f'Network interface ID, default "{default_interface_id}". This must match the ID used in ' |
| 30 | + "the static config file." |
| 31 | + ), |
| 32 | +) |
| 33 | +parser.add_argument( |
| 34 | + "infile", |
| 35 | + nargs="?", |
| 36 | + type=argparse.FileType("r"), |
| 37 | + default=sys.stdin, |
| 38 | + help="Input DBC file, default stdin", |
| 39 | +) |
| 40 | +parser.add_argument( |
| 41 | + "outfile", |
| 42 | + nargs="?", |
| 43 | + type=argparse.FileType("w"), |
| 44 | + default=sys.stdout, |
| 45 | + help="Output filename, default stdout", |
| 46 | +) |
| 47 | +args = parser.parse_args() |
13 | 48 |
|
14 |
| -db = cantools.database.load_file(sys.argv[1]) |
15 |
| - |
16 |
| -with open("network-interfaces.json") as f: |
17 |
| - network_interfaces = json.load(f) |
18 |
| - for interface in network_interfaces: |
19 |
| - if interface["type"] == "CAN_INTERFACE": |
20 |
| - interface_id = interface["interfaceId"] |
| 49 | +db = cantools.database.load(args.infile, strict=not args.permissive) |
21 | 50 |
|
22 | 51 | signal_decoders_to_add = []
|
23 | 52 |
|
| 53 | +processed_messages = set() |
24 | 54 | for message in db.messages:
|
| 55 | + message_text = message.name if message.name else message.frame_id |
| 56 | + if message_text in processed_messages: |
| 57 | + message_text = f"{message_text}_{message.frame_id}" |
| 58 | + processed_messages.add(message_text) |
| 59 | + processed_signals = set() |
25 | 60 | for signal in message.signals:
|
| 61 | + if signal.name in processed_signals: |
| 62 | + print( |
| 63 | + f"Signal {signal.name} occurs multiple times in the message {message_text}, only" |
| 64 | + " the first occurrence will be used", |
| 65 | + file=sys.stderr, |
| 66 | + ) |
| 67 | + continue |
| 68 | + processed_signals.add(signal.name) |
26 | 69 | signal_to_add = {}
|
27 | 70 | signal_to_add["name"] = signal.name
|
28 | 71 | signal_to_add["factor"] = signal.scale
|
|
52 | 95 | "type": "CAN_SIGNAL",
|
53 | 96 | "canSignal": signal_to_add,
|
54 | 97 | "fullyQualifiedName": f"Vehicle.{message.name}.{signal.name}",
|
55 |
| - "interfaceId": interface_id, |
| 98 | + "interfaceId": args.interface_id, |
56 | 99 | }
|
57 | 100 | )
|
58 | 101 |
|
59 | 102 | out = json.dumps(signal_decoders_to_add, indent=4, sort_keys=True)
|
60 | 103 |
|
61 |
| -if len(sys.argv) < 3: |
62 |
| - print(out) |
63 |
| -else: |
64 |
| - with open(sys.argv[2], "w") as fp: |
65 |
| - fp.write(out) |
| 104 | +args.outfile.write(out) |
0 commit comments