Add relay management

This commit is contained in:
Chteufleur 2015-11-01 16:07:35 +01:00
parent 32df6b8690
commit 7116d3239c
15 changed files with 421 additions and 13 deletions

78
controllers/relay.go Normal file
View File

@ -0,0 +1,78 @@
package controllers
import (
"github.com/astaxie/beego"
"github.com/astaxie/beego/httplib"
"datahouse/models/variables"
"datahouse/models/relay"
"strings"
)
type ViewRelayController struct {
beego.Controller
}
func (c *ViewRelayController) Prepare() {
c.Data["IsViewRelay"] = true;
c.Data["version"] = variables.Version
}
func (c *ViewRelayController) Get() {
c.Data["relays"] = relay.GetAllRelay()
mac := c.Ctx.Input.Param(":sensor")
r := relay.GetRelayByMac(mac)
if r.Id != 0 {
c.Data["isRelaySelected"] = true
c.Data["relayMac"] = r.Mac
if r.Description != "" {
c.Data["relayDescription"] = r.Description
} else {
c.Data["relayDescription"] = r.Mac
}
}
c.TplNames = "relay.tpl"
}
func (c *ViewRelayController) Post() {
mac := c.Ctx.Input.Param(":sensor")
r := relay.GetRelayByMac(mac)
ret := ""
if r.Id != 0 {
ret += r.Mac+"/"
if r.IpAddress != "" {
getRep, err := httplib.Get("http://"+r.IpAddress+"/status").String()
if err == nil {
ret += getRep
} else {
relay.UpdateSensorIpAddress(r.Mac, "")
}
}
}
c.Ctx.Output.Body([]byte(ret))
}
type AddRelayController struct {
beego.Controller
}
func (c *AddRelayController) Prepare() {
c.Data["version"] = variables.Version
}
func (c *AddRelayController) Get() {
ip := strings.Split(c.Ctx.Request.RemoteAddr, ":")[0]
mac := c.Ctx.Input.Param(":sensor")
relay.UpdateSensorIpAddress(mac, ip)
c.Ctx.Output.Body([]byte("OK"))
}

View File

@ -3,6 +3,7 @@ package controllers
import ( import (
"github.com/astaxie/beego" "github.com/astaxie/beego"
"datahouse/models/relay"
"datahouse/models/sensor" "datahouse/models/sensor"
"datahouse/models/temperature" "datahouse/models/temperature"
"datahouse/models/variables" "datahouse/models/variables"
@ -27,8 +28,10 @@ func (c *SensorsController) Prepare() {
func (c *SensorsController) Get() { func (c *SensorsController) Get() {
sensors := sensor.GetAllSensor() sensors := sensor.GetAllSensor()
relays := relay.GetAllRelay()
c.Data["sensors"] = sensors c.Data["sensors"] = sensors
c.Data["relays"] = relays
c.TplNames = "sensors.tpl" c.TplNames = "sensors.tpl"
} }

126
models/relay/relay.go Normal file
View File

@ -0,0 +1,126 @@
package relay
import (
"github.com/astaxie/beego/orm"
"datahouse/models/database"
"datahouse/models/utils"
)
type RelayTable struct {
Id int64
Mac string
Description string
IpAddress string
}
func init() {
orm.RegisterModel(new(RelayTable))
}
func GetRelayByMac(relayMac string) *RelayTable {
o := orm.NewOrm()
o.Using(database.Alias)
ret := new(RelayTable)
var maps []orm.Params
_, err := o.QueryTable(new(RelayTable)).Filter("Mac", relayMac).Values(&maps)
if err == nil {
for _, m := range maps {
ret.Id = utils.GetInt(m, "Id")
ret.Mac = utils.GetString(m, "Mac")
ret.Description = utils.GetString(m, "Description")
ret.IpAddress = utils.GetString(m, "IpAddress")
break
}
}
return ret
}
func GetAllRelay() []RelayTable {
o := orm.NewOrm()
o.Using(database.Alias)
var ret []RelayTable
var maps []orm.Params
_, err := o.QueryTable(new(RelayTable)).Values(&maps)
if err == nil {
for _, m := range maps {
r := new(RelayTable)
r.Id = utils.GetInt(m, "Id")
r.Mac = utils.GetString(m, "Mac")
r.Description = utils.GetString(m, "Description")
r.IpAddress = utils.GetString(m, "IpAddress")
ret = append(ret, *r)
}
}
return ret
}
func GetRelay(id int64) *RelayTable {
o := orm.NewOrm()
o.Using(database.Alias)
var ret = new(RelayTable)
var maps []orm.Params
_, err := o.QueryTable(new(RelayTable)).Filter("Id", id).Values(&maps)
if err == nil {
for _, m := range maps {
ret.Id = utils.GetInt(m, "Id")
ret.Mac = utils.GetString(m, "Mac")
ret.Description = utils.GetString(m, "Description")
ret.IpAddress = utils.GetString(m, "IpAddress")
}
}
return ret
}
func UpdateSensorDescription(mac, description string) {
o := orm.NewOrm()
o.Using(database.Alias)
s := GetRelayByMac(mac)
if o.Read(s) == nil {
s.Description = description
o.Update(s)
} else {
AddRelay(mac, description, "")
}
}
func UpdateSensorIpAddress(mac, ip string) {
o := orm.NewOrm()
o.Using(database.Alias)
s := GetRelayByMac(mac)
if o.Read(s) == nil {
s.IpAddress = ip
o.Update(s)
} else {
AddRelay(mac, "", ip)
}
}
func AddRelay(mac, desc, ip string) {
o := orm.NewOrm()
o.Using(database.Alias)
_, _ = o.Insert(&RelayTable{Mac: mac, Description: desc, IpAddress: ip})
}
func DeleteSensorByMac(mac string) {
o := orm.NewOrm()
o.Using(database.Alias)
o.Delete(&RelayTable{Mac: mac})
}
func DeleteSensor(id int64) {
o := orm.NewOrm()
o.Using(database.Alias)
o.Delete(&RelayTable{Id: id})
}

View File

@ -4,12 +4,20 @@ const (
Version = "0.0.3" Version = "0.0.3"
SessionName = "Session_Data_House" SessionName = "Session_Data_House"
sensorMacRegex = ":sensor([0-9A-Fa-f:]+)"
) )
var ( var (
RootRoute = "/" RootRoute = "/"
AddTempRoute = "/add/temp/:sensor([0-9A-Fa-f:]+)/:val([0-9]+)"
ViewTempRoute = "/view/temp" AddTempRoute = "/add/temp/"+sensorMacRegex+"/:val([0-9]+)"
AddRelayRoute = "/add/relay/"+sensorMacRegex
ViewTempRoute = "/view/temp"
ViewRelaysRoute = "/view/relay"
ViewRelayRoute = "/view/relay/"+sensorMacRegex
SensorsRoute = "/sensors" SensorsRoute = "/sensors"
LoginRoute = "/login" LoginRoute = "/login"
UserRoute = "/user" UserRoute = "/user"

View File

@ -8,8 +8,14 @@ import (
func init() { func init() {
beego.Router(variables.RootRoute, &controllers.MainController{}) beego.Router(variables.RootRoute, &controllers.MainController{})
beego.Router(variables.AddTempRoute, &controllers.AddTempController{}) beego.Router(variables.AddTempRoute, &controllers.AddTempController{})
beego.Router(variables.AddRelayRoute, &controllers.AddRelayController{})
beego.Router(variables.ViewTempRoute, &controllers.ViewTempController{}) beego.Router(variables.ViewTempRoute, &controllers.ViewTempController{})
beego.Router(variables.ViewRelaysRoute, &controllers.ViewRelayController{})
beego.Router(variables.ViewRelayRoute, &controllers.ViewRelayController{})
beego.Router(variables.SensorsRoute, &controllers.SensorsController{}) beego.Router(variables.SensorsRoute, &controllers.SensorsController{})
beego.Router(variables.LoginRoute, &controllers.LoginController{}) beego.Router(variables.LoginRoute, &controllers.LoginController{})
beego.Router(variables.UserRoute, &controllers.UserController{}) beego.Router(variables.UserRoute, &controllers.UserController{})

View File

@ -0,0 +1,36 @@
/* Main marketing message and sign up button */
.jumbotron {
text-align: center;
border-bottom: 1px solid #e5e5e5;
}
.jumbotron .btn {
padding: 14px 24px;
font-size: 21px;
}
/* Supporting marketing content */
.marketing {
margin: 40px 0;
}
.marketing p + h4 {
margin-top: 28px;
}
/* Responsive: Portrait tablets and up */
@media screen and (min-width: 768px) {
/* Remove the padding we set earlier */
.header,
.marketing,
.footer {
padding-right: 0;
padding-left: 0;
}
/* Space out the masthead */
.header {
margin-bottom: 30px;
}
/* Remove the bottom border on the jumbotron for visual effect */
.jumbotron {
border-bottom: 0;
}
}

21
static/css/style.css Normal file
View File

@ -0,0 +1,21 @@
/* make sidebar nav vertical */
@media (min-width: 768px) {
.sidebar-nav .navbar .navbar-collapse {
padding: 0;
max-height: none;
}
.sidebar-nav .navbar ul {
float: none;
}
.sidebar-nav .navbar ul:not {
display: block;
}
.sidebar-nav .navbar li {
float: none;
display: block;
}
.sidebar-nav .navbar li a {
padding-top: 12px;
padding-bottom: 12px;
}
}

BIN
static/img/bulbOff.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
static/img/bulbOn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -9,6 +9,7 @@
<link rel="icon" href="/static/img/favicon.ico"> <link rel="icon" href="/static/img/favicon.ico">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/style.css">
<link href="/static/bootstrap/css/sticky-footer-navbar.css" rel="stylesheet"> <link href="/static/bootstrap/css/sticky-footer-navbar.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]> <!--[if lt IE 9]>

View File

@ -17,6 +17,13 @@
class="active" class="active"
{{end}} {{end}}
><a href="/view/temp">Temperatures</a></li> ><a href="/view/temp">Temperatures</a></li>
<li
{{if .IsViewRelay}}
class="active"
{{end}}
><a href="/view/relay">Relais</a></li>
<!-- <li <!-- <li
{{if .IsViewElec}} {{if .IsViewElec}}
class="active" class="active"

View File

@ -1,6 +1,8 @@
{{template "base/base.html" .}} {{template "base/base.html" .}}
{{define "meta"}} {{define "meta"}}
{{end}} {{end}}
{{define "extrajs"}}
{{end}}
{{define "body"}} {{define "body"}}
<br/> <br/>
{{range $key, $val := .sensors}} {{range $key, $val := .sensors}}

102
views/relay.tpl Normal file
View File

@ -0,0 +1,102 @@
{{template "base/base.html" .}}
{{define "meta"}}
<link href="/static/css/jumbotron-narrow.css" rel="stylesheet">
{{end}}
{{define "body"}}
<div class="row">
<div class="col-sm-3">
<div class="sidebar-nav">
<div class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".sidebar-navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<span class="visible-xs navbar-brand">Sidebar menu</span>
</div>
<div class="navbar-collapse collapse sidebar-navbar-collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#"><strong>List des relays</strong></a></li>
{{range $key, $val := .relays}}
<li>
<a class="relayLink" id="{{$val.Mac}}" href="/view/relay/{{$val.Mac}}" >
{{if eq $val.Description ""}}
{{$val.Mac}}
{{else}}
{{$val.Description}}
{{end}}
<img class="navbar-right" src="/static/img/bulbOff.png" style="width: 20px; margin-right: 0px;" />
</a>
</li>
{{end}}
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<div class="col-sm-9">
{{template "content" .}}
</div>
</div>
{{end}}
{{define "content"}}
{{if .isRelaySelected}}
<div class="jumbotron">
<h3>{{.relayDescription}}</h3>
<br/>
<p><a class="btn btn-lg btn-primary" href="#" role="button">Toggle</a></p>
<br/>
<p><img id="{{.relayMac}}" src="/static/img/bulbOff.png" style="width: 100px;"/></p>
</div>
{{end}}
{{end}}
{{define "extrajs"}}
<script type="application/javascript">
var forEachRelay = function() {
$(".relayLink").each(function( index ) {
$.ajax({
url: "/view/relay/"+$(this).attr("id"),
method: "POST",
success: function(result){
var res = result.split("/");
if (res.length < 2) {
return;
}
var mac = res[0];
var status = res[1];
// Update img of the left list
var links = $(".relayLink")
for (var i=0; i<links.length; i++) {
if ($(links[i]).attr("id") == mac) {
if (status == "allume") {
$(links[i]).children("img").attr("src", "/static/img/bulbOn.png")
} else {
$(links[i]).children("img").attr("src", "/static/img/bulbOff.png")
}
}
}
// update the img of the selected relay
if ($(".jumbotron img").attr("id") == mac) {
if (status == "allume") {
$(".jumbotron img").attr("src", "/static/img/bulbOn.png")
} else {
$(".jumbotron img").attr("src", "/static/img/bulbOff.png")
}
}
}
});
});
}
forEachRelay();
setInterval(forEachRelay, 5000);
</script>
{{end}}

View File

@ -1,8 +1,11 @@
{{template "base/base.html" .}} {{template "base/base.html" .}}
{{define "meta"}} {{define "meta"}}
{{end}} {{end}}
{{define "extrajs"}}
{{end}}
{{define "body"}} {{define "body"}}
<br/> <br/>
{{range $key, $val := .sensors}} {{range $key, $val := .sensors}}
<form method="POST" action="/sensors" class="form-inline"> <form method="POST" action="/sensors" class="form-inline">
<div class="panel panel-info"> <div class="panel panel-info">
@ -14,17 +17,6 @@
<div class="form-group"> <div class="form-group">
<label>Interval de prise de mesure : </label> <label>Interval de prise de mesure : </label>
<input type="number" class="form-control" name="interval" value="{{$val.Interval}}"/> <input type="number" class="form-control" name="interval" value="{{$val.Interval}}"/>
<!-- <select name="interval">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select> -->
</div> </div>
<br/><br/> <br/><br/>
<div class="form-group"> <div class="form-group">
@ -38,5 +30,27 @@
</div> </div>
</form> </form>
{{end}} {{end}}
<br/>
{{range $key, $val := .relays}}
<form method="POST" action="/sensors" class="form-inline">
<div class="panel panel-warning">
<div class="panel-heading">
<h3 class="panel-title">{{$val.Mac}}</h3>
<input type="hidden" name="mac" value="{{$val.Mac}}"/>
</div>
<div class="panel-body">
<div class="form-group">
<label>Nom du relai : </label>
<input type="text" class="form-control" name="description" value="{{$val.Description}}"/>
</div>
<br/><br/>
<input class="btn btn-default btn btn-success" name="save" type="submit" value="Enregistrer"/>
<input class="btn btn-default btn btn-danger" name="delete" type="submit" value="Supprimer"/>
</div>
</div>
</form>
{{end}}
<br/> <br/>
{{end}} {{end}}

View File

@ -75,6 +75,10 @@
}); });
</script> </script>
{{end}} {{end}}
{{define "extrajs"}}
{{end}}
{{define "body"}} {{define "body"}}
<center><h1>Temperatures</h1></center><br/> <center><h1>Temperatures</h1></center><br/>