Refactored code. Changing SQL and CSV formats.

This commit is contained in:
Adrian Woodley
2016-12-15 16:37:01 +08:00
parent c1770389f4
commit 3b664d0dcc
11 changed files with 693179 additions and 2 deletions

159788
csv Normal file

File diff suppressed because it is too large Load Diff

24841
http.client Normal file

File diff suppressed because it is too large Load Diff

159788
queue Normal file

File diff suppressed because it is too large Load Diff

321
sc200-pull.py Executable file
View File

@@ -0,0 +1,321 @@
#!/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()
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)

302
sc200-push.sh Executable file
View File

@@ -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)

View File

@@ -1,5 +1,5 @@
{
"mainFile": "sc200.py",
"mainFile": "sc200-pull.py",
"use-tabs": false,
"venv": "",
"relatedProjects": [],

159788
socket Normal file

File diff suppressed because it is too large Load Diff

159788
sqlite3 Normal file

File diff suppressed because it is too large Load Diff

3720
sys Normal file

File diff suppressed because it is too large Load Diff

24841
threading Normal file

File diff suppressed because it is too large Load Diff