#!/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)