hitl_tester.modules.cyber_6t.relay

Controls the USB relay

(c) 2020-2024 TurnAround Factor, Inc.

#

CUI DISTRIBUTION CONTROL

Controlled by: DLA J68 R&D SBIP

CUI Category: Small Business Research and Technology

Distribution/Dissemination Controls: PROTECTED BY SBIR DATA RIGHTS

POC: GOV SBIP Program Manager Denise Price, 571-767-0111

Distribution authorized to U.S. Government Agencies only, to protect information not owned by the

U.S. Government and protected by a contractor’s ‘limited rights’ statement, or received with the understanding that

it is not routinely transmitted outside the U.S. Government (determination made September 14, 2024). Other requests

for this document shall be referred to ACOR DLA Logistics Operations (J-68), 8725 John J. Kingman Rd., Suite 4317,

Fort Belvoir, VA 22060-6221

#

SBIR DATA RIGHTS

Contract No.:SP4701-23-C-0083

Contractor Name: TurnAround Factor, Inc.

Contractor Address: 10365 Wood Park Ct. Suite 313 / Ashland, VA 23005

Expiration of SBIR Data Rights Period: September 24, 2029

The Government's rights to use, modify, reproduce, release, perform, display, or disclose technical data or computer

software marked with this legend are restricted during the period shown as provided in paragraph (b)(4) of the Rights

in Noncommercial Technical Data and Computer Software--Small Business Innovative Research (SBIR) Program clause

contained in the above identified contract. No restrictions apply after the expiration date shown above. Any

reproduction of technical data, computer software, or portions thereof marked with this legend must also reproduce

the markings.

  1"""
  2Controls the USB relay
  3
  4# (c) 2020-2024 TurnAround Factor, Inc.
  5#
  6# CUI DISTRIBUTION CONTROL
  7# Controlled by: DLA J68 R&D SBIP
  8# CUI Category: Small Business Research and Technology
  9# Distribution/Dissemination Controls: PROTECTED BY SBIR DATA RIGHTS
 10# POC: GOV SBIP Program Manager Denise Price, 571-767-0111
 11# Distribution authorized to U.S. Government Agencies only, to protect information not owned by the
 12# U.S. Government and protected by a contractor’s ‘limited rights’ statement, or received with the understanding that
 13# it is not routinely transmitted outside the U.S. Government (determination made September 14, 2024). Other requests
 14# for this document shall be referred to ACOR DLA Logistics Operations (J-68), 8725 John J. Kingman Rd., Suite 4317,
 15# Fort Belvoir, VA 22060-6221
 16#
 17# SBIR DATA RIGHTS
 18# Contract No.:SP4701-23-C-0083
 19# Contractor Name: TurnAround Factor, Inc.
 20# Contractor Address: 10365 Wood Park Ct. Suite 313 / Ashland, VA 23005
 21# Expiration of SBIR Data Rights Period: September 24, 2029
 22# The Government's rights to use, modify, reproduce, release, perform, display, or disclose technical data or computer
 23# software marked with this legend are restricted during the period shown as provided in paragraph (b)(4) of the Rights
 24# in Noncommercial Technical Data and Computer Software--Small Business Innovative Research (SBIR) Program clause
 25# contained in the above identified contract. No restrictions apply after the expiration date shown above. Any
 26# reproduction of technical data, computer software, or portions thereof marked with this legend must also reproduce
 27# the markings.
 28"""
 29
 30import atexit
 31
 32import serial
 33from serial.serialutil import SerialException
 34
 35from hitl_tester.modules.logger import logger
 36
 37
 38# NOTE: Relay Assignments
 39# Relay 0 = Battery #1 Power Switch
 40# Relay 1 = Battery #2 Power Switch
 41# Relay 2 = Battery #3 Power Switch
 42# Relay 3 = N/A
 43
 44
 45class NoDataException(Exception):
 46    """Exception raised when no data is received"""
 47
 48    def __init__(self):
 49        super().__init__("No data received")
 50
 51
 52class RelayController:
 53    """Relay controller"""
 54
 55    @staticmethod
 56    def on(num: int):
 57        """Turn relay on"""
 58        RelayController.call(f"relay on {num}")
 59
 60    @staticmethod
 61    def off(num: int):
 62        """Turn relay off"""
 63        RelayController.call(f"relay off {num}")
 64
 65    @staticmethod
 66    def status():
 67        """Shows relay status"""
 68        relays = []
 69        for i in range(4):
 70            relays.append(RelayController.call(f"relay read {i}"))
 71        print(f"Relay 1: {relays[0]}\nRelay 2: {relays[1]}\nRelay 3: {relays[2]}\nRelay 4: {relays[3]}")
 72
 73    @staticmethod
 74    def call(cmd: str) -> str:
 75        """Talk to relay"""
 76        response = None
 77        try:
 78            # 9600,8,N,1
 79            with serial.Serial("/dev/taf-relay", timeout=1) as ser:
 80                ser.write(bytes(cmd + "\r", "utf-8"))
 81                response = ser.read(25)
 82                if not response:
 83                    raise NoDataException
 84                response = response[len(cmd) : -1]
 85                if not response:
 86                    raise NoDataException
 87                response = response.decode().strip("\n\r")
 88        except (TimeoutError, NoDataException) as ex:
 89            logger.write_debug_to_report(ex)
 90        except (FileNotFoundError, SerialException):
 91            pass
 92        return response or ""
 93
 94    @staticmethod
 95    def reset():
 96        """Reset relay"""
 97        for i in range(3):
 98            RelayController.off(i)
 99
100
101@atexit.register
102def __atexit__():
103    """Open all relays when shutting down."""
104    logger.write_debug_to_report("Shutting down relays.")
105    RelayController.reset()
106
107
108if __name__ == "__main__":
109    print("Resetting relays...")
110    RelayController.reset()
111    print("Status:")
112    RelayController.status()
class NoDataException(builtins.Exception):
46class NoDataException(Exception):
47    """Exception raised when no data is received"""
48
49    def __init__(self):
50        super().__init__("No data received")

Exception raised when no data is received

Inherited Members
builtins.BaseException
with_traceback
add_note
args
class RelayController:
53class RelayController:
54    """Relay controller"""
55
56    @staticmethod
57    def on(num: int):
58        """Turn relay on"""
59        RelayController.call(f"relay on {num}")
60
61    @staticmethod
62    def off(num: int):
63        """Turn relay off"""
64        RelayController.call(f"relay off {num}")
65
66    @staticmethod
67    def status():
68        """Shows relay status"""
69        relays = []
70        for i in range(4):
71            relays.append(RelayController.call(f"relay read {i}"))
72        print(f"Relay 1: {relays[0]}\nRelay 2: {relays[1]}\nRelay 3: {relays[2]}\nRelay 4: {relays[3]}")
73
74    @staticmethod
75    def call(cmd: str) -> str:
76        """Talk to relay"""
77        response = None
78        try:
79            # 9600,8,N,1
80            with serial.Serial("/dev/taf-relay", timeout=1) as ser:
81                ser.write(bytes(cmd + "\r", "utf-8"))
82                response = ser.read(25)
83                if not response:
84                    raise NoDataException
85                response = response[len(cmd) : -1]
86                if not response:
87                    raise NoDataException
88                response = response.decode().strip("\n\r")
89        except (TimeoutError, NoDataException) as ex:
90            logger.write_debug_to_report(ex)
91        except (FileNotFoundError, SerialException):
92            pass
93        return response or ""
94
95    @staticmethod
96    def reset():
97        """Reset relay"""
98        for i in range(3):
99            RelayController.off(i)

Relay controller

@staticmethod
def on(num: int):
56    @staticmethod
57    def on(num: int):
58        """Turn relay on"""
59        RelayController.call(f"relay on {num}")

Turn relay on

@staticmethod
def off(num: int):
61    @staticmethod
62    def off(num: int):
63        """Turn relay off"""
64        RelayController.call(f"relay off {num}")

Turn relay off

@staticmethod
def status():
66    @staticmethod
67    def status():
68        """Shows relay status"""
69        relays = []
70        for i in range(4):
71            relays.append(RelayController.call(f"relay read {i}"))
72        print(f"Relay 1: {relays[0]}\nRelay 2: {relays[1]}\nRelay 3: {relays[2]}\nRelay 4: {relays[3]}")

Shows relay status

@staticmethod
def call(cmd: str) -> str:
74    @staticmethod
75    def call(cmd: str) -> str:
76        """Talk to relay"""
77        response = None
78        try:
79            # 9600,8,N,1
80            with serial.Serial("/dev/taf-relay", timeout=1) as ser:
81                ser.write(bytes(cmd + "\r", "utf-8"))
82                response = ser.read(25)
83                if not response:
84                    raise NoDataException
85                response = response[len(cmd) : -1]
86                if not response:
87                    raise NoDataException
88                response = response.decode().strip("\n\r")
89        except (TimeoutError, NoDataException) as ex:
90            logger.write_debug_to_report(ex)
91        except (FileNotFoundError, SerialException):
92            pass
93        return response or ""

Talk to relay

@staticmethod
def reset():
95    @staticmethod
96    def reset():
97        """Reset relay"""
98        for i in range(3):
99            RelayController.off(i)

Reset relay