commit df002755ce6af7dc6c4f0373339c3fa53936e5a9 Author: paspo Date: Mon Feb 5 09:47:07 2018 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..8a2455a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +packages/ +*.apk diff --git a/APKBUILD b/APKBUILD new file mode 100755 index 0000000..45d9cf4 --- /dev/null +++ b/APKBUILD @@ -0,0 +1,31 @@ +# Contributor: Paolo Asperti +# Maintainer: Paolo Asperti +pkgname=acf-openpdu +pkgver=0.1 +pkgrel=1 +pkgdesc="Linux installation caching system" +url="https://github.com/paspo/installinux" +arch="noarch" +license="GPL2" +depends="acf-core" +makedepends="" +install="acf-openpdu.post-install" +subpackages="" +source="" + +package() { + mkdir -p "$pkgdir" +} + +package() { +# make DESTDIR=$pkgdir install || return 1 + 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 -Dm644 acf-app/openpdu.menu "$pkgdir"/usr/share/acf/app/openpdu/openpdu.menu + install -Dm644 acf-app/openpdu.roles "$pkgdir"/usr/share/acf/app/openpdu/openpdu.roles + install -Dm644 acf-app/openpdu-controller.lua "$pkgdir"/usr/share/acf/app/openpdu/openpdu-controller.lua + install -Dm644 acf-app/openpdu-model.lua "$pkgdir"/usr/share/acf/app/openpdu/openpdu-model.lua + install -Dm644 acf-app/openpdu-status-html.lsp "$pkgdir"/usr/share/acf/app/openpdu/openpdu-status-html.lsp + +} diff --git a/README b/README new file mode 100755 index 0000000..5b5300c --- /dev/null +++ b/README @@ -0,0 +1,19 @@ +ACF interface for the OpenPDU project. + +Connect the wires, and install this package. +Then go to https://[YOUR_IP], enter user/pass so you can login to ACF. +Under "OpenPDU" you can control your outlets. + +DONE: + * Basic Outlet Status (almost everything hardcoded :( ) + * Power control (ON/OFF) for each socket + * All the sockets are powered ON on boot + * ACF package + +TODO: + * configuration file + * editing socket parameters + * everything else (there's a long list) + +BUGS: + * At the moment, the "Edit" button doesn't work diff --git a/acf-app/openpdu-controller.lua b/acf-app/openpdu-controller.lua new file mode 100755 index 0000000..1cce39b --- /dev/null +++ b/acf-app/openpdu-controller.lua @@ -0,0 +1,19 @@ +-- the openpdu controller + +local mymodule = {} + +mymodule.default_action = "status" + +mymodule.status = function(self) + return self.model.status() +end + +mymodule.poweron = function(self) + return self.handle_form(self, self.model.get_setpower, self.model.setpoweron, self.clientdata, "commitpower", "Action result") +end + +mymodule.poweroff = function(self) + return self.handle_form(self, self.model.get_setpower, self.model.setpoweroff, self.clientdata, "commitpower", "Action result") +end + +return mymodule diff --git a/acf-app/openpdu-model.lua b/acf-app/openpdu-model.lua new file mode 100755 index 0000000..5e9d03d --- /dev/null +++ b/acf-app/openpdu-model.lua @@ -0,0 +1,88 @@ +local mymodule = {} + +posix = require("posix") +fs = require("acf.fs") + +local configpath = "/etc/openpdu/" + +local config = {} +for i=1,8 do + config[i]={socket=i,status="unknown",description="Socket " .. tostring(i),actions={"on","off"}} +end +config[1].gpio=1 +config[2].gpio=2 +config[3].gpio=3 +config[4].gpio=7 +config[5].gpio=8 +config[6].gpio=9 +config[7].gpio=11 +config[8].gpio=12 + +mymodule.status = function() + mymodule.updatestatus() + return cfe({ type="structure", value=config, label="Outlets" }) +end + +mymodule.updatestatus = function() + for i=1,8 do + f = "/sys/class/gpio/gpio" .. tostring(config[i].gpio) .. "/value" + v = fs.read_file(f) + if (tonumber(v) == 0) then + s = "On" + elseif (tonumber(v) == 1) then + s = "Off" + else + s = "unknown (" .. v .. ")" + end + config[i].status = s + end +end + + +mymodule.setpower = function(socket, power, ret) + -- Check to make sure the socket is valid + if (socket == nil) then + ret.errtxt = "Socket cannot be nil" + elseif (not type(socket) == "number") then + ret.errtxt = "Socket must be a number" + elseif (tonumber(socket) < 0) then + ret.errtxt = "Socket must be >0" + elseif (tonumber(socket) > 8) then + ret.errtxt = "Socket must be <=8" + end + + -- If it is, poweron the socket + if (ret.errtxt == nil ) then + f = "/sys/class/gpio/gpio" .. tostring(config[tonumber(socket)].gpio) .. "/value" + if (power == 1) then + ret.descr = "Socket " .. tostring(socket) .. " Powered ON" + p = "0" + else + ret.descr = "Socket " .. tostring(socket) .. " Powered OFF" + p = "1" + end + v = fs.write_file(f, p) + return ret + end + + return ret +end + + + +mymodule.get_setpower = function(self, clientdata) + local socket = cfe({label="Socket", value=clientdata.socket or ""}) + return cfe({ type="group", label="Set Socket Power state", value={socket=socket} }) +end + +mymodule.setpoweron = function(self, r) + mymodule.setpower(r.value.socket.value, 1, r) + return r +end + +mymodule.setpoweroff = function(self, r) + mymodule.setpower(r.value.socket.value, 0, r) + return r +end + +return mymodule diff --git a/acf-app/openpdu-status-html.lsp b/acf-app/openpdu-status-html.lsp new file mode 100755 index 0000000..22914cd --- /dev/null +++ b/acf-app/openpdu-status-html.lsp @@ -0,0 +1,58 @@ +<% local view, viewlibrary, page_info, session = ... %> +<% htmlviewfunctions = require("htmlviewfunctions") %> +<% html = require("acf.html") %> + + + + + + + +<% htmlviewfunctions.displaycommandresults({"edit", "startstop", "poweron", "poweroff"}, session) %> + +<% local header_level = htmlviewfunctions.displaysectionstart(view, page_info) %> + + + + + + <% if viewlibrary.check_permission("edit") or viewlibrary.check_permission("power") then %> + + <% end %> + + +<% +local redir = cfe({type="hidden", value=page_info.orig_action}) +for i,item in ipairs(view.value) do %> + + + + + <% if viewlibrary.check_permission("edit") or viewlibrary.check_permission("power") then %> + + <% end %> + +<% end %> +
Socket #StatusDescriptionAction
<%= html.html_escape(item.socket) %><%= html.html_escape(item.status) %><%= html.html_escape(item.description) %> + <% local socket = cfe({type="hidden", value=item.socket}) %> + <% if viewlibrary.check_permission("edit") then + htmlviewfunctions.displayitem(cfe({type="link", value={socket=socket, redir=redir}, label="", option="Edit", action="edit" }), page_info, -1) + end %> + <% if viewlibrary.check_permission("poweron") or viewlibrary.check_permission("poweroff") then + htmlviewfunctions.displayitem(cfe({type="form", value={socket=socket, redir=redir}, label="", option="Power ON", action="poweron" }), page_info, -1) + htmlviewfunctions.displayitem(cfe({type="form", value={socket=socket, redir=redir}, label="", option="Power OFF", action="poweroff" }), page_info, -1) + end %> +
+<% htmlviewfunctions.displaysectionend(header_level) %> diff --git a/acf-app/openpdu.menu b/acf-app/openpdu.menu new file mode 100755 index 0000000..2594bb5 --- /dev/null +++ b/acf-app/openpdu.menu @@ -0,0 +1,2 @@ +#CAT GROUP/DESC TAB ACTION +Applications 20OpenPDU Status status diff --git a/acf-app/openpdu.roles b/acf-app/openpdu.roles new file mode 100755 index 0000000..5d6072f --- /dev/null +++ b/acf-app/openpdu.roles @@ -0,0 +1,4 @@ +USER=openpdu:status +EDITOR=openpdu:status +EXPERT=openpdu:status +ADMIN=openpdu:status,openpdu:edit,openpdu:power,openpdu:poweron,openpdu:poweroff diff --git a/acf-openpdu.post-install b/acf-openpdu.post-install new file mode 100755 index 0000000..c52d3c2 --- /dev/null +++ b/acf-openpdu.post-install @@ -0,0 +1,3 @@ +#!/bin/sh + +exit 0 diff --git a/etc/local.d/openpdu.start b/etc/local.d/openpdu.start new file mode 100755 index 0000000..de15e1f --- /dev/null +++ b/etc/local.d/openpdu.start @@ -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 diff --git a/etc/openpdu/openpdu.conf b/etc/openpdu/openpdu.conf new file mode 100755 index 0000000..e69de29