Python Examples

Transmit CAN frames on DW CAN 01

Download example

"""
Basic CAN frame transmission example using icsneopy library.

Demonstrates how to transmit CAN frames on DW CAN 01.
"""

import icsneopy


def transmit_can_frame():
	"""Transmit a CAN frame."""
	devices = icsneopy.find_all_devices()
	if not devices:
		raise RuntimeError("No devices found")

	device = devices[0]

	try:
		if not device.open():
			raise RuntimeError("Failed to open device")

		if not device.go_online():
			raise RuntimeError("Failed to go online")

		frame = icsneopy.CANMessage()
		frame.network = icsneopy.Network(icsneopy.Network.NetID.DWCAN_01)
		frame.arbid = 0x123
		frame.data = (0x01, 0x02, 0x03, 0x04)

		success = device.transmit(frame)
		if success:
			print(f"Frame transmitted: ID=0x{frame.arbid:03X}")
		else:
			print("Failed to transmit frame")

	finally:
		device.close()


if __name__ == "__main__":
	transmit_can_frame()

Receive CAN frames on DW CAN 01

Download example

"""
Basic CAN frame reception example using icsneopy library.

Demonstrates how to receive CAN frames on DW CAN 01 using callback handlers.
"""

import icsneopy
import time


def receive_can_frames():
	"""Receive CAN frames with callback handling."""
	devices = icsneopy.find_all_devices()
	if not devices:
		raise RuntimeError("No devices found")

	device = devices[0]
	frame_count = 0

	def on_frame(frame):
		nonlocal frame_count
		frame_count += 1
		print(f"[RX {frame_count}] ID: 0x{frame.arbid:03X}, "
			  f"Data: {[hex(b) for b in frame.data]}")

	frame_filter = icsneopy.MessageFilter(icsneopy.Network.NetID.DWCAN_01)
	callback = icsneopy.MessageCallback(on_frame, frame_filter)

	try:
		if not device.open():
			raise RuntimeError("Failed to open device")

		if not device.go_online():
			raise RuntimeError("Failed to go online")

		device.add_message_callback(callback)
		print("Listening for CAN frames for 10 seconds...")
		time.sleep(10)

		print(f"Total frames received: {frame_count}")

	finally:
		device.close()


if __name__ == "__main__":
	receive_can_frames()

Complete CAN Example

Download example

"""
Complete CAN example using icsneopy library.

Demonstrates device setup and CAN frame transmission/reception.
"""

import icsneopy
import time


def setup_device():
	"""Initialize CAN device."""
	devices = icsneopy.find_all_devices()
	if not devices:
		raise RuntimeError("No devices found")

	device = devices[0]
	print(f"Using device: {device}")
	return device


def open_device(device):
	"""Open device connection."""
	try:
		if not device.open():
			raise RuntimeError("Failed to open device")

		if not device.go_online():
			device.close()
			raise RuntimeError("Failed to go online")

		print("Device initialized successfully")
		return True

	except Exception as e:
		print(f"Device setup failed: {e}")
		return False


def transmit_can_frame(device, arbid, data):
	"""Transmit a CAN frame."""
	frame = icsneopy.CANMessage()
	frame.network = icsneopy.Network(icsneopy.Network.NetID.DWCAN_01)
	frame.arbid = arbid
	frame.data = data

	success = device.transmit(frame)
	if success:
		print(f"Frame transmitted: ID=0x{arbid:03X}, Data={list(data)}")
	else:
		print(f"Failed to transmit frame ID=0x{arbid:03X}")

	return success


def setup_can_reception(device):
	"""Configure CAN frame reception with callback."""
	frame_count = 0

	def frame_handler(frame):
		nonlocal frame_count
		frame_count += 1
		print(f"[RX {frame_count}] ID: 0x{frame.arbid:03X}, "
			  f"Data: {[hex(b) for b in frame.data]}, "
			  f"Length: {len(frame.data)}")

	frame_filter = icsneopy.MessageFilter(icsneopy.Network.NetID.DWCAN_01)
	callback = icsneopy.MessageCallback(frame_handler, frame_filter)
	device.add_message_callback(callback)

	print("CAN frame reception configured")
	return 0


def cleanup_device(device):
	"""Close device connection."""
	if device:
		device.close()
		print("Device connection closed")


def main():
	"""Complete CAN example with proper error handling."""
	device = None

	try:
		# Setup device
		device = setup_device()

		# Open device
		if not open_device(device):
			raise RuntimeError("Failed to initialize device")

		# Setup frame reception
		setup_can_reception(device)

		# Transmit test frames
		test_frames = [
			(0x123, (0x01, 0x02, 0x03, 0x04)),
			(0x456, (0x05, 0x06, 0x07, 0x08)),
			(0x789, (0x09, 0x0A, 0x0B, 0x0C))
		]

		for arbid, data in test_frames:
			transmit_result = transmit_can_frame(device, arbid, data)
			if not transmit_result:
				print(f"Warning: Failed to transmit frame ID=0x{arbid:03X}")
			time.sleep(0.1)

		# Listen for responses
		print("Listening for CAN frames for 5 seconds...")
		time.sleep(5)

	except Exception as e:
		print(f"Error: {e}")
		return 1

	finally:
		cleanup_device(device)

	return 0


if __name__ == "__main__":
	main()

LiveData Subscription and Monitoring

Download example

"""
LiveData subscription and monitoring example using icsneopy library.

"""

import icsneopy
import time
from datetime import timedelta


def livedata_example():
	"""Subscribe to and monitor LiveData signals."""
	devices = icsneopy.find_all_devices()
	if not devices:
		raise RuntimeError("No devices found")

	device = devices[0]
	print(f"Using device: {device}")

	try:
		if not device.open():
			raise RuntimeError("Failed to open device")

		if not device.go_online():
			raise RuntimeError("Failed to go online")

		device.enable_message_polling()

		# Create subscription message
		msg = icsneopy.LiveDataCommandMessage()
		msg.handle = icsneopy.get_new_handle()
		msg.cmd = icsneopy.LiveDataCommand.SUBSCRIBE
		msg.update_period = timedelta(milliseconds=500)
		msg.expiration_time = timedelta(milliseconds=0)

		# Subscribe to various LiveData signals
		msg.append_signal_arg(icsneopy.LiveDataValueType.GPS_LATITUDE)
		msg.append_signal_arg(icsneopy.LiveDataValueType.GPS_LONGITUDE)
		msg.append_signal_arg(icsneopy.LiveDataValueType.GPS_ACCURACY)
		msg.append_signal_arg(icsneopy.LiveDataValueType.DAQ_ENABLE)
		msg.append_signal_arg(icsneopy.LiveDataValueType.MANUAL_TRIGGER)
		msg.append_signal_arg(icsneopy.LiveDataValueType.TIME_SINCE_MSG)

		print("\nSubscribing to LiveData signals...")
		if not device.subscribe_live_data(msg):
			raise RuntimeError(f"Subscription failed: {icsneopy.get_last_error()}")

		print("Subscription successful")
		print("\nMonitoring LiveData for 5 seconds...")

		response_count = 0
		start_time = time.time()

		while time.time() - start_time < 5:
			result = device.get_messages()
			messages = result[0] if isinstance(result, tuple) else result

			for m in messages:
				if isinstance(m, icsneopy.LiveDataStatusMessage):
					if m.handle == msg.handle:
						print(f"\n[Status] Command: {m.requested_command}, Status: {m.status}")

				elif isinstance(m, icsneopy.LiveDataValueMessage):
					if m.handle == msg.handle:
						response_count += 1
						print(f"\n[Response #{response_count}]")
						signal_names = ["GPS_LAT", "GPS_LON", "GPS_ACC", 
									   "DAQ_EN", "MAN_TRIG", "TIME_SINCE"]
						for idx, val in enumerate(m.values):
							value = icsneopy.livedata_value_to_double(val)
							name = signal_names[idx] if idx < len(signal_names) else f"Signal_{idx}"
							print(f"  {name:12s}: {value:10.2f}")

			time.sleep(0.1)

		print(f"\nReceived {response_count} response messages")

		# Demonstrate setting values
		print("\nSetting custom values...")
		set_msg = icsneopy.LiveDataSetValueMessage()
		set_msg.handle = icsneopy.get_new_handle()
		set_msg.cmd = icsneopy.LiveDataCommand.SET_VALUE

		# Set DAQ_ENABLE
		value = icsneopy.livedata_double_to_value(1.0)
		if value:
			set_msg.append_set_value(icsneopy.LiveDataValueType.DAQ_ENABLE, value)

		# Set MANUAL_TRIGGER
		value = icsneopy.livedata_double_to_value(1.0)
		if value:
			set_msg.append_set_value(icsneopy.LiveDataValueType.MANUAL_TRIGGER, value)

		if device.set_value_live_data(set_msg):
			print("Values set successfully")
			time.sleep(0.5)

			# Check the results
			result = device.get_messages()
			messages = result[0] if isinstance(result, tuple) else result
			for m in messages:
				if isinstance(m, icsneopy.LiveDataStatusMessage):
					if m.handle == set_msg.handle:
						print(f" Set status: {m.status}")

		# Keep device awake by resetting TIME_SINCE_MSG
		print("\nResetting TIME_SINCE_MSG to keep device awake...")
		reset_msg = icsneopy.LiveDataSetValueMessage()
		reset_msg.handle = icsneopy.get_new_handle()
		reset_msg.cmd = icsneopy.LiveDataCommand.SET_VALUE
		
		value = icsneopy.livedata_double_to_value(0.0)
		if value:
			reset_msg.append_set_value(icsneopy.LiveDataValueType.TIME_SINCE_MSG, value)
			if device.set_value_live_data(reset_msg):
				print("TIME_SINCE_MSG reset to 0")

		# Unsubscribe
		print("\nUnsubscribing...")
		if device.unsubscribe_live_data(msg.handle):
			print("Unsubscribed successfully")

	finally:
		device.close()
		print("\nDevice closed")


if __name__ == "__main__":
	livedata_example()

Transmit Ethernet frames on Ethernet 01

Download example

"""
Basic Ethernet frame transmission example using icsneopy library.

Demonstrates how to transmit Ethernet frames on Ethernet 01.
"""

import icsneopy


def transmit_ethernet_frame():
	"""Transmit an Ethernet frame."""
	devices = icsneopy.find_all_devices()
	if not devices:
		raise RuntimeError("No devices found")

	device = devices[0]

	try:
		if not device.open():
			raise RuntimeError("Failed to open device")

		if not device.go_online():
			raise RuntimeError("Failed to go online")

		frame = icsneopy.EthernetMessage()
		frame.network = icsneopy.Network(icsneopy.Network.NetID.ETHERNET_01)
		frame.data = [
			0x00, 0xFC, 0x70, 0x00, 0x01, 0x02,
			0x00, 0xFC, 0x70, 0x00, 0x01, 0x01,
			0x08, 0x00,
			0x01, 0xC5, 0x01, 0xC5
		]

		success = device.transmit(frame)
		if success:
			print("Frame transmitted successfully")
		else:
			print("Failed to transmit frame")

	finally:
		device.close()


if __name__ == "__main__":
	transmit_ethernet_frame()

Monitor Ethernet Status

Download example

"""
Ethernet status monitoring example using icsneopy library.

Demonstrates how to monitor Ethernet link status changes.
"""

import icsneopy
import time

def main():
   devices = icsneopy.find_all_devices()
   if len(devices) == 0:
      print("error: no devices found")
      return False

   device = devices[0]
   print(f"info: monitoring Ethernet status on {device}")

   def on_message(message):
      print(f"info: timestamp: {message.timestamp}, network: {message.network}, state: {message.state}, speed: {message.speed}, duplex: {message.duplex}, mode: {message.mode}")

   filter = icsneopy.MessageFilter(icsneopy.Message.Type.EthernetStatus)
   callback = icsneopy.MessageCallback(on_message, filter)
   device.add_message_callback(callback)

   if not device.open():
      print("error: unable to open device")
      return False

   if not device.go_online():
      print("error: unable to go online")
      return False

   while True:
      time.sleep(1)

main()

TC10 Power Management

Download example

import icsneopy
import argparse


def main():
    parser = get_parser()
    args = parser.parse_args()
    run_test(args)


def find_device(serial: str) -> icsneopy.Device:
    devices = icsneopy.find_all_devices()
    for d in devices:
        if d.get_serial() == serial:
            print(f"opening device {serial}")
            return d
    return None


def run_test(args):
    # find the device
    d = find_device(args.serial)
    if d is None:
        print(f"error: unable to find device {args.serial}")
        exit(1)

    # open the device
    if not d.open():
        print(f"error: unable to open device {args.serial}")
        exit(1)

    # check if TC10 is supported
    if not d.supports_tc10():
        print(f"error: device does not support TC10 {args.serial}")
        exit(1)

    # send the request on all networks
    for n in args.networks:
        net = getattr(icsneopy.Network.NetID, n)
        if args.send_wake:
            print(f"requesting TC10 wake on network {net}")
            if not d.request_tc10_wake(net):
                print(f"error: unable to send TC10 wake on device {args.serial}")
                exit(1)
        elif args.send_sleep:
            print(f"requesting TC10 sleep on network {net}")
            if not d.request_tc10_sleep(net):
                print(f"error: unable to send TC10 sleep on device {args.serial}")
                exit(1)

    # close the device
    print(f"closing device {args.serial}")
    d.close()


def get_parser():
    parser = argparse.ArgumentParser(description="TC10 wake request")
    parser.add_argument(
        "serial",
        help="The serial number of the device",
    )
    parser.add_argument(
        "--networks",
        nargs="+",
        help="List of icsneopy networks to use.  Multiple networks accepted, e.g. '--networks ETHERNET_01 AE_01'",
        required=True,
    ),
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument(
        "--send-wake",
        help="Trigger TC10 wake on the selected networks",
        action="store_true",
        default=False,
    )
    group.add_argument(
        "--send-sleep",
        help="Trigger TC10 sleep on the selected networks",
        action="store_true",
        default=False,
    )
    return parser


if __name__ == "__main__":
    main()

DoIP Ethernet Activation

Download example

"""
DoIP activation control example using icsneopy library.

Demonstrates DoIP (Diagnostics over Internet Protocol) Ethernet activation
control with comprehensive error handling and state validation.
"""

import icsneopy
import time


def doip_activation_demo():
	"""Demonstrate DoIP Ethernet activation control with error handling."""
	devices = icsneopy.find_all_devices()
	if not devices:
		raise RuntimeError("No devices found")

	device = devices[0]
	print(f"Using {device} for DoIP activation control")

	try:
		if not device.open():
			raise RuntimeError("Failed to open device")

		if not device.go_online():
			raise RuntimeError("Failed to go online")

		initial_state = device.get_digital_io(icsneopy.IO.EthernetActivation, 1)
		print(f"Initial DoIP activation state: {initial_state}")

		print("Activating DoIP Ethernet...")
		device.set_digital_io(icsneopy.IO.EthernetActivation, 1, True)
		time.sleep(1)

		active_state = device.get_digital_io(icsneopy.IO.EthernetActivation, 1)
		print(f"DoIP activated: {active_state}")
		time.sleep(2)

		print("Deactivating DoIP Ethernet...")
		device.set_digital_io(icsneopy.IO.EthernetActivation, 1, False)
		time.sleep(1)

		final_state = device.get_digital_io(icsneopy.IO.EthernetActivation, 1)
		print(f"DoIP deactivated: {final_state}")

	except Exception as e:
		print(f"DoIP control error: {e}")
	finally:
		device.close()


if __name__ == "__main__":
	doip_activation_demo()

Complete Ethernet Example

Download example

"""
Complete Ethernet example using icsneopy library.

Demonstrates device setup and Ethernet frame transmission/reception.
"""

import icsneopy
import time


def setup_device():
	"""Initialize Ethernet device."""
	devices = icsneopy.find_all_devices()
	if not devices:
		raise RuntimeError("No devices found")

	device = devices[0]
	print(f"Using device: {device}")
	return device


def open_device(device):
	"""Open device connection."""
	try:
		if not device.open():
			raise RuntimeError("Failed to open device")

		if not device.go_online():
			device.close()
			raise RuntimeError("Failed to go online")

		print("Device initialized successfully")
		return True

	except Exception as e:
		print(f"Device setup failed: {e}")
		return False

def on_status_message(message):
	print(f"info: network: {message.network}, state: {message.state}, speed: {message.speed}, duplex: {message.duplex}, mode: {message.mode}")
	

def setup_ethernet_reception(device):
	"""Configure Ethernet frame reception with callback."""
	frame_count = 0

	def frame_handler(frame):
		nonlocal frame_count
		frame_count += 1
		dst = frame.get_destination_mac()
		src = frame.get_source_mac()
		et = frame.get_ether_type()

		dst_str = ":".join(f"{b:02x}" for b in dst) if dst is not None else "N/A"
		src_str = ":".join(f"{b:02x}" for b in src) if src is not None else "N/A"
		et_str = f"0x{et:04x}" if et is not None else "N/A"

		print(f"[RX {frame_count}], "
			f"dst={dst_str}, src={src_str}, ethertype={et_str}, "
			f"Data: {[hex(b) for b in frame.data]}, "
			f"Length: {len(frame.data)}")
	frame_filter = icsneopy.MessageFilter(icsneopy.Network.NetID.ETHERNET_02)
	callback = icsneopy.MessageCallback(frame_handler, frame_filter)
	device.add_message_callback(callback)

	print("Ethernet frame reception configured")
	return 0


def transmit_ethernet_frame(device):
	"""Transmit an Ethernet frame."""
	frame = icsneopy.EthernetMessage()
	frame.network = icsneopy.Network(icsneopy.Network.NetID.ETHERNET_01)
	frame.data = [
		0x00, 0xFC, 0x70, 0x00, 0x01, 0x02,
		0x00, 0xFC, 0x70, 0x00, 0x01, 0x01,
		0x08, 0x00,
		0x01, 0xC5, 0x01, 0xC5
	]

	success = device.transmit(frame)
	if success:
		print("Frame transmitted successfully")
	else:
		print("Failed to transmit frame")

	return success

def cleanup_device(device):
	"""Close device connection."""
	if device:
		device.close()
		print("Device connection closed")

def main():
	"""Complete Ethernet example"""
	device = None

	try:
		# Initialize device
		device = setup_device()

		# Open device
		if not open_device(device):
			raise RuntimeError("Failed to initialize device")
		
		filter = icsneopy.MessageFilter(icsneopy.Message.Type.EthernetStatus)
		status_callback = icsneopy.MessageCallback(on_status_message, filter)
		device.add_message_callback(status_callback)

		#Setup Ethernet Callback
		setup_ethernet_reception(device)

		# Transmit an Ethernet frame
		transmit_result = transmit_ethernet_frame(device)
		if not transmit_result:
			print("Warning: Failed to transmit frame")

		# Monitor for a period
		print("Monitoring for 10 seconds...")
		time.sleep(10)

		print(f"Monitoring completed.")

	except Exception as e:
		print(f"Error: {e}")
		return 1

	finally:
		cleanup_device(device)

	return 0


if __name__ == "__main__":
	main()

Device Firmware/Chip Versions

Download example

import icsneopy

def chip_versions():
	devices = icsneopy.find_all_devices()

	if len(devices) == 0:
		print("no devices found")
		return False

	device = devices[0]
	print(f"selected {device}")

	if not device.open():
		print("unable to open device")
		return False

	chip_versions = device.get_chip_versions()
	if not chip_versions:
		print("no chip versions")
		return False

	print("chip versions:")
	for i in chip_versions:
		version = f"{i.major}.{i.minor}.{i.maintenance}.{i.build}"
		print(f"    id: {i.id}, name: {i.name}, version: {version}")

	return True

if __name__ == "__main__":
	chip_versions()

SPI Example for 10BASE-T1S

Download example

"""
Complete SPI example for 10BASE-T1S MACPHYs using icsneopy library.

Demonstrates device setup and SPI frame transmission/reception.
"""

import icsneopy
import time


def setup_device():
    """Initialize SPI device."""
    devices = icsneopy.find_all_devices()
    if not devices:
        raise RuntimeError("No devices found")

    device = devices[0]
    print(f"Using device: {device}")
    return device


def open_device(device):
    """Open device connection."""
    try:
        if not device.open():
            raise RuntimeError("Failed to open device")

        if not device.go_online():
            device.close()
            raise RuntimeError("Failed to go online")

        print("Device initialized successfully")
        return True

    except Exception as e:
        print(f"Device setup failed: {e}")
        return False


def transmit_spi_frame(device, mms, addr, dir, write_data=None):
    """Transmit a SPI frame."""
    frame = icsneopy.SPIMessage()
    frame.network = icsneopy.Network(icsneopy.Network.NetID.SPI_01)
    frame.direction = dir
    frame.mms = mms
    frame.address = addr
    if dir == icsneopy.SPIMessage.Direction.Read:
        frame.payload = [0]  # single register
    else:
        frame.payload = [write_data]

    success = device.transmit(frame)
    if success:
        print("Frame transmitted")
    else:
        print("Failed to transmit frame")

    return success


def setup_spi_reception(device):
    """Configure SPI frame reception with callback."""

    def frame_handler(frame):
        access = (
            "Write"
            if frame.direction == icsneopy.SPIMessage.Direction.Write
            else "Read"
        )
        print(
            f"{access}, "
            f"MMS: 0x{frame.mms:02X}, "
            f"Register: 0x{frame.address:03X}, "
            f"Data: {[hex(b) for b in frame.payload]}, "
            f"Length: {len(frame.payload)}"
        )

    frame_filter = icsneopy.MessageFilter(icsneopy.Network.NetID.SPI_01)
    callback = icsneopy.MessageCallback(frame_handler, frame_filter)
    device.add_message_callback(callback)

    print("SPI frame reception configured")


def cleanup_device(device):
    """Close device connection."""
    if device:
        device.close()
        print("Device connection closed")


def main():
    """Complete SPI example with proper error handling."""
    device = None

    try:
        # Setup device
        device = setup_device()

        # Open device
        if not open_device(device):
            raise RuntimeError("Failed to initialize device")

        # Setup frame reception
        setup_spi_reception(device)

        # Read 10BASE-T1S MACPHY ID register
        transmit_spi_frame(device, 0x0, 0x0001, icsneopy.SPIMessage.Direction.Read)

        # Change 10BASE-T1S Test mode control
        transmit_spi_frame(device, 0x3, 0x08FB, icsneopy.SPIMessage.Direction.Read)
        transmit_spi_frame(
            device, 0x3, 0x08FB, icsneopy.SPIMessage.Direction.Write, 0x6000
        )
        transmit_spi_frame(device, 0x3, 0x08FB, icsneopy.SPIMessage.Direction.Read)

        time.sleep(0.1)

        # Listen for responses
        print("Listening for SPI frames for 5 seconds...")
        time.sleep(5)

    except Exception as e:
        print(f"Error: {e}")
        return 1

    finally:
        cleanup_device(device)

    return 0


if __name__ == "__main__":
    main()

10BASE-T1S Settings Configuration

Download example

"""
10BASE-T1S Settings Configuration Example
Demonstrates interactive T1S network configuration
"""

import icsneopy


def get_user_confirmation(prompt):
    """Get yes/no confirmation from user."""
    response = input(f"{prompt} (y/n): ").strip().lower()
    return response == 'y'


def select_networks(available_networks):
    """Let user select which networks to configure."""
    print("\n" + "=" * 70)
    print("Select T1S Networks to Configure")
    print("=" * 70)
    
    for i, net_id in enumerate(available_networks, 1):
        print(f"  [{i}] {net_id}")
    
    response = input("\nEnter network numbers to configure (e.g., '1,3' or '1-3' or 'all'): ").strip().lower()
    
    if not response:
        return []
    
    if response == 'all':
        return available_networks
    
    selected = []
    tokens = response.split(',')
    
    for token in tokens:
        token = token.strip()
        
        if '-' in token:
            try:
                parts = token.split('-')
                start = int(parts[0])
                end = int(parts[1])
                for i in range(start, end + 1):
                    if 1 <= i <= len(available_networks):
                        selected.append(available_networks[i - 1])
            except (ValueError, IndexError):
                pass
        else:
            try:
                num = int(token)
                if 1 <= num <= len(available_networks):
                    selected.append(available_networks[num - 1])
            except ValueError:
                pass
    
    return selected


def get_uint8_input(prompt, default_value):
    """Get uint8 input from user with default."""
    response = input(f"{prompt} [{default_value}]: ").strip()
    if not response:
        return default_value
    try:
        val = int(response)
        if 0 <= val <= 255:
            return val
    except ValueError:
        pass
    return default_value


def get_uint16_input(prompt, default_value):
    """Get uint16 input from user with default."""
    response = input(f"{prompt} [{default_value}]: ").strip()
    if not response:
        return default_value
    try:
        val = int(response)
        if 0 <= val <= 65535:
            return val
    except ValueError:
        pass
    return default_value


def opt_to_string(opt):
    """Convert optional value to string for display."""
    if opt is None:
        return "N/A"
    if isinstance(opt, bool):
        return "true" if opt else "false"
    return str(opt)


def display_t1s_settings(device, network):
    """Display T1S settings for a network."""
    print(f"\t{network} T1S Settings:")
    
    settings = device.settings
    if not settings:
        print("\t  Unable to read settings")
        return
    
    print(f"\t  PLCA Enabled:       {opt_to_string(settings.is_t1s_plca_enabled(network))}")
    print(f"\t  Local ID:           {opt_to_string(settings.get_t1s_local_id(network))}")
    print(f"\t  Max Nodes:          {opt_to_string(settings.get_t1s_max_nodes(network))}")
    print(f"\t  TX Opp Timer:       {opt_to_string(settings.get_t1s_tx_opp_timer(network))}")
    print(f"\t  Max Burst:          {opt_to_string(settings.get_t1s_max_burst(network))}")
    print(f"\t  Burst Timer:        {opt_to_string(settings.get_t1s_burst_timer(network))}")
    
    term_enabled = settings.is_t1s_termination_enabled(network)
    if term_enabled is not None:
        print(f"\t  Termination:        {opt_to_string(term_enabled)}")
    
    local_id_alt = settings.get_t1s_local_id_alternate(network)
    if local_id_alt is not None:
        print(f"\t  Local ID Alternate: {opt_to_string(local_id_alt)}")
        print(f"\t  Bus Dec Beacons:    {opt_to_string(settings.is_t1s_bus_decoding_beacons_enabled(network))}")
        print(f"\t  Bus Dec All:        {opt_to_string(settings.is_t1s_bus_decoding_all_enabled(network))}")
        
        multi_id_mask = settings.get_t1s_multi_id_enable_mask(network)
        if multi_id_mask is not None:
            print(f"\t  Multi-ID Mask:      0x{multi_id_mask:02X}")
            print("\t  Multi-IDs:          ", end="")
            multi_ids = []
            for i in range(7):
                multi_id = settings.get_t1s_multi_id(network, i)
                multi_ids.append(f"[{i}]={opt_to_string(multi_id)}")
            print(", ".join(multi_ids))
    
    print()


def configure_t1s_network(device, network):
    """Interactively configure T1S settings for a network."""
    print("\n" + "=" * 70)
    print(f"Configuring T1S Network: {network}")
    print("=" * 70)
    
    settings = device.settings
    if not settings:
        print("Unable to read settings")
        return
    
    print("\n--- Basic PLCA Settings ---")
    plca_enabled = get_user_confirmation("Enable PLCA")
    settings.set_t1s_plca(network, plca_enabled)
    
    local_id = get_uint8_input("Local ID (0-255)", 1)
    settings.set_t1s_local_id(network, local_id)
    
    max_nodes = get_uint8_input("Max Nodes (0-255)", 8)
    settings.set_t1s_max_nodes(network, max_nodes)
    
    tx_opp_timer = get_uint8_input("TX Opportunity Timer (0-255)", 20)
    settings.set_t1s_tx_opp_timer(network, tx_opp_timer)
    
    max_burst = get_uint16_input("Max Burst (0-65535)", 128)
    settings.set_t1s_max_burst(network, max_burst)
    
    burst_timer = get_uint16_input("Burst Timer (0-65535)", 64)
    settings.set_t1s_burst_timer(network, burst_timer)
    
    if settings.is_t1s_termination_enabled(network) is not None:
        print("\n--- Termination Settings ---")
        term_enabled = get_user_confirmation("Enable Termination")
        settings.set_t1s_termination(network, term_enabled)
    
    if settings.get_t1s_local_id_alternate(network) is not None:
        print("\n--- Extended Settings ---")
        local_id_alt = get_uint8_input("Local ID Alternate (0-255)", 0)
        settings.set_t1s_local_id_alternate(network, local_id_alt)
        
        bus_dec_beacons = get_user_confirmation("Enable Bus Decoding (Beacons)")
        settings.set_t1s_bus_decoding_beacons(network, bus_dec_beacons)
        
        bus_dec_all = get_user_confirmation("Enable Bus Decoding (All Symbols)")
        settings.set_t1s_bus_decoding_all(network, bus_dec_all)
        
        if get_user_confirmation("Configure Multi-ID settings?"):
            multi_id_mask = get_uint8_input("Multi-ID Enable Mask (0x00-0xFF, hex)", 0x00)
            settings.set_t1s_multi_id_enable_mask(network, multi_id_mask)
            
            print("Configure Multi-IDs (7 slots):")
            for i in range(7):
                multi_id = get_uint8_input(f"  Multi-ID [{i}]", 0)
                settings.set_t1s_multi_id(network, i, multi_id)
    
    print(f"\n[OK] Configuration staged for {network}")


def main():
    """Main T1S settings configuration example."""
    device = None
    
    try:
        print("\n" + "=" * 70)
        print("10BASE-T1S SETTINGS CONFIGURATION EXAMPLE")
        print("=" * 70)
        print(f"libicsneo {icsneopy.get_version()}")
        print("=" * 70)
        
        print("\nFinding devices... ", end="", flush=True)
        devices = icsneopy.find_all_devices()
        print(f"OK, {len(devices)} device{'s' if len(devices) != 1 else ''} found")
        
        if not devices:
            print("No devices found!")
            return 1
        
        for d in devices:
            print(f"  {d}")
        
        device = None
        for d in devices:
            if d.get_type().get_device_type() == icsneopy.DeviceType.Enum.RADComet3:
                device = d
                break
        
        if not device and devices:
            device = devices[0]
        
        if not device:
            print("No suitable device found!")
            return 1
        
        print(f"\nSelected device: {device}")
        print(f"Serial: {device.get_serial()}")
        
        print("\nOpening device... ", end="", flush=True)
        if not device.open():
            print("FAIL")
            return 1
        print("OK")
        
        settings = device.settings
        t1s_networks = []
        for net in device.get_supported_tx_networks():
            if net.get_type() != icsneopy.Network.Type.AutomotiveEthernet:
                continue
            if settings.get_t1s_local_id(net) is not None:
                t1s_networks.append(net)
        
        if not t1s_networks:
            print("No T1S networks found on this device")
            device.close()
            return 1
        
        print(f"\nFound {len(t1s_networks)} T1S network{'s' if len(t1s_networks) != 1 else ''}:")
        for i, net_id in enumerate(t1s_networks, 1):
            print(f"  [{i}] {net_id}")
        
        print("\n" + "-" * 70)
        print("Current T1S Settings:")
        print("-" * 70)
        for net_id in t1s_networks:
            display_t1s_settings(device, net_id)
        
        networks_to_config = select_networks(t1s_networks)
        
        if not networks_to_config:
            print("\nNo networks selected for configuration.")
            print("Closing device... ", end="", flush=True)
            device.close()
            print("OK")
            return 0
        
        print(f"\nConfiguring {len(networks_to_config)} network{'s' if len(networks_to_config) != 1 else ''}...")
        
        for net_id in networks_to_config:
            configure_t1s_network(device, net_id)
        
        print("\n" + "=" * 70)
        save_to_eeprom = get_user_confirmation("Save settings to EEPROM (permanent)?")
        print("=" * 70)
        
        settings = device.settings
        print(f"\nApplying settings{' to EEPROM' if save_to_eeprom else ' temporarily'}... ", end="", flush=True)
        success = settings.apply(not save_to_eeprom)
        if not success:
            print("FAIL")
            device.close()
            return 1
        print("OK")
        
        print("\n" + "-" * 70)
        print("Updated T1S Settings:")
        print("-" * 70)
        for net_id in t1s_networks:
            display_t1s_settings(device, net_id)
        
        print("Closing device... ", end="", flush=True)
        device.close()
        print("OK")
        
    except KeyboardInterrupt:
        print("\n\nInterrupted by user")
        return 1
    
    except Exception as e:
        print(f"\nError: {e}")
        import traceback
        traceback.print_exc()
        return 1
    
    finally:
        if device and device.is_open():
            device.close()
    
    return 0


if __name__ == "__main__":
    exit(main())

Analog Output Control

Download example

"""
Basic analog output control example using icsneopy library.

Demonstrates how to configure and control analog outputs on supported devices.

Usage: python analog_out_basic.py <pin> <voltage> [--yes]

Arguments:
  pin: Pin number (1-3 for RAD Galaxy)
  voltage: Voltage level (0-5)
  --yes: Skip confirmation prompt
"""

import sys
import icsneopy


def analog_output_example(pin: int, voltage: int, skip_confirm: bool = False):
	"""Configure and control analog outputs."""
	# Confirmation prompt
	if not skip_confirm:
		print(f"WARNING: This will set analog output pin {pin} to {voltage}V")
		print("Make sure nothing sensitive is connected to this pin.")
		response = input("Continue? (yes/no): ")
		if response.lower() != "yes":
			print("Aborted.")
			return
	
	devices = icsneopy.find_all_devices()
	if not devices:
		raise RuntimeError("No devices found")

	device = devices[0]

	try:
		if not device.open():
			raise RuntimeError("Failed to open device")

		settings = device.settings
		if not settings:
			raise RuntimeError("Device settings not available")

		print("Refreshing device settings...")
		if not settings.refresh():
			raise RuntimeError("Failed to refresh settings")

		# Enable analog output on specified pin
		print(f"Enabling analog output on pin {pin}...")
		if not settings.set_misc_io_analog_output_enabled(pin, True):
			raise RuntimeError(f"Failed to enable analog output on pin {pin}")

		# Map voltage level to enum
		voltage_map = {
			0: icsneopy.Settings.MiscIOAnalogVoltage.V0,
			1: icsneopy.Settings.MiscIOAnalogVoltage.V1,
			2: icsneopy.Settings.MiscIOAnalogVoltage.V2,
			3: icsneopy.Settings.MiscIOAnalogVoltage.V3,
			4: icsneopy.Settings.MiscIOAnalogVoltage.V4,
			5: icsneopy.Settings.MiscIOAnalogVoltage.V5
		}
		voltage_enum = voltage_map[voltage]

		# Set pin to specified voltage
		print(f"Setting pin {pin} to {voltage}V...")
		if not settings.set_misc_io_analog_output(pin, voltage_enum):
			raise RuntimeError(f"Failed to set voltage on pin {pin}")

		# Apply settings
		print("Applying settings...")
		if not settings.apply():
			raise RuntimeError("Failed to apply settings")

		print("Analog output configured successfully!")
		print(f"Pin {pin}: Enabled at {voltage}V")

	finally:
		device.close()


if __name__ == "__main__":
	if len(sys.argv) < 3:
		print("Error: Missing required arguments\n")
		print("Usage: python analog_out_basic.py <pin> <voltage> [--yes]")
		print("\nArguments:")
		print("  pin: Pin number (1-3 for RAD Galaxy)")
		print("  voltage: Voltage level (0-5)")
		print("  --yes: Skip confirmation prompt")
		sys.exit(1)
	
	try:
		pin = int(sys.argv[1])
		if pin < 1 or pin > 3:
			print("Error: Invalid pin number (must be 1-3)")
			sys.exit(1)
		
		voltage = int(sys.argv[2])
		if voltage < 0 or voltage > 5:
			print("Error: Invalid voltage level (must be 0-5)")
			sys.exit(1)
		
		skip_confirm = "--yes" in sys.argv
		
		analog_output_example(pin, voltage, skip_confirm)
		
	except ValueError:
		print("Error: Pin and voltage must be integers")
		sys.exit(1)