py_canoe.core.application.Application

Source code in src\py_canoe\core\application.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def __init__(self, enable_events: bool = True) -> None:
    self._enable_events = enable_events
    self.bus_types = {'CAN': 1, 'J1939': 2, 'TTP': 4, 'LIN': 5, 'MOST': 6, 'Kline': 14}
    self.com_object = None
    self.application_events = None
    self.bus: Bus = None
    self.capl: Capl = None
    self.configuration: Configuration = None
    self.environment: Environment = None
    self.measurement: Measurement = None
    self.system: System = None
    self.ui: Ui = None
    self.version: Version = None
    self.capl_function_objects = object()
    self.user_capl_functions = tuple()

attach_to_active_application()

Attach to a active instance of the CANoe application.

Source code in src\py_canoe\core\application.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
def attach_to_active_application(self) -> bool:
    """Attach to a active instance of the CANoe application."""
    try:
        self._launch_application()
        if self.com_object:
            logger.info("Successfully attached to active CANoe application ")
            self._setup_post_configuration_loading()
            return True
        else:
            logger.error("Failed to attach to active CANoe application")
            return False
    except Exception as e:
        logger.error(f"Error attaching to active CANoe application: {e}")
        return False

new(auto_save=False, prompt_user=False, timeout=5)

Create a new empty CANoe configuration.

Source code in src\py_canoe\core\application.py
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def new(self, auto_save: bool = False, prompt_user: bool = False, timeout: int = 5) -> bool:
    """Create a new empty CANoe configuration."""
    self._launch_application()
    status = False
    try:
        logger.info("Opening new empty CANoe configuration...")
        self.com_object.New(auto_save, prompt_user)
        if self._enable_events:
            cond = lambda: self.application_events.OPENED
        else:
            cond = lambda: self.com_object.FullName != ""
        status = DoEventsUntil(cond, timeout, "New CANoe configuration")
        if status:
            logger.info("New empty CANoe configuration Opened ")
            self._setup_post_configuration_loading()
        return status
    except Exception as e:
        logger.error(f"Error creating new configuration: {e}")
        status = False
        return status

open(canoe_cfg, visible=True, auto_save=True, prompt_user=False, timeout=5)

Open an existing CANoe configuration.

Source code in src\py_canoe\core\application.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
def open(self, canoe_cfg: str | Path, visible: bool = True, auto_save: bool = True, prompt_user: bool = False, timeout: int = 5) -> bool:
    """Open an existing CANoe configuration."""
    self._launch_application()
    status = False
    try:
        self.visible = visible
        logger.info("Opening CANoe configuration ...")
        canoe_cfg_str = str(canoe_cfg)
        self.com_object.Open(canoe_cfg, auto_save, prompt_user)
        if self._enable_events:
            cond = lambda: self.application_events.OPENED
        else:
            cond = lambda: self.com_object.FullName.lower() == canoe_cfg_str.lower()
        status = DoEventsUntil(cond, timeout, "Open CANoe configuration")
        if status:
            logger.info(f"CANoe Configuration {canoe_cfg} Opened ")
            self._setup_post_configuration_loading()
        return status
    except Exception as e:
        logger.error(f"Error opening configuration: {e}")
        status = False
        return status

open_config(canoe_cfg, auto_save=True, prompt_user=False, timeout=60)

Switch to a different CANoe configuration without restarting CANoe.

This method switches configurations in an already-running CANoe instance. Use this when CANoe is already running and you want to load a different .cfg file.

For starting CANoe with a configuration from scratch, use open() instead.

Parameters:
  • canoe_cfg (str | Path) –

    Path to the CANoe configuration (.cfg) file.

  • auto_save (bool, default: True ) –

    If True, automatically save the current configuration before switching.

  • prompt_user (bool, default: False ) –

    If True, prompt user for confirmation before switching.

  • timeout (int, default: 60 ) –

    Maximum time to wait for configuration to load (seconds).

Returns:
  • bool

    True if configuration was successfully loaded, False otherwise.

Source code in src\py_canoe\core\application.py
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
def open_config(self, canoe_cfg: str | Path, auto_save: bool = True, prompt_user: bool = False, timeout: int = 60) -> bool:
    """Switch to a different CANoe configuration without restarting CANoe.

    This method switches configurations in an already-running CANoe instance.
    Use this when CANoe is already running and you want to load a different .cfg file.

    For starting CANoe with a configuration from scratch, use open() instead.

    Args:
        canoe_cfg: Path to the CANoe configuration (.cfg) file.
        auto_save: If True, automatically save the current configuration before switching.
        prompt_user: If True, prompt user for confirmation before switching.
        timeout: Maximum time to wait for configuration to load (seconds).

    Returns:
        True if configuration was successfully loaded, False otherwise.
    """
    import time as _time
    status = False
    try:
        abs_path = str(Path(canoe_cfg).resolve())
        logger.info(f"Switching to CANoe configuration: {abs_path}")

        # Reset OPENED flag before calling Open
        self.application_events.OPENED = False

        # Call COM Open() to switch configuration
        self.com_object.Open(abs_path, auto_save, prompt_user)

        if self._enable_events:
            status = DoEventsUntil(
                lambda: self.application_events.OPENED and
                        self.configuration.full_name.lower() == abs_path.lower(),
                timeout,
                f"Switch to configuration {canoe_cfg}"
            )
        else:
            # Poll FullName without PumpWaitingMessages
            poll_deadline = _time.monotonic() + timeout
            while _time.monotonic() < poll_deadline:
                try:
                    if self.configuration.full_name.lower() == abs_path.lower():
                        status = True
                        break
                except Exception:
                    pass
                _time.sleep(0.2)

        if status:
            logger.info(f"Configuration switched successfully to {canoe_cfg}")
            self._setup_post_configuration_loading()
        else:
            logger.warning(f"Configuration switch timed out after {timeout}s")

        return status
    except Exception as e:
        logger.error(f"Error switching configuration: {e}")
        return False

pump_messages()

Pump COM messages to prevent blocking.

This is a thin wrapper around pythoncom.PumpWaitingMessages(). Use this in custom wait loops to keep COM responsive.

Example

while not ready(): app.pump_messages() time.sleep(0.1)

Source code in src\py_canoe\core\application.py
246
247
248
249
250
251
252
253
254
255
256
257
def pump_messages(self) -> None:
    """Pump COM messages to prevent blocking.

    This is a thin wrapper around pythoncom.PumpWaitingMessages().
    Use this in custom wait loops to keep COM responsive.

    Example:
        >>> while not ready():
        >>>     app.pump_messages()
        >>>     time.sleep(0.1)
    """
    pythoncom.PumpWaitingMessages()

quit(timeout=5)

Quit CANoe and clean up COM references.

Source code in src\py_canoe\core\application.py
157
158
159
160
161
162
163
164
165
166
167
168
169
170
def quit(self, timeout: int = 5) -> bool:
    """Quit CANoe and clean up COM references."""
    status = False
    try:
        self.configuration.modified = False
        self.com_object.Quit()
        status = DoEventsUntil(lambda: self.application_events.QUIT, timeout, "Quit CANoe application")
        if status:
            logger.info("CANoe Application Quit Successfully ")
        return status
    except Exception as e:
        logger.error(f"Error during CANoe quit: {e}")
        status = False
        return status