SwitchEV / iso15118

Implementation of the ISO 15118 Communication Protocol (-2, -20, -8)
Apache License 2.0
147 stars 82 forks source link

Order of supportedProtocols is not preserved #424

Open js-tud opened 6 days ago

js-tud commented 6 days ago

Hello,

if I enter multiple protocols in the evcc_config file, the order is not preserved due to the use of set() in functions _format_list() and load_requested_protocols() located in iso15118/shared/utils.py

This is a quick fix that preserves the priority order found in https://stackoverflow.com/a/58666031 and https://stackoverflow.com/a/23529016

"""removes duplicates and preserves order"""
def _ordered_list_without_duplicates(l: List[str]) -> List[str]:
    tmp = set()
    return [x for x in l if not (x in tmp or tmp.add(x))]

"""intersects two lists and preserves order of list1"""
def _ordered_intersected_lists(list1: List[str], list2: List[str]) -> List[str]:
    set2 = set(list2)
    return [x for x in list1 if x in set2]

def _format_list(read_settings: List[str]) -> List[str]:
    read_settings = list(filter(None, read_settings))
    read_settings = [setting.strip().upper() for setting in read_settings]
#    read_settings = list(set(read_settings))
    return _ordered_list_without_duplicates(read_settings)

def load_requested_protocols(read_protocols: Optional[List[str]]) -> List[Protocol]:
    supported_protocols = [
        "ISO_15118_2",
        "ISO_15118_20_AC",
        "ISO_15118_20_DC",
        "DIN_SPEC_70121",
    ]
    protocols = _format_list(read_protocols)
#    valid_protocols = list(set(protocols).intersection(supported_protocols))
    valid_protocols = _ordered_intersected_lists(protocols, supported_protocols)

    if not valid_protocols:
        raise NoSupportedProtocols(
            f"No supported protocols configured. Supported protocols are "
            f"{supported_protocols} and could be configured in evcc_config.json"
        )
    return [Protocol[name] for name in valid_protocols if name in Protocol.__members__]