Source code for PyExpLabSys.drivers.innova
# -*- coding: utf-8 -*-
"""
Driver for the Innova RT 6K UPS
Implemented from this document:
http://networkupstools.org/protocols/megatec.htmlL
"""
import serial
import io
#: The first 7 places of the response to the status inquiry are numbers, who
#: are paired with the names in the list below
STATUS_INQUIRY_NAMES = [
'input_voltage',
'input_fault_voltage',
'output_voltage',
'output_current_load_percent',
'input_frequency',
'battery_voltage',
'temperature_C',
]
#: The last section of the response to the status inquiry are 0's and 1's,
#: which indicate the boolean status of the fields listed below.
STATUS_INQUIRY_BOOLEANS = [
'utility_fail_immediate',
'battery_low',
'bypass_boost_or_buck_active',
'UPS_failed',
'UPS_type_is_standby',
'test_in_progress',
'shutdown_active',
'beeper_on',
]
#: The names for the floats returned as section from the rating information
#: command
RATING_INFORMATION_FIELDS = [
'rating_voltage',
'rating_current',
'battery_voltage',
'frequency',
]
[docs]class Megatec(object):
"""Driver that implements parts of the Megatech specification"""
[docs] def __init__(self, device, baudrate=2400, timeout=2.0):
self.serial = serial.Serial(device, baudrate=baudrate, timeout=timeout)
self.serialio = io.TextIOWrapper(
io.BufferedRWPair(self.serial, self.serial), newline='\r'
)
print('init')
[docs] def com(self, command):
"""Perform communication"""
self.serialio.write(command)
self.serialio.flush()
return self.serialio.readline()
[docs] def get_status(self):
"""Return the status as a dict
The values in the dict are either float or booleans. The keys for the
float values are:
* output_voltage
* input_voltage
* temperature_C
* input_frequency
* battery_voltage
* output_current_load_percent
* input_fault_voltage
The keys for the boolean values are:
* utility_fail_immediate
* battery_low
* bypass_boost_or_buck_active
* UPS_failed
* UPS_type_is_standby
* test_in_progress
* shutdown_active
* beeper_on
"""
response = self.com('Q1\r')
if response[0] != '(' or response[-1] != '\r':
msg = (
'Unexpect reply on status inquiry. Either did not start '
'with "(" or end with "\\r"'
)
raise IOError(msg)
# Split into section and
sections = response.strip('(').split(' ')
status = {
name: float(value) for name, value in zip(STATUS_INQUIRY_NAMES, sections)
}
# Section 7 are boolean indicators
bool_strs = sections[7].strip()
for name, bool_str in zip(STATUS_INQUIRY_BOOLEANS, bool_strs):
status[name] = bool_str == '1'
return status
[docs] def test_for_10_sec(self):
"""Run a test of the batteries for 10 sec and return to utility"""
response = self.com('T\r')
if response.strip() != 'ACK':
message = 'UPS response to command "T" was "{}", not "ACK" as ' 'expected.'
raise IOError(message.format(response))
[docs]class InnovaRT6K(Megatec):
"""for the InnovaRT6k UPS"""
def main():
from pprint import pprint
innova = InnovaRT6K('COM1')
# pprint(innova.get_status())
pprint(innova.ups_rating_information())
if __name__ == '__main__':
main()