initial import
This commit is contained in:
commit
e1f80c4f7d
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
packages/
|
||||||
|
*.apk
|
||||||
|
.on-save.json
|
26
APKBUILD
Normal file
26
APKBUILD
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Contributor: Paolo Asperti <paolo@asperti.com>
|
||||||
|
# Maintainer: Paolo Asperti <paolo@asperti.com>
|
||||||
|
pkgname=openpdu
|
||||||
|
pkgver=0.1
|
||||||
|
pkgrel=1
|
||||||
|
pkgdesc="OpenPDU project - main binary"
|
||||||
|
url="https://github.com/paspo/installinux"
|
||||||
|
arch="noarch"
|
||||||
|
license="GPL2"
|
||||||
|
depends="python, py-argh, apk-cron"
|
||||||
|
makedepends=""
|
||||||
|
install="openpdu.post-install"
|
||||||
|
subpackages=""
|
||||||
|
source=""
|
||||||
|
|
||||||
|
build() {
|
||||||
|
:
|
||||||
|
}
|
||||||
|
|
||||||
|
package() {
|
||||||
|
mkdir -p "$pkgdir"
|
||||||
|
install -Dm644 etc/openpdu/openpdu.conf "$pkgdir"/etc/openpdu/openpdu.conf
|
||||||
|
install -Dm755 etc/local.d/openpdu.start "$pkgdir"/etc/local.d/openpdu.start
|
||||||
|
|
||||||
|
install -Dm755 openpdu "$pkgdir"/usr/sbin/openpdu
|
||||||
|
}
|
21
etc/local.d/openpdu.start
Normal file
21
etc/local.d/openpdu.start
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
OUT1=1
|
||||||
|
OUT2=2
|
||||||
|
OUT3=3
|
||||||
|
OUT4=7
|
||||||
|
OUT5=8
|
||||||
|
OUT6=9
|
||||||
|
OUT7=11
|
||||||
|
OUT8=12
|
||||||
|
|
||||||
|
for n in $(seq 1 8) ; do
|
||||||
|
eval "echo \$OUT$n > /sys/class/gpio/export"
|
||||||
|
eval "echo out > /sys/class/gpio/gpio\$OUT$n/direction"
|
||||||
|
|
||||||
|
# 0=on 1=off :)
|
||||||
|
VAL=0
|
||||||
|
|
||||||
|
eval "echo $VAL > /sys/class/gpio/gpio\$OUT$n/value"
|
||||||
|
sleep 0.2
|
||||||
|
done
|
22
etc/openpdu/openpdu.conf
Normal file
22
etc/openpdu/openpdu.conf
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
[DEFAULT]
|
||||||
|
|
||||||
|
|
||||||
|
# EXAMPLE GPIO BOARD
|
||||||
|
# [board0]
|
||||||
|
# out0 = 1
|
||||||
|
# out1 = 2
|
||||||
|
# out2 = 3
|
||||||
|
# out3 = 7
|
||||||
|
# out4 = 8
|
||||||
|
# out5 = 9
|
||||||
|
# out6 = 11
|
||||||
|
# out7 = 12
|
||||||
|
# type = gpio-out
|
||||||
|
# channels = 8
|
||||||
|
|
||||||
|
|
||||||
|
# EXAMPLE I2C BOARD
|
||||||
|
# [board1]
|
||||||
|
# type = i2c-out
|
||||||
|
# address = 20
|
||||||
|
# channels = 8
|
195
openpdu
Executable file
195
openpdu
Executable file
@ -0,0 +1,195 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import argh
|
||||||
|
from argh import arg
|
||||||
|
import re
|
||||||
|
import ConfigParser
|
||||||
|
import json as JSON
|
||||||
|
|
||||||
|
VERSION = 0.1
|
||||||
|
defaults = {}
|
||||||
|
boards = []
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def version():
|
||||||
|
'show program version and quit'
|
||||||
|
return 'OpenPDU version %s - Copyright (C) 2018 by Paolo Asperti.' % VERSION
|
||||||
|
|
||||||
|
@arg('-j', '--json', help="output in json")
|
||||||
|
def dumpcfg(json=False):
|
||||||
|
'dump configuration'
|
||||||
|
if json:
|
||||||
|
b = [board.toJSON() for board in boards]
|
||||||
|
return JSON.dumps({'boards':b})
|
||||||
|
else:
|
||||||
|
b = ''
|
||||||
|
for board in boards:
|
||||||
|
b += board.toSTR()
|
||||||
|
return '\nBoards:\n' + b
|
||||||
|
|
||||||
|
|
||||||
|
@arg("board", help="board number")
|
||||||
|
@arg("out", help="out number")
|
||||||
|
@arg("onoff", help="1=on [everything else]=off")
|
||||||
|
@arg('-j', '--json', help="output in json")
|
||||||
|
def setpower(board, out, onoff, json=False):
|
||||||
|
'enable or disable power to a socket'
|
||||||
|
b = [b for b in boards if b.boardnum==int(board)]
|
||||||
|
if len(b) != 1:
|
||||||
|
print 'wrong board number: %s' % str(board)
|
||||||
|
sys.exit(1)
|
||||||
|
theBoard = b[0]
|
||||||
|
if int(out)>int(theBoard.channels)-1:
|
||||||
|
print 'wrong out number: %s, board has %s channels (0..%s)' % (str(out),str(theBoard.channels),str(int(theBoard.channels)-1))
|
||||||
|
sys.exit(1)
|
||||||
|
status = (onoff == '1')
|
||||||
|
return theBoard.setpower(int(out),status)
|
||||||
|
|
||||||
|
|
||||||
|
@arg("board", help="board number")
|
||||||
|
@arg("out", help="out number")
|
||||||
|
@arg('-j', '--json', help="output in json")
|
||||||
|
def getpower(board, out, json=False):
|
||||||
|
'get socket power status'
|
||||||
|
b = [b for b in boards if b.boardnum==int(board)]
|
||||||
|
if len(b) != 1:
|
||||||
|
print 'wrong board number: %s' % str(board)
|
||||||
|
sys.exit(1)
|
||||||
|
theBoard = b[0]
|
||||||
|
if int(out)>int(theBoard.channels)-1:
|
||||||
|
print 'wrong out number: %s, board has %s channels (0..%s)' % (str(out),str(theBoard.channels),str(int(theBoard.channels)-1))
|
||||||
|
sys.exit(1)
|
||||||
|
return theBoard.getpower(int(out))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class BoardI2COut(object):
|
||||||
|
def __init__(self, boardnum, channels=None, address=None):
|
||||||
|
self.boardnum = boardnum
|
||||||
|
if channels is None:
|
||||||
|
self.channels = 0
|
||||||
|
else:
|
||||||
|
self.channels = channels
|
||||||
|
if address is None:
|
||||||
|
self.address = 0x20
|
||||||
|
else:
|
||||||
|
self.address = address
|
||||||
|
|
||||||
|
def dumpcfg(json=False):
|
||||||
|
if json:
|
||||||
|
return {'boardnum':self.boardnum,'type':'i2c-out','channels':self.channels,'address':self.address}
|
||||||
|
else:
|
||||||
|
return 'Board %i\nType: i2c-out\nChannels: %i\nAddress: %i' % (self.boardnum,self.channels,self.address)
|
||||||
|
|
||||||
|
def toJSON(self):
|
||||||
|
return {'boardnum':self.boardnum,'type':'i2c-out','channels':self.channels,'address':self.address}
|
||||||
|
|
||||||
|
def toSTR(self):
|
||||||
|
return ' Board %s\n Type: i2c-out\n Channels: %s\n Address: %s\n\n' % (self.boardnum,self.channels,self.address)
|
||||||
|
|
||||||
|
def setpower(self, channel, power):
|
||||||
|
return
|
||||||
|
|
||||||
|
def getpower(self, channel):
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class BoardGpioOut(object):
|
||||||
|
gpios = []
|
||||||
|
|
||||||
|
def __init__(self, boardnum, channels=None, gpios=None):
|
||||||
|
self.boardnum = boardnum
|
||||||
|
if channels is None:
|
||||||
|
self.channels = 0
|
||||||
|
else:
|
||||||
|
self.channels = int(channels)
|
||||||
|
if not isinstance(gpios, list):
|
||||||
|
print 'No gpios specified for gpio board %s' % self.boardnum
|
||||||
|
if len(gpios) != self.channels:
|
||||||
|
print 'Wrong number of gpios specified for gpio board %s' % self.boardnum
|
||||||
|
self.gpios = [int(gpio) for gpio in gpios]
|
||||||
|
|
||||||
|
def dumpcfg(json=False):
|
||||||
|
if json:
|
||||||
|
return {'boardnum':self.boardnum,'type':'gpio-out','channels':self.channels}
|
||||||
|
else:
|
||||||
|
return 'Board %i\nType: gpio-out\nChannels: %i ' % (self.boardnum,self.channels)
|
||||||
|
|
||||||
|
def toJSON(self):
|
||||||
|
return {'boardnum':self.boardnum,'type':'gpio-out','channels':self.channels}
|
||||||
|
|
||||||
|
def toSTR(self):
|
||||||
|
return ' Board %s\n Type: gpio-out\n Channels: %s\n\n' % (self.boardnum,self.channels)
|
||||||
|
|
||||||
|
def setpower(self, channel, power):
|
||||||
|
io = self.gpios[channel]
|
||||||
|
fn = '/sys/class/gpio/gpio%s/value' % io
|
||||||
|
f = open(fn,'w')
|
||||||
|
out = '0' if power else '1'
|
||||||
|
return f.write(out)
|
||||||
|
|
||||||
|
def getpower(self, channel):
|
||||||
|
io = self.gpios[channel]
|
||||||
|
fn = '/sys/class/gpio/gpio%s/value' % io
|
||||||
|
f = open(fn,'r')
|
||||||
|
return int(f.read()) == 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
configParser = ConfigParser.SafeConfigParser(defaults=defaults)
|
||||||
|
|
||||||
|
configFile = '/etc/openpdu/openpdu.conf'
|
||||||
|
if os.path.isfile(configFile) and os.access(configFile, os.R_OK):
|
||||||
|
configParser.read(configFile)
|
||||||
|
|
||||||
|
for s in configParser.sections():
|
||||||
|
if re.match('^board.*',s):
|
||||||
|
bType = configParser.get(s, 'type')
|
||||||
|
num = int(re.sub(r'^board','',s))
|
||||||
|
if bType=='gpio-out':
|
||||||
|
channels = int(configParser.get(s, 'channels'))
|
||||||
|
gpios = []
|
||||||
|
for g in range(0,channels):
|
||||||
|
gpios.append(int(configParser.get(s, 'out%s' % g)))
|
||||||
|
b = BoardGpioOut(boardnum=num, channels=channels, gpios=gpios)
|
||||||
|
boards.append(b)
|
||||||
|
elif bType=='i2c-out':
|
||||||
|
channels = int(configParser.get(s, 'channels'))
|
||||||
|
address = configParser.get(s, 'address')
|
||||||
|
b = BoardI2COut(boardnum=num, channels=channels, address=address)
|
||||||
|
boards.append(b)
|
||||||
|
|
||||||
|
|
||||||
|
parser = argh.ArghParser()
|
||||||
|
parser.add_commands([setpower, getpower, dumpcfg, version])
|
||||||
|
|
||||||
|
# dispatching:
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser.dispatch()
|
3
openpdu.post-install
Normal file
3
openpdu.post-install
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
exit 0
|
Loading…
Reference in New Issue
Block a user