# Event Streams Driver for generic ethernet TCP barcode readers

**URL:** <https://forum.inductiveautomation.com/t/event-streams-driver-for-generic-ethernet-tcp-barcode-readers/113001>\
**Category:** Module Development\
**Tags:** ignition83\
**Created:** [December 27, 2025, 4:55am UTC](https://forum.inductiveautomation.com/t/event-streams-driver-for-generic-ethernet-tcp-barcode-readers/113001 "2025-12-27T04:55:11Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![David\_Stone](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/david_stone/32/79749_2.png) [@David\_Stone](https://forum.inductiveautomation.com/u/David_Stone)\
**Post date:** [December 27, 2025, 4:55am UTC](https://forum.inductiveautomation.com/t/event-streams-driver-for-generic-ethernet-tcp-barcode-readers/113001/1 "2025-12-27T04:55:11Z")

</div>

Hi All,

I have just released a very simple but useful driver for Event Streams in 8.3.  
This driver starts up a TCP server listening on a given port for any connections from a barcode reader.  
Any received barcodes are generated as an event, with the source IP and the received ASCII string delivered with a timestamp as the payload.  
This driver was made to remove the hacked up TCP listener scripts that get built in Ignition for logging barcodes to databases etc... In theory, due to it's event based architecture, there is no throughput limits for this driver, and it will queue events in the Event Streams system.  
I will be conducting more testing, but I believe that this is much more scalable than the existing options I have seen.

Currently tested working on:

- Cognex DataMan DM280

> **[Release v1.0.0-alpha · system24seven/barcode-stream](https://github.com/system24seven/barcode-stream/releases/tag/1.0.0)**
>
> This module creates a TCP listener server on the provided port number that generates an Event Stream on reciept of a packet from the TCP socket.
> Full Changelog: https://github.com/system24seven/bar...

For testing purposes, you can use this LLM generated python script to send barcodes to it manually, remember to upen the chosen port on your gateway firewall:

`python3 tcp_send.py <IP Address> <Chosen Port> "barcode string"`

> **tcp\_send.py**
>
> ```python
> #!/usr/bin/env python3
> """
> Simple TCP Client
> 
> Sends a string to a specified TCP host and port.
> """
> 
> import socket
> import sys
> 
> def send_message(host, port, message, timeout=5):
> """
> Send a message to a TCP server
>     
> Args:
> host: Target hostname or IP address
> port: Target port number
> message: Message to send
> timeout: Connection timeout in seconds (default: 5)
>     
> Returns:
> True if successful, False otherwise
> """
> try:
> # Create a TCP socket
> with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
> # Set timeout
> sock.settimeout(timeout)
>             
> # Connect to the server
> print(f"Connecting to {host}:{port}...")
> sock.connect((host, port))
> print(f"Connected!")
>             
> # Send the message (add newline if not present)
> if not message.endswith('\n'):
> message += '\n'
>             
> sock.sendall(message.encode('utf-8'))
> print(f"Sent: {message.strip()}")
>             
> return True
>             
> except socket.timeout:
> print(f"Error: Connection timeout after {timeout} seconds", file=sys.stderr)
> return False
> except ConnectionRefusedError:
> print(f"Error: Connection refused - is the server running on {host}:{port}?", file=sys.stderr)
> return False
> except socket.gaierror:
> print(f"Error: Could not resolve hostname '{host}'", file=sys.stderr)
> return False
> except Exception as e:
> print(f"Error: {e}", file=sys.stderr)
> return False
> 
> def main():
> """Main function with command-line interface"""
> import argparse
>     
> parser = argparse.ArgumentParser(
> description='Send a string to a TCP server',
> formatter_class=argparse.RawDescriptionHelpFormatter,
> epilog='''
> Examples:
> %(prog)s localhost 1000 "Hello World"
> %(prog)s 192.168.1.100 8080 "Test message"
> %(prog)s -t 10 example.com 9000 "Message with custom timeout"
> '''
> )
>     
> parser.add_argument('host', help='Target hostname or IP address')
> parser.add_argument('port', type=int, help='Target port number')
> parser.add_argument('message', help='Message to send')
> parser.add_argument('-t', '--timeout', type=int, default=5,
> help='Connection timeout in seconds (default: 5)')
>     
> args = parser.parse_args()
>     
> # Send the message
> success = send_message(args.host, args.port, args.message, args.timeout)
>     
> # Exit with appropriate code
> sys.exit(0 if success else 1)
> 
> if __name__ == ' __main__':
> main()
> 
> ```

---

<div class="post-metadata">

**Author:** ![David\_Stone](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/david_stone/32/79749_2.png) [@David\_Stone](https://forum.inductiveautomation.com/u/David_Stone)\
**Post date:** [December 28, 2025, 7:28am UTC](https://forum.inductiveautomation.com/t/event-streams-driver-for-generic-ethernet-tcp-barcode-readers/113001/2 "2025-12-28T07:28:45Z")

</div>

I have done a bit of work on this now to make it simpler to use the data in streams, now the ASCII string is included raw as the `event.payload` and the timestamp and the source IP are included as part of `event.metadata`, which is how I believe IA intended the data to emerge.

> **[Release v1.0.0-beta · system24seven/barcode-stream](https://github.com/system24seven/barcode-stream/releases/tag/1.0.0-beta)**
>
> Full Changelog: 1.0.0...1.0.0-beta
