Skip to content

Meaning of can.BusABC.state #736

Open

Description

@onvav

Hello,
please help me understand the meaning of class BusState(Enum):. I would like to show status of the interface (Kvaser Leaf and Vector VN1610 are on my desk) as specified by CAN specification (error active, error passive and bus-off state).
But the @Property def state(self): of the classes class KvaserBus(BusABC): and class VectorBus(BusABC): are not implemented.

I would like to implement them but I am not sure what it shall returns

  • state of the CAN bus as defined by standard (active, passive, error=busoff)
  • state of the Python class BusABC (active, passive=silent_mode, error=some_driver)

The documentation says that it returns "current state of the hardware". Does it mean state of driver connection with HW interface or state of CAN bus controller (active->passive->busoff)?

Activity

  1. christiansandberg commented on Dec 5, 2019

    @christiansandberg
    Collaborator

    Unfortunately it is a mix of both. I’m guessing the idea was that when reading it you would get the first and when writing to it you change the second. You could look at another implementation, like pcan for inspiration.

  2. bggardner commented on Jun 1, 2020

    @bggardner

    I was writing a post to the message board, but found this issue and decided to post it here instead:

    Could we consider renaming the BusState enum options according to the CAN specification (ERROR_ACTIVE, ERROR_PASSIVE, BUS_DOWN)?

    Also, as I primarily use socketcan, there is a fourth state ("STOPPED"), which means the interface (not just the "bus") is down and will not automatically recover (as in Bus-Off) until brought back up. I'm not sure how applicable this is to the other interfaces, but maybe add this fourth state? Knowing the difference between Bus-Off and down/stopped in an application can be important. For those who are interested, the SocketCAN state can be found using "ip -d link show ", then finding the string on this line: "can state restart-ms ".

    Additionally, defaulting BusABC's state property to be ACTIVE seems to be bad practice. It seems the better practice would be to either make the state property throw a NotImplementedError() by default or default to a new UNKNOWN enum value. If there is no way to detect the state for an interface and it actually needs the state property to return ACTIVE (and not UNKNOWN) or an exception, then only that interface's Bus class would override the state property. This may solve the "mix of both" issue by simply defining more states, or making them different class properties (hardware state vs. software state). I would prefer a single property (state) with more enum options.

    I can work on a PR if pursuing this is worthwhile.

  3. bggardner commented on Jun 1, 2020

    @bggardner

    For reference, from iproute2:

    static const char *can_state_names[CAN_STATE_MAX] = {
    	[CAN_STATE_ERROR_ACTIVE] = "ERROR-ACTIVE",
    	[CAN_STATE_ERROR_WARNING] = "ERROR-WARNING",
    	[CAN_STATE_ERROR_PASSIVE] = "ERROR-PASSIVE",
    	[CAN_STATE_BUS_OFF] = "BUS-OFF",
    	[CAN_STATE_STOPPED] = "STOPPED",
    	[CAN_STATE_SLEEPING] = "SLEEPING"
    };
    
  4. felixdivo commented on Nov 21, 2020

    @felixdivo
    Collaborator

    Do we plan to agree on a naming for the 4.0 release? Would probably be a good idea to change it before and not after it.

  5. hardbyte commented on Apr 14, 2021

    @hardbyte
    Owner

    Agree, needs a champion! My 2c is that BusABC.state should include all the options as @bggardner has suggested.

  6. bggardner commented on May 3, 2021

    @bggardner

    PR #847 contains my suggestions, except for the default value of BusABC.state (see comment), which 4.0 would be a good time to change it. Let me know and I can update the PR to include it (probably the NotImplementedError() option).

  7. keelung-yang commented on Jan 6, 2022

    @keelung-yang

    Why there is no a state to stand for RUNNING / NORMAL / BUS_ON ?
    If users want to check bus state whether in normal (without any error) by reading bus's state property, how should we write correct state getter? even if there is an device api can fetch status of CAN bus.

  8. bggardner commented on Jan 6, 2022

    @bggardner

    The ERROR-ACTIVE state is equivalent to "normal". All three ERROR-* states mean the bus is "running", but in various states of error, and it could be argued that even BUS-OFF could be considered "running", as the bus can recover automatically from it without intervention. ERROR-ACTIVE, ERROR-PASSIVE and BUS-OFF are defined in ISO 11898-1. ERROR-WARNING is really just ERROR-ACTIVE when the errors haven't exceeded the ERROR-PASSIVE threshold (the warning threshold is implementation-specific). We are considering a STOPPED state so the application knows the CAN interface is disabled/inoperable as opposed to enabled/operable but in the BUS-OFF state.

  9. bggardner commented on Oct 12, 2022

    @bggardner

    @hardbyte @felixdivo Now that 4.0 has been released and this was not incorporated :(, what's the plan? Maybe 4.1? I updated PR #847 with upstream so the change can be easily merged.

  10. felixdivo commented on Oct 12, 2022

    @felixdivo
    Collaborator

    @bggardner thanks for reviving this. I'm not involved anymore, so @hardbyte maybe you have an opinion?

  11. zariiii9003 commented on Oct 13, 2022

    @zariiii9003
    Collaborator

    I suggest adding these properties to BusABC

    from enum import Enum, auto
    
    
    class ErrorState(Enum):
        ERROR_ACTIVE = auto()
        ERROR_WARNING = auto()
        ERROR_PASSIVE = auto()
        BUS_OFF = auto()
        STOPPED = auto()
        SLEEPING = auto()
    
    
    class BusABC(metaclass=ABCMeta):
        
        @property
        def error_state(self) -> ErrorState:
            raise NotImplementedError()
        
        @property
        def tx_error_count(self) -> int:
            raise NotImplementedError()
        
        @property
        def rx_error_count(self) -> int:
            raise NotImplementedError()

    The BusState class should be deprecated and replaced by a silent: bool = False argument in BusABC.__init__() (and maybe a silent property).

  12. bggardner commented on Oct 13, 2022

    @bggardner

    Point of order: The definition of bus state in ISO 11898-1 is "one of two complementary logical states: dominant or recessive"...equivalent to a zero or one. Elsewhere in ISO-11898-1, the three states error-active, error-passive, and bus-off are referred to as states of a node, not the bus (nor an "error state"). However, for the majority of this repo's use cases, these definitions are probably not critically important.

    In any case, it is important to indicate these three "node states" to the application. The state of the can interface should also be indicated to the application, which would most likely be one of "up" or "down". However, if the interface is "up", the node will be in one of those three states; and if the interface is "down", the node will be in none of those states. I believe the iproute2 developers came to the same conclusion, which is why they have combined the "node states" with the "interface states" into the six "can states" above. I propose(d) we do the same.

    So, props to @zariiii9003 for recommending error counts as well, but I think we can keep the BusState class, and document it is a combined indicator of both the CAN node state and the state of the CAN interface. I would be open to renaming it to CanState to avoid nomenclature confusion with BusState.

  13. zariiii9003 commented on Oct 14, 2022

    @zariiii9003
    Collaborator

    "Error state" is quite common in CAN interface docs. There's even an "error state indicator" bit.
    But i do not care about the name. Keeping BusState makes the transition more complicated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions