Compare commits
6 Commits
0.1.1
...
feature/dr
| Author | SHA1 | Date | |
|---|---|---|---|
|
89747067b8
|
|||
| 2999f73668 | |||
| cf0195fd18 | |||
| 9895fff59a | |||
| 0a507d0953 | |||
| 1093b2283d |
34
.drone.yml
Normal file
34
.drone.yml
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
platform: linux/arm
|
||||||
|
|
||||||
|
workspace:
|
||||||
|
base: /home/builder/package
|
||||||
|
path: /
|
||||||
|
|
||||||
|
clone:
|
||||||
|
default:
|
||||||
|
image: plugins/git:linux-arm
|
||||||
|
depth: 50
|
||||||
|
|
||||||
|
pipeline:
|
||||||
|
build:
|
||||||
|
image: openpdu/builder:3.7
|
||||||
|
environment:
|
||||||
|
- REPODEST=/home/builder/package
|
||||||
|
secrets:
|
||||||
|
- source: abuild_ssh_key
|
||||||
|
target: RSA_PRIVATE_KEY
|
||||||
|
- source: abuild_ssh_key_name
|
||||||
|
target: RSA_PRIVATE_KEY_NAME
|
||||||
|
|
||||||
|
gitea_release:
|
||||||
|
image: plugins/gitea-release:linux-arm
|
||||||
|
files: builder/armhf/*.apk
|
||||||
|
checksum:
|
||||||
|
- md5
|
||||||
|
- sha1
|
||||||
|
- sha256
|
||||||
|
- sha512
|
||||||
|
secrets: [ gitea_token ]
|
||||||
|
base_url: https://git.asperti.com
|
||||||
|
when:
|
||||||
|
event: tag
|
||||||
2
APKBUILD
2
APKBUILD
@@ -1,7 +1,7 @@
|
|||||||
# Contributor: Paolo Asperti <paolo@asperti.com>
|
# Contributor: Paolo Asperti <paolo@asperti.com>
|
||||||
# Maintainer: Paolo Asperti <paolo@asperti.com>
|
# Maintainer: Paolo Asperti <paolo@asperti.com>
|
||||||
pkgname=openpdu
|
pkgname=openpdu
|
||||||
pkgver=0.1.1
|
pkgver=0.1.2
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="OpenPDU project - main binary"
|
pkgdesc="OpenPDU project - main binary"
|
||||||
url="https://github.com/openpdu/openpdu"
|
url="https://github.com/openpdu/openpdu"
|
||||||
|
|||||||
91
openpdu
91
openpdu
@@ -11,9 +11,9 @@ import time
|
|||||||
import ConfigParser
|
import ConfigParser
|
||||||
import json as JSON
|
import json as JSON
|
||||||
|
|
||||||
VERSION = '0.1.1'
|
VERSION = '0.1.2'
|
||||||
boardsDefaults = {}
|
boardsDefaults = {'inverted':False}
|
||||||
outletsDefaults = {'description': 'Generic outlet','startpower':0}
|
outletsDefaults = {'description': 'Generic outlet','startpower':False}
|
||||||
_boards = []
|
_boards = []
|
||||||
_outlets = []
|
_outlets = []
|
||||||
|
|
||||||
@@ -101,6 +101,54 @@ def getpower(outlet, json=False):
|
|||||||
return JSON.dumps({'powerstatus':out,'outlet':outlet}) if json else msg
|
return JSON.dumps({'powerstatus':out,'outlet':outlet}) if json else msg
|
||||||
|
|
||||||
|
|
||||||
|
class BoardDummy(object):
|
||||||
|
channels = []
|
||||||
|
|
||||||
|
def __init__(self, boardnum, channels=None, filename=None):
|
||||||
|
self.boardnum = boardnum
|
||||||
|
if channels is None:
|
||||||
|
self.channels = 1
|
||||||
|
else:
|
||||||
|
self.channels = int(channels)
|
||||||
|
self.parser = ConfigParser.SafeConfigParser()
|
||||||
|
self.filename = filename
|
||||||
|
if os.path.isfile(filename) and os.access(filename, os.R_OK):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
with open(self.filename, 'wb') as theFile:
|
||||||
|
self.parser.add_section('STATUS')
|
||||||
|
for c in range(0,self.channels):
|
||||||
|
self.parser.set('STATUS', 'channel%s' % c, '0')
|
||||||
|
self.parser.write(theFile)
|
||||||
|
|
||||||
|
def toJSON(self):
|
||||||
|
return {'boardnum':self.boardnum,'type':'dummy','channels':self.channels}
|
||||||
|
|
||||||
|
def toSTR(self):
|
||||||
|
return ' Board %s\n Type: dummy\n Channels: %s\n\n' % (self.boardnum,self.channels)
|
||||||
|
|
||||||
|
def setpower(self, channel, power):
|
||||||
|
self.parser.read(self.filename)
|
||||||
|
p = '1' if power else '0'
|
||||||
|
s = self.parser.set('STATUS', 'channel%s' % channel, p)
|
||||||
|
with open(self.filename, 'wb') as theFile:
|
||||||
|
return self.parser.write(theFile)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getpower(self, channel):
|
||||||
|
self.parser.read(self.filename)
|
||||||
|
s = self.parser.get('STATUS', 'channel%s' % channel)
|
||||||
|
return int(s)==1
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# MCP23008
|
# MCP23008
|
||||||
class BoardI2COut(object):
|
class BoardI2COut(object):
|
||||||
@@ -108,7 +156,7 @@ class BoardI2COut(object):
|
|||||||
next_refresh = 0
|
next_refresh = 0
|
||||||
lifetime_sec = 2
|
lifetime_sec = 2
|
||||||
|
|
||||||
def __init__(self, boardnum, channels=None, address=None, bus=None):
|
def __init__(self, boardnum, channels=None, address=None, bus=None, inverted=False):
|
||||||
self.boardnum = boardnum
|
self.boardnum = boardnum
|
||||||
if channels is None:
|
if channels is None:
|
||||||
self.channels = 0
|
self.channels = 0
|
||||||
@@ -122,6 +170,7 @@ class BoardI2COut(object):
|
|||||||
self.bus = 1
|
self.bus = 1
|
||||||
else:
|
else:
|
||||||
self.bus = bus
|
self.bus = bus
|
||||||
|
self.inverted = inverted
|
||||||
if not glob.glob('/dev/i2c*'):
|
if not glob.glob('/dev/i2c*'):
|
||||||
raise OSError('Cannot access I2C. Please ensure I2C is enabled')
|
raise OSError('Cannot access I2C. Please ensure I2C is enabled')
|
||||||
|
|
||||||
@@ -135,6 +184,8 @@ class BoardI2COut(object):
|
|||||||
old_data = data = self.getdata()
|
old_data = data = self.getdata()
|
||||||
mask = 1 << channel
|
mask = 1 << channel
|
||||||
data &= ~mask
|
data &= ~mask
|
||||||
|
if self.inverted:
|
||||||
|
power = not power
|
||||||
if power:
|
if power:
|
||||||
data |= mask
|
data |= mask
|
||||||
if old_data != data:
|
if old_data != data:
|
||||||
@@ -144,7 +195,8 @@ class BoardI2COut(object):
|
|||||||
def getpower(self, channel):
|
def getpower(self, channel):
|
||||||
data = self.getdata()
|
data = self.getdata()
|
||||||
d = ( data >> channel ) & 1
|
d = ( data >> channel ) & 1
|
||||||
return d == 1
|
c = 0 if self.inverted else 1
|
||||||
|
return d == c
|
||||||
|
|
||||||
def getdata(self):
|
def getdata(self):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
@@ -160,12 +212,13 @@ class BoardI2COut(object):
|
|||||||
class BoardGpioOut(object):
|
class BoardGpioOut(object):
|
||||||
gpios = []
|
gpios = []
|
||||||
|
|
||||||
def __init__(self, boardnum, channels=None, gpios=None):
|
def __init__(self, boardnum, channels=None, gpios=None, inverted=False):
|
||||||
self.boardnum = boardnum
|
self.boardnum = boardnum
|
||||||
if channels is None:
|
if channels is None:
|
||||||
self.channels = 0
|
self.channels = 0
|
||||||
else:
|
else:
|
||||||
self.channels = int(channels)
|
self.channels = int(channels)
|
||||||
|
self.inverted = inverted
|
||||||
if not isinstance(gpios, list):
|
if not isinstance(gpios, list):
|
||||||
print 'No gpios specified for gpio board %s' % self.boardnum
|
print 'No gpios specified for gpio board %s' % self.boardnum
|
||||||
if len(gpios) != self.channels:
|
if len(gpios) != self.channels:
|
||||||
@@ -182,14 +235,20 @@ class BoardGpioOut(object):
|
|||||||
io = self.gpios[channel]
|
io = self.gpios[channel]
|
||||||
fn = '/sys/class/gpio/gpio%s/value' % io
|
fn = '/sys/class/gpio/gpio%s/value' % io
|
||||||
f = open(fn,'w')
|
f = open(fn,'w')
|
||||||
out = '0' if power else '1'
|
if self.inverted:
|
||||||
|
power = not power
|
||||||
|
out = '1' if power else '0'
|
||||||
return f.write(out)
|
return f.write(out)
|
||||||
|
|
||||||
def getpower(self, channel):
|
def getpower(self, channel):
|
||||||
io = self.gpios[channel]
|
io = self.gpios[channel]
|
||||||
fn = '/sys/class/gpio/gpio%s/value' % io
|
fn = '/sys/class/gpio/gpio%s/value' % io
|
||||||
f = open(fn,'r')
|
f = open(fn,'r')
|
||||||
return int(f.read()) == 0
|
e = f.read()
|
||||||
|
power = int('0'+e) == 1
|
||||||
|
if self.inverted:
|
||||||
|
power = not power
|
||||||
|
return power
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
for gpio in self.gpios:
|
for gpio in self.gpios:
|
||||||
@@ -250,18 +309,22 @@ for s in boardsConfigParser.sections():
|
|||||||
if re.match('^board.*',s):
|
if re.match('^board.*',s):
|
||||||
bType = boardsConfigParser.get(s, 'type')
|
bType = boardsConfigParser.get(s, 'type')
|
||||||
num = int(re.sub(r'^board','',s))
|
num = int(re.sub(r'^board','',s))
|
||||||
|
inverted = int('0' + boardsConfigParser.get(s, 'inverted')) == 1
|
||||||
|
channels = int(boardsConfigParser.get(s, 'channels'))
|
||||||
if bType=='gpio-out':
|
if bType=='gpio-out':
|
||||||
channels = int(boardsConfigParser.get(s, 'channels'))
|
|
||||||
gpios = []
|
gpios = []
|
||||||
for g in range(0,channels):
|
for g in range(0,channels):
|
||||||
gpios.append(int(boardsConfigParser.get(s, 'channel%s' % g)))
|
gpios.append(int(boardsConfigParser.get(s, 'channel%s' % g)))
|
||||||
b = BoardGpioOut(boardnum=num, channels=channels, gpios=gpios)
|
b = BoardGpioOut(boardnum=num, channels=channels, gpios=gpios, inverted=inverted)
|
||||||
_boards.append(b)
|
_boards.append(b)
|
||||||
elif bType=='i2c-out':
|
elif bType=='i2c-out':
|
||||||
channels = int(boardsConfigParser.get(s, 'channels'))
|
|
||||||
address = boardsConfigParser.get(s, 'address')
|
address = boardsConfigParser.get(s, 'address')
|
||||||
bus = boardsConfigParser.get(s, 'bus')
|
bus = boardsConfigParser.get(s, 'bus')
|
||||||
b = BoardI2COut(boardnum=num, channels=channels, address=address, bus=bus)
|
b = BoardI2COut(boardnum=num, channels=channels, address=address, bus=bus, inverted=inverted)
|
||||||
|
_boards.append(b)
|
||||||
|
elif bType=='dummy':
|
||||||
|
filename = boardsConfigParser.get(s, 'filename')
|
||||||
|
b = BoardDummy(boardnum=num, channels=channels, filename=filename)
|
||||||
_boards.append(b)
|
_boards.append(b)
|
||||||
|
|
||||||
outletsConfigParser = ConfigParser.SafeConfigParser(defaults=outletsDefaults)
|
outletsConfigParser = ConfigParser.SafeConfigParser(defaults=outletsDefaults)
|
||||||
@@ -274,7 +337,7 @@ for s in outletsConfigParser.sections():
|
|||||||
description = outletsConfigParser.get(s, 'description')
|
description = outletsConfigParser.get(s, 'description')
|
||||||
boardnum = outletsConfigParser.get(s, 'board')
|
boardnum = outletsConfigParser.get(s, 'board')
|
||||||
channel = outletsConfigParser.get(s, 'channel')
|
channel = outletsConfigParser.get(s, 'channel')
|
||||||
startpower = outletsConfigParser.get(s, 'startpower') == 1
|
startpower = int('0' + outletsConfigParser.get(s, 'startpower')) == 1
|
||||||
o = Outlet(outletnum=num, boardnum=boardnum, channel=channel, startpower=startpower)
|
o = Outlet(outletnum=num, boardnum=boardnum, channel=channel, startpower=startpower)
|
||||||
o.description = description
|
o.description = description
|
||||||
_outlets.append(o)
|
_outlets.append(o)
|
||||||
@@ -282,7 +345,7 @@ for s in outletsConfigParser.sections():
|
|||||||
|
|
||||||
|
|
||||||
parser = argh.ArghParser()
|
parser = argh.ArghParser()
|
||||||
parser.add_commands([setpower, getpower, outlets, boards, initboards, version])
|
parser.add_commands([setpower, getpower, outlets, boards, initboards, version, initoutlets])
|
||||||
|
|
||||||
# dispatching:
|
# dispatching:
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user