|
11 | 11 | import logging |
12 | 12 | from collections import deque |
13 | 13 |
|
14 | | -from can import Message |
| 14 | +from can import Message, CanError |
15 | 15 | from can.bus import BusABC |
16 | 16 |
|
17 | 17 | logger = logging.getLogger(__name__) |
|
26 | 26 | ics = None |
27 | 27 |
|
28 | 28 |
|
| 29 | +class ICSApiError(CanError): |
| 30 | + # A critical error which affects operation or accuracy. |
| 31 | + ICS_SPY_ERR_CRITICAL = 0x10 |
| 32 | + # An error which is not understood. |
| 33 | + ICS_SPY_ERR_QUESTION = 0x20 |
| 34 | + # An important error which may be critical depending on the application |
| 35 | + ICS_SPY_ERR_EXCLAMATION = 0x30 |
| 36 | + # An error which probably does not need attention. |
| 37 | + ICS_SPY_ERR_INFORMATION = 0x40 |
| 38 | + |
| 39 | + def __init__( |
| 40 | + self, error_number, description_short, description_long, |
| 41 | + severity, restart_needed |
| 42 | + ): |
| 43 | + super(ICSApiError, self).__init__(description_short) |
| 44 | + self.error_number = error_number |
| 45 | + self.description_short = description_short |
| 46 | + self.description_long = description_long |
| 47 | + self.severity = severity |
| 48 | + self.restart_needed = restart_needed == 1 |
| 49 | + |
| 50 | + def __str__(self): |
| 51 | + return "{} {}".format(self.description_short, self.description_long) |
| 52 | + |
| 53 | + @property |
| 54 | + def is_critical(self): |
| 55 | + return self.severity == self.ICS_SPY_ERR_CRITICAL |
| 56 | + |
| 57 | + |
29 | 58 | class NeoViBus(BusABC): |
30 | 59 | """ |
31 | 60 | The CAN Bus implemented for the python_ics interface |
@@ -127,10 +156,13 @@ def _process_msg_queue(self, timeout=None): |
127 | 156 | continue |
128 | 157 | self.rx_buffer.append(ics_msg) |
129 | 158 | if errors: |
130 | | - logger.warning("%d errors found" % errors) |
| 159 | + logger.warning("%d error(s) found" % errors) |
131 | 160 |
|
132 | 161 | for msg in ics.get_error_messages(self.dev): |
133 | | - logger.warning(msg) |
| 162 | + error = ICSApiError(*msg) |
| 163 | + if error.is_critical: |
| 164 | + raise error |
| 165 | + logger.warning(error) |
134 | 166 |
|
135 | 167 | def _is_filter_match(self, arb_id): |
136 | 168 | """ |
@@ -219,7 +251,11 @@ def send(self, msg, timeout=None): |
219 | 251 | message.StatusBitField = flags |
220 | 252 | message.StatusBitField2 = 0 |
221 | 253 | message.NetworkID = self.network |
222 | | - ics.transmit_messages(self.dev, message) |
| 254 | + |
| 255 | + try: |
| 256 | + ics.transmit_messages(self.dev, message) |
| 257 | + except ics.RuntimeError: |
| 258 | + raise ICSApiError(*ics.get_last_api_error(self.dev)) |
223 | 259 |
|
224 | 260 | def set_filters(self, can_filters=None): |
225 | 261 | """Apply filtering to all messages received by this Bus. |
|
0 commit comments