# Path: ripyl/util/enum.py
# class Enum(object):
#     '''Base class for enumeration classes
#     
#     This provides a name() class method that will return the string
#     attribute name for an encoded enumeration value.
#     
#     e.g.
#     
#     >>> class Colors(Enum):
#     ...     blue = 1
#     ...     red = 2
#     ...     green = 3
#         
#     >>> Colors.name(Colors.red)
#     'red'
#     
#     >>> Colors.name(1, full_name=True)
#     'Colors.blue'
# 
#     "Instantiating" the Enum sub-class calls the name() method as well:
#     
#     >>> Colors(3, full_name=False)
#     'green'
#     
#     If necesssary you can use non-integers as the values as long as they are hashable:
#     
#     >>> class MathConst(Enum):
#     ...     pi = 3.2     # in certain US states :)
#     ...     e = 2.71828
#         
#     >>> MathConst.pi
#     3.2
#     
#     '''
# 
#     @classmethod
#     def name(cls, value, full_name=False):
#         '''Lookup the enumeration name with the provided value
# 
#         value (hashable)
#             A hashable Enum value (typically int) to find a name for.
# 
#         full_name (bool)
#             Include full name of Enum object in result
# 
#         Returns a string for the Enum attribute associated with value.
#         '''
#         
#         try:
#             enum_lookup = cls._enum_lookup
#         except AttributeError:
#             # Build inverse dict of class attributes with their values as key
#             enum_lookup = dict((v, k) for k, v in cls.__dict__.items() if k[0] != '_')
#             cls._enum_lookup = enum_lookup
#         
#         try:
#             aname = enum_lookup[value]
#             prefix = cls.__name__ + '.' if full_name else ''
#             return prefix + aname
# 
#         except KeyError:
#             return 'unknown'
# 
#     def __new__(cls, value, full_name=False):
#         '''Override class instantitation to perform name lookup instead'''
#         return cls.name(value, full_name)


from ripyl.decode import *
from ripyl.util.enum import Enum
import ripyl.streaming as stream
import ripyl.sigproc as sigp
import ripyl.protocol.uart as uart
import ripyl.protocol.obd2 as obd
# or in the response to the StartCommunication request. (ISO14230)
# ISO9141 keys : 08 08; 94 94
# ISO14230 keys: 8F E9; 8F 6B; 8F 6D; 8F EF

# Unknown key used on Sagem MC1000 for ISO14230 init: D9 8F

# Detecting the length of a message is tricky since ISO9141 doesn't include a byte
# count and we are not monitoring the L-line to differentiate between data sent
# and received. Until a better system can be devised the decoder uses a simple
# minimum time period between bytes to decide if a new message has started.
# The OBD-2 standard requires this to be at least 55ms but This can be violated by
# the tool controlling the interface. In one case, a piece of software had a gap
# as low as 8ms between messages.

# ISO14230 messages are terminated at the length indicated in their header.

# Messages are either a request from an external tool or a response from one or
# more ECUs. These are distinguished by looking at the value of the service ID (mode)
# in the message. This is the first data byte after the header.
# SIDs from 0x00 to 0x3F are requests. SIDs from 0x40 to 0x7F are responses.



class KLineProtocol(Enum):
    '''Enumeration for identifying the message protocol'''
    Unknown = 0
    ISO9141 = 1
    ISO14230 = 2 # KWP2000



# Path: ripyl/util/enum.py
# class Enum(object):
#     '''Base class for enumeration classes
#     
#     This provides a name() class method that will return the string
#     attribute name for an encoded enumeration value.
#     
#     e.g.
#     
#     >>> class Colors(Enum):
#     ...     blue = 1
#     ...     red = 2
#     ...     green = 3
#         
#     >>> Colors.name(Colors.red)
#     'red'
#     
#     >>> Colors.name(1, full_name=True)
#     'Colors.blue'
# 
#     "Instantiating" the Enum sub-class calls the name() method as well:
#     
#     >>> Colors(3, full_name=False)
#     'green'
#     
#     If necesssary you can use non-integers as the values as long as they are hashable:
#     
#     >>> class MathConst(Enum):
#     ...     pi = 3.2     # in certain US states :)
#     ...     e = 2.71828
#         
#     >>> MathConst.pi
#     3.2
#     
#     '''
# 
#     @classmethod
#     def name(cls, value, full_name=False):
#         '''Lookup the enumeration name with the provided value
# 
#         value (hashable)
#             A hashable Enum value (typically int) to find a name for.
# 
#         full_name (bool)
#             Include full name of Enum object in result
# 
#         Returns a string for the Enum attribute associated with value.
#         '''
#         
#         try:
#             enum_lookup = cls._enum_lookup
#         except AttributeError:
#             # Build inverse dict of class attributes with their values as key
#             enum_lookup = dict((v, k) for k, v in cls.__dict__.items() if k[0] != '_')
#             cls._enum_lookup = enum_lookup
#         
#         try:
#             aname = enum_lookup[value]
#             prefix = cls.__name__ + '.' if full_name else ''
#             return prefix + aname
# 
#         except KeyError:
#             return 'unknown'
# 
#     def __new__(cls, value, full_name=False):
#         '''Override class instantitation to perform name lookup instead'''
#         return cls.name(value, full_name)


# Path: ripyl/protocol/iso_k_line.py
from ripyl.decode import *
from ripyl.util.enum import Enum
import ripyl.streaming as stream
import ripyl.sigproc as sigp
import ripyl.protocol.uart as uart
import ripyl.protocol.obd2 as obd

# or in the response to the StartCommunication request. (ISO14230)
# ISO9141 keys : 08 08; 94 94
# ISO14230 keys: 8F E9; 8F 6B; 8F 6D; 8F EF

# Unknown key used on Sagem MC1000 for ISO14230 init: D9 8F

# Detecting the length of a message is tricky since ISO9141 doesn't include a byte
# count and we are not monitoring the L-line to differentiate between data sent
# and received. Until a better system can be devised the decoder uses a simple
# minimum time period between bytes to decide if a new message has started.
# The OBD-2 standard requires this to be at least 55ms but This can be violated by
# the tool controlling the interface. In one case, a piece of software had a gap
# as low as 8ms between messages.

# ISO14230 messages are terminated at the length indicated in their header.

# Messages are either a request from an external tool or a response from one or
# more ECUs. These are distinguished by looking at the value of the service ID (mode)
# in the message. This is the first data byte after the header.
# SIDs from 0x00 to 0x3F are requests. SIDs from 0x40 to 0x7F are responses.



class KLineProtocol(Enum):
    '''Enumeration for identifying the message protocol'''
    Unknown = 0
    ISO9141 = 1
    ISO14230 = 2 # KWP2000



class KLineStreamStatus(Enum):