commit c1770389f413aa7d9ba8910e326e0509b1e63daf Author: Adrian Woodley Date: Thu Dec 15 12:52:35 2016 +0800 Initial commit diff --git a/sc200-smart-alarm-set.py b/sc200-smart-alarm-set.py new file mode 100755 index 0000000..688f3ae --- /dev/null +++ b/sc200-smart-alarm-set.py @@ -0,0 +1,132 @@ +#!/usr/bin/python3 +from netaddr import IPNetwork +#from netaddr import IPAddress +from xmlrpc.client import ServerProxy +import socket +import queue +import threading +import sys +import http.client + +WORKERS = 10 + +if len(sys.argv) == 1: + Nets = [ + '10.250.48.0/27', + '10.250.48.32/27', + '10.250.48.64/27', + '10.250.48.96/27', + '10.250.48.128/27', + '10.250.48.160/27', + '10.250.49.0/27', + '10.250.49.32/27', + '10.250.49.64/27', + '10.250.49.128/27', + '10.250.49.160/27', + '10.250.50.0/27', + '10.250.50.32/27', + '10.250.50.65/27', + '10.250.50.96/27', + '10.250.50.128/27', + '10.250.50.160/27', + '10.250.50.192/27', + '10.250.50.224/27', + '10.250.51.0/27', + '10.250.51.32/27', + '10.250.51.64/27', + '10.250.51.96/27', + '10.250.51.128/27', + '10.250.52.0/27', + '10.250.52.32/27', + '10.250.52.64/27', + '10.250.52.96/27', + '10.250.52.128/27', + '10.250.52.160/27', + '10.250.52.192/27' + ] +else: + Nets = sys.argv[1:] + + +def GetStatusCode(host, path="/"): + try: + conn = http.client.HTTPConnection(host) + conn.request("GET", path) + return conn.getresponse().status + except Exception: + return None + + +class Worker(threading.Thread): + + def __init__(self, IPs): + self.__IPs = IPs + self.parent = threading.current_thread() + threading.Thread.__init__(self) + + def run(self): + retry = False + socket.setdefaulttimeout(5) + while 1: + IP = self.__IPs.get() + + if IP is None: + break + + if GetStatusCode(str(IP), "/languages") == 200: + print((self.getName() + ' processing: ' + str(IP))) + while True: + proxy = ServerProxy('http://%s/xmlrpc' % IP) + try: + Values = proxy.db.set({ +'Smart-Alarm-Name:1': 'Solar', +'Smart-Alarm-Severity:1': 3, +'Smart-Alarm-DO-Mapping-A:1': 1, +'Smart-Alarm-Send-Trap:1': 1, +'Source-Alarm-Status:1': 1, +'Source-Alarm-Mapping:1': 1, +'Source-Schedule-Mapping:1': 1, +'Source-Schedule-Status:1': 1, +'Smart-Alarm-Operator:1': 0, +'Source-Schedule-First-Date-Time:1': 1481673600, +'Source-Schedule-Duration:1': 480, +'Alarm-Severity': 5, +'Alarm-DO-Mapping-A': 0, +'Alarm-Send-Trap': 0, +'Low-Float-Threshold': 50 + }) + except socket.timeout: + retry = True + continue + + if retry: + retry = False + else: + break + print((self.getName() + ':' + str(IP) + str(Values))) + else: + print((self.getName() + ' skipping: ' + str(IP))) + + +IPs = queue.Queue(0) + +for i in range(WORKERS): + Worker(IPs).start() + +for SubNet in Nets: + Net = IPNetwork(SubNet) + + for IP in Net: + if ((IP != Net.network and IP != Net.broadcast) or + Net.broadcast is None): + #print(('Queued: ' + str(IP))) + IPs.put(IP) + +for i in range(WORKERS): + IPs.put(None) + +if threading.current_thread() is not threading.main_thread(): + sys.exit(0) + +sys.exit(0) + diff --git a/sc200-temp.py b/sc200-temp.py new file mode 100755 index 0000000..f9c1469 --- /dev/null +++ b/sc200-temp.py @@ -0,0 +1,80 @@ +#!/usr/bin/python3 +from xmlrpc.client import ServerProxy +import sys +import http.client + +IP = sys.argv[1] +proxy = ServerProxy('http://%s/xmlrpc' % IP) + + +def GetStatusCode(host, path="/"): + try: + conn = http.client.HTTPConnection(host) + conn.request("GET", path) + return conn.getresponse().status + except Exception: + return None + + +def index(): + if GetStatusCode(str(IP), "/languages") == 200: + Rectifiers = proxy.db.get(['Number-Of-Registered-Rectifiers'])[0] + print(('Batteries')) + for num in range(1, Rectifiers): + print(('Rectifier-{0}'.format(num))) + + +def num_indexes(): + if GetStatusCode(str(IP), "/languages") == 200: + Rectifiers = proxy.db.get(['Number-Of-Registered-Rectifiers'])[0] + Rectifiers += 1 + print((Rectifiers)) + + +def get(index): + if GetStatusCode(str(IP), "/languages") == 200: + if index == 'Batteries': + query = 'Battery-Temperature' + print((proxy.db.get([query])[0])) + elif index[:10] == 'Rectifier-': + query = 'Rectifier-Heatsink-Temperature:{0}-{0}'.format(index[10:]) + print((proxy.db.get([query])[0][0])) + else: + return + + + +def query(): + if GetStatusCode(str(IP), "/languages") == 200: + Rectifiers = proxy.db.get(['Number-Of-Registered-Rectifiers'])[0] + Values = proxy.db.get([ + 'Battery-Temperature', + 'Rectifier-Heatsink-Temperature:1-%s' % Rectifiers + ]) + + if len(Values) > 0: + outString = "" + outString += ("Batteries:%s" % Values[0]) + numRect = 1 + for Rectifier in Values[1]: + if type(Rectifier) is float: + outString += (" Rectifier-{0}:{1}".format(numRect, + Rectifier)) + elif type(Rectifier) is dict: + outString += (" Rectifier-{0}:{1}".format(numRect, + Values[1][Rectifier['repeatLast']])) + numRect += 1 + print(outString) + +if len(sys.argv) > 2: + if sys.argv[2] == 'index': + index() + elif sys.argv[2] == 'num_indexes': + num_indexes() + elif sys.argv[2] == 'get' and len(sys.argv) == 4: + get(sys.argv[3]) + elif sys.argv[2] == 'query': + query() + +sys.exit(0) + diff --git a/sc200.nja b/sc200.nja new file mode 100644 index 0000000..6fecbf2 --- /dev/null +++ b/sc200.nja @@ -0,0 +1,29 @@ +{ + "mainFile": "sc200.py", + "use-tabs": false, + "venv": "", + "relatedProjects": [], + "name": "SC200", + "license": "GNU General Public License v3", + "url": "", + "pythonPath": "python3", + "preExecScript": "", + "additional_builtins": [], + "programParams": "", + "indentation": 4, + "PYTHONPATH": "", + "supported-extensions": [ + ".py", + ".html", + ".jpg", + ".png", + ".ui", + ".css", + ".json", + ".js", + ".ini" + ], + "project-type": "Import from sources", + "postExecScript": "", + "description": "" +} \ No newline at end of file diff --git a/sc200.py b/sc200.py new file mode 100755 index 0000000..fcb8167 --- /dev/null +++ b/sc200.py @@ -0,0 +1,302 @@ +#!/usr/bin/python3 +from netaddr import IPNetwork +#from netaddr import IPAddress +from xmlrpc.client import ServerProxy +import sqlite3 +import socket +import csv +import queue +import threading +import sys +import http.client + +WORKERS = 10 + +if len(sys.argv) == 1: + Nets = [ + '10.250.48.0/27', + '10.250.48.32/27', + '10.250.48.64/27', + '10.250.48.96/27', + '10.250.48.128/27', + '10.250.48.160/27', + '10.250.49.0/27', + '10.250.49.32/27', + '10.250.49.64/27', + '10.250.49.128/27', + '10.250.49.160/27', + '10.250.50.0/27', + '10.250.50.32/27', + '10.250.50.65/27', + '10.250.50.96/27', + '10.250.50.128/27', + '10.250.50.160/27', + '10.250.50.192/27', + '10.250.50.224/27', + '10.250.51.0/27', + '10.250.51.32/27', + '10.250.51.64/27', + '10.250.51.96/27', + '10.250.51.128/27', + '10.250.52.0/27', + '10.250.52.32/27', + '10.250.52.64/27', + '10.250.52.96/27', + '10.250.52.128/27', + '10.250.52.160/27', + '10.250.52.192/27' + ] +else: + Nets = sys.argv[1:] + +#Nets = [ + #'10.250.48.0/27'] + +#print((Nets)) + + +def Setup(): + db.execute('''CREATE TABLE SC200 ( + IP text PRIMARY KEY, + SiteName text, + SiteNotes text, + SerialNumber text, + FloatVoltage float, + OperatingVoltage float, + BatteryCapacity int, + ACRectifierCurrentLimit int, + HighFloatThreshold float, + EnableActiveVoltageControl bool, + EnableTemperatureCompensation bool, + TemperatureCompensationSlope float, + TemperatureCompensationReferenceTemperature float, + TemperatureCompensationUpperLimit float, + TemperatureCompensationLowerLimit float, + EnableEqualize bool, + EqualizeVoltage float, + EqualizeDuration int, + EnableFastCharge bool, + FastChargeVoltage float, + FastChargeVoltageThreshold float, + FastChargeAmpereHourThreshold int, + FastChargeRechargePercentage int, + FastChargeMaximumDuration int, + FastChargeAmpereHourStopThreshold int, + EnableBatterCurrentLimit bool, + BCLLimit int, + EnableBatterTest bool, + BatteryTestDuration int, + BatteryTestTerminationVoltage float, + LVDDisconnectVoltage float, + LVDReconnectVoltage float, + NumberOfRegisteredRectifiers int, + NumberOfRectifiersFailed int + )''') + + SQL = '''CREATE TABLE AlarmNames ( + SiteIP text primary key''' + for x in range(59): + SQL = SQL + ', Alarm' + repr(x) + ' text' + SQL = SQL + ')' + + db.execute(SQL) + + SQL = '''CREATE TABLE AlarmSeverities ( + SiteIP text primary key''' + for x in range(59): + SQL = SQL + ', Alarm' + repr(x) + ' int' + SQL = SQL + ')' + + db.execute(SQL) + + +def GetStatusCode(host, path="/"): + try: + conn = http.client.HTTPConnection(host) + conn.request("GET", path) + return conn.getresponse().status + except Exception: + return None + + +class Worker(threading.Thread): + + def __init__(self, IPs, Results): + self.__IPs = IPs + self.__Results = Results + self.parent = threading.current_thread() + threading.Thread.__init__(self) + + def run(self): + retry = False + socket.setdefaulttimeout(5) + #print ('Started') + while 1: + IP = self.__IPs.get() + #print((self.getName())) + if IP is None: + self.__Results.put(None) + #print('Exiting') + break + + #s = socket.socket() + #if s.connect_ex((str(IP), 80)) == 0: + if GetStatusCode(str(IP), "/languages") == 200: + print((self.getName() + ' processing: ' + str(IP))) + #print(('Socket OK: %s' % IP)) + #print(('%s' % IP)) + while True: + proxy = ServerProxy('http://%s/xmlrpc' % IP) + try: + Values = proxy.db.get([ + 'Site-Name', + 'Site-Notes', + 'Serial-Number', + 'Float-Voltage', + 'Operating-Voltage', + 'Battery-Capacity', + 'AC-Rectifier-Current-Limit', + 'High-Float-Threshold', + 'Enable-Active-Voltage-Control', + 'Enable-Temperature-Compensation', + 'Temperature-Compensation-Slope', + 'Temperature-Compensation-Reference-Temperature', + 'Temperature-Compensation-Upper-Limit', + 'Temperature-Compensation-Lower-Limit', + 'Enable-Equalize', + 'Equalize-Voltage', + 'Equalize-Duration', + 'Enable-Fast-Charge', + 'Fast-Charge-Voltage', + 'Fast-Charge-Voltage-Threshold', + 'Fast-Charge-Ampere-Hour-Threshold', + 'Fast-Charge-Recharge-Percentage', + 'Fast-Charge-Maximum-Duration', + 'Fast-Charge-Ampere-Hour-Stop-Threshold', + 'Enable-Battery-Current-Limit', + 'BCL-Limit', + 'Enable-Battery-Test', + 'Battery-Test-Duration', + 'Battery-Test-Termination-Voltage', + 'LVD-Disconnect-Voltage:1', + 'LVD-Reconnect-Voltage:1', + 'Number-Of-Registered-Rectifiers', + 'Number-Of-Rectifiers-Failed' + ]) + except socket.timeout: + retry = True + continue + + if retry: + retry = False + else: + break + + if len(Values) > 0: + Values.insert(0, str(IP)) + self.__Results.put(['SC200', Values]) + + AlarmNames = ['Alarm-Name:' + repr(x) for x in range(59)] + while True: + try: + Values = proxy.db.get(AlarmNames) + except socket.timeout: + retry = True + continue + + if retry: + retry = False + else: + break + + Values.insert(0, str(IP)) + + self.__Results.put(['AlarmNames', Values]) + + AlarmSeverities = ['Alarm-Severity:' + repr(x) + for x in range(59)] + Values = proxy.db.get(AlarmSeverities) + + Values.insert(0, str(IP)) + + self.__Results.put(['AlarmSeverities', Values]) + #s.close() + else: + print((self.getName() + ' skipping: ' + str(IP))) + + +def Loader(): + Count = WORKERS + c = db.cursor() + + while 1: + Row = Results.get() + if Row is None: + if Count > 1: + Count -= 1 + print(Count) + else: + break + else: + print(('Loading: %s %s' % (Row[1][0], Row[0]))) + SQL = 'INSERT INTO %s VALUES (' % Row[0] + for i in Row[1]: + SQL += '?,' + SQL = SQL[:-1] + SQL += ')' + + c.execute(SQL, Row[1]) + db.commit() + + +def Output(): + c = db.cursor() + with open('/tmp/sc200.csv', 'w', newline='') as outFile: + csvWriter = csv.writer(outFile, delimiter=',', quotechar='"', + quoting=csv.QUOTE_MINIMAL) + c.execute('''SELECT * FROM SC200 ORDER BY IP''') + csvWriter.writerow([col[0] for col in c.description]) + for row in c: + csvWriter.writerow(row) + outFile.close() + + with open('/tmp/sc200-alarms.csv', 'w', newline='') as outFile: + csvWriter = csv.writer(outFile, delimiter=',', quotechar='"', + quoting=csv.QUOTE_MINIMAL) + c.execute('''SELECT * FROM AlarmNames LIMIT 1''') + for row in c: + csvWriter.writerow(row) + c.execute('''SELECT * FROM AlarmSeverities''') + for row in c: + csvWriter.writerow(row) + outFile.close() + +db = sqlite3.connect(':memory:') +#db = sqlite3.connect('/tmp/sc200.db') + +Setup() +IPs = queue.Queue(0) +Results = queue.Queue(0) + +for i in range(WORKERS): + Worker(IPs, Results).start() + +for SubNet in Nets: + Net = IPNetwork(SubNet) + + for IP in Net: + if IP != Net.network and IP != Net.broadcast: + #print(('Queued: ' + str(IP))) + IPs.put(IP) + +for i in range(WORKERS): + IPs.put(None) + +if threading.current_thread() is not threading.main_thread(): + sys.exit(0) + +Loader() +Output() + +sys.exit(0) +