1#!/usr/bin/env python3 2# 3# Copyright 2018 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from acts.controllers.relay_lib.relay import RelayState 18from acts.controllers.relay_lib.usb_relay_board_base import UsbRelayBoardBase 19from pylibftdi import BitBangDevice 20""" This library is to control the sainsmart board. 21 22Device: 23 https://www.sainsmart.com/products/8-channel-12v-usb-relay-module 24 25Additional setup steps: 26Change out pip/pip3 and python2.7/3.4 based on python version 271. pip install pylibftdi 282. pip install libusb1 293. sudo apt-get install libftdi-dev 304. Make this file /etc/udev/rules.d/99-libftdi.rules with root and add the lines below: 31SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GROUP="plugdev", MODE="0660" 32SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GROUP="plugdev", MODE="0660" 335. Connect USB relay to computer and power board with necessary connectors 346. Verify device is found by: python -m pylibftdi.examples.list_devices 356a. Example output: FTDI:FT245R USB FIFO:A9079L5D 367. The FIFO value is going to be your device name in the config 378. Your config should look something like this (note FIFO name is used here): 38 39{ 40 "_description": "This is an example skeleton of a ficticious relay.", 41 "testbed": [{ 42 "_description": "A testbed with one relay", 43 "name": "relay_test", 44 "RelayDevice": { 45 "boards": [{ 46 "type": "SainSmart8ChannelUsbRelayBoard", 47 "name": "ttyUSB0", 48 "device": "A9079L5D" 49 }], 50 "devices": [{ 51 "type": "SingleButtonDongle", 52 "name": "aukey", 53 "mac_address": "e9:08:ef:2b:47:a1", 54 "relays": { 55 "Action": "ttyUSB0/1" 56 } 57 58 }] 59 } 60 }], 61 "logpath": "/tmp/logs", 62 "testpaths": ["../tests"] 63} 64""" 65 66 67class SainSmart8ChannelUsbRelayBoard(UsbRelayBoardBase): 68 def set(self, relay_position, value): 69 """Returns the current status of the passed in relay. 70 71 Note that this board acts in reverse of normal relays. 72 EG: NO = NC and NC = NO 73 74 Args: 75 relay_position: Relay position. 76 value: Turn_on or Turn_off the relay for the given relay_position. 77 """ 78 with BitBangDevice(self.device) as bb: 79 if value == RelayState.NO: 80 bb.port &= ~(self.address[relay_position]) 81 else: 82 bb.port |= self.address[relay_position] 83 self.status_dict[relay_position] = value 84