Files
SC200/sc200-pull.py
2016-12-16 14:17:19 +08:00

345 lines
9.5 KiB
Python
Executable File

#!/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))
Settings = [
'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'
] + \
['Alarm-Name:' + repr(x) for x in range(59)] + \
['Alarm-Severity:' + repr(x) for x in range(59)]
def Setup():
db.execute('''CREATE TABLE SettingsValues (
IP TEXT,
SettingsID TEXT,
Value TEXT)''')
#db.execute('''CREATE TABLE Settings (
#ID INTEGER PRIMARY KEY,
#Name TEXT UNIQUE)''')
#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(Settings)
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])
#print((list(zip(Settings, Row[1][1:]))))
c.executemany('INSERT INTO SettingsValues VALUES ( \'%s\', ?, ?)'
% Row[1][0],
list(zip(Settings, Row[1][1:])))
db.commit()
def Output():
c = db.cursor()
fieldNames = ['IP'] + Settings
with open('/tmp/sc200.csv', 'w', newline='') as outFile:
csvWriter = csv.DictWriter(outFile, fieldnames=fieldNames,
delimiter=',', quotechar='"',
quoting=csv.QUOTE_MINIMAL)
csvWriter.writeheader()
c.execute('''SELECT DISTINCT IP FROM SettingsValues ORDER BY IP''')
for Row in c:
IP = Row
print((('''SELECT SettingsID, Value
FROM SettingsValues WHERE IP = \'%s\'''' % IP)))
row = c.execute('''SELECT SettingsID, Value
FROM SettingsValues WHERE IP = \'%s\'''' % IP)
print(((row)))
outFile.close()
#csvWriter.writerow()
#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 SettingsValues 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) 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)
Loader()
Output()
sys.exit(0)