Adding TeleInfo into the list

This commit is contained in:
Chteufleur 2016-03-04 23:17:05 +01:00
parent a3ce8abd39
commit 207971f2db
11 changed files with 584 additions and 10 deletions

View File

@ -6,6 +6,7 @@ import (
"git.kingpenguin.tk/chteufleur/datahouse.git/models/relay"
"git.kingpenguin.tk/chteufleur/datahouse.git/models/sensor"
"git.kingpenguin.tk/chteufleur/datahouse.git/models/temperature"
"git.kingpenguin.tk/chteufleur/datahouse.git/models/teleinfo"
"git.kingpenguin.tk/chteufleur/datahouse.git/models/variables"
"strconv"
@ -30,9 +31,11 @@ func (c *SensorsController) Prepare() {
func (c *SensorsController) Get() {
sensors := sensor.GetAllSensor()
relays := relay.GetAllRelay()
compteurs := teleinfo.GetAllCompteur()
c.Data["sensors"] = sensors
c.Data["relays"] = relays
c.Data["compteurs"] = compteurs
c.TplNames = "sensors.tpl"
}
@ -42,6 +45,8 @@ func (c *SensorsController) Post() {
c.PostTempSensors()
} else if tpye == "relay" {
c.PostRelay()
} else if tpye == "compteur" {
c.PostCompteur()
} else {
c.Redirect("/404", 404)
}
@ -85,3 +90,21 @@ func (c *SensorsController) PostRelay() {
c.Redirect("/404", 404)
}
}
func (c *SensorsController) PostCompteur() {
description := c.Input().Get("description")
adresse := c.Input().Get("adresse")
isDelete := c.Input().Get("delete")
isSave := c.Input().Get("save")
if isSave != "" {
teleinfo.UpdateCompteur(adresse, description)
c.Redirect("/sensors", 302)
} else if isDelete != "" {
cpt := teleinfo.GetCompteurByAdresse(adresse)
teleinfo.DeleteCompteur(cpt.Id)
c.Redirect("/sensors", 302)
} else {
c.Redirect("/404", 404)
}
}

68
controllers/teleinfo.go Normal file
View File

@ -0,0 +1,68 @@
package controllers
import (
"github.com/astaxie/beego"
"git.kingpenguin.tk/chteufleur/datahouse.git/models/variables"
"git.kingpenguin.tk/chteufleur/datahouse.git/models/teleinfo"
)
//——————————————————————————————————————————————————————————————————————————————
// AddTeleinfoController
//——————————————————————————————————————————————————————————————————————————————
type AddTeleinfoController struct {
beego.Controller
}
func (c *AddTeleinfoController) Prepare() {
c.Data["version"] = variables.Version
}
func (c *AddTeleinfoController) Get() {
adresse := c.GetString(teleinfo.AdresseCompteur)
tarif := c.GetString(teleinfo.OptionTarifaire)
option := c.GetString(teleinfo.OptionBase)
hp, _ := c.GetInt(teleinfo.HeurePleinne)
hc, _ := c.GetInt(teleinfo.HeureCreuse)
teleinfo.AddData(adresse, tarif, option, int64(hp), int64(hc))
cpt := teleinfo.GetCompteurByAdresse(adresse)
if cpt == nil || cpt.Id == 0 {
teleinfo.AddCompteur(adresse)
}
c.Ctx.Output.Body([]byte(""))
}
//——————————————————————————————————————————————————————————————————————————————
// ViewTeleinfoController
//——————————————————————————————————————————————————————————————————————————————
type ViewTeleinfoController struct {
beego.Controller
}
func (c *ViewTeleinfoController) Prepare() {
c.Data["IsViewTeleinfo"] = true
c.Data["version"] = variables.Version
}
func (c *ViewTeleinfoController) Get() {
c.Data["compteurs"] = teleinfo.GetAllCompteur()
adresse := c.Ctx.Input.Param(":compteur")
cpt := teleinfo.GetCompteurByAdresse(adresse)
if cpt.Id != 0 {
c.Data["isCompteurSelected"] = true
c.Data["dataCompteur"] = teleinfo.GetLastDataForCompteur(cpt.AdresseCompteur)
c.Data["compteurAdresse"] = cpt.AdresseCompteur
if cpt.Description != "" {
c.Data["compteurDescription"] = cpt.Description
} else {
c.Data["compteurDescription"] = cpt.AdresseCompteur
}
}
c.TplNames = "teleinfo.tpl"
}

229
models/teleinfo/teleinfo.go Normal file
View File

@ -0,0 +1,229 @@
package teleinfo
import (
"github.com/astaxie/beego/logs"
"github.com/astaxie/beego/orm"
"git.kingpenguin.tk/chteufleur/datahouse.git/models/database"
"git.kingpenguin.tk/chteufleur/datahouse.git/models/utils"
"time"
)
const (
AdresseCompteur = "ADCO"
OptionTarifaire = "OPTARIF"
OptionBase = "BASE" // Wh
HeurePleinne = "HCHP" // Wh
HeureCreuse = "HCHC" // Wh
)
var (
_, timezoneOffset = time.Now().Zone()
log = logs.NewLogger(10000)
optionTarifaireTranslate = make(map[string]string)
)
func init() {
log.SetLogger("console", "")
orm.RegisterModel(new(TeleinfoTable), new(CompteurTeleinfoTable))
orm.DefaultRowsLimit = 4500
optionTarifaireTranslate["BASE"] = "Base"
optionTarifaireTranslate["HC.."] = "Heures Creuses"
optionTarifaireTranslate["EJP."] = "EJP"
}
//——————————————————————————————————————————————————————————————————————————————
// TeleinfoTable
//——————————————————————————————————————————————————————————————————————————————
type TeleinfoTable struct {
Id int64
HorodateGMT time.Time `orm:"auto_now;type(datetime)"`
AdresseCompteur string
OptionTarifaire string
OptionBase string
HeurePleinne int64
HeureCreuse int64
}
func AddData(adresse, tarif, option string, hp, hc int64) {
log.Info("Add teleinfo {adresse: %s, tarif: %s, option: %s, hp: %d, hc: %d}", adresse, tarif, option, hp, hc)
o := orm.NewOrm()
o.Using(database.Alias)
ti := new(TeleinfoTable)
ti.AdresseCompteur = adresse
ti.OptionTarifaire = tarif
ti.OptionBase = option
ti.HeurePleinne = hp
ti.HeureCreuse = hc
o.Insert(ti)
}
func GetAllDataForCompteur(adresseCompteur string) []TeleinfoTable {
o := orm.NewOrm()
o.Using(database.Alias)
var dataArray []TeleinfoTable
var maps []orm.Params
_, err := o.QueryTable(new(TeleinfoTable)).Filter("AdresseCompteur", adresseCompteur).Values(&maps)
if err == nil {
for _, m := range maps {
d := new(TeleinfoTable)
d.Id = utils.GetInt(m, "Id")
d.HorodateGMT = utils.GetTime(m, "HorodateGMT")
d.AdresseCompteur = utils.GetString(m, "AdresseCompteur")
d.OptionTarifaire = optionTarifaireTranslate[utils.GetString(m, "OptionTarifaire")]
d.OptionBase = utils.GetString(m, "OptionBase")
d.HeurePleinne = utils.GetInt(m, "HeurePleinne")
d.HeureCreuse = utils.GetInt(m, "HeureCreuse")
dataArray = append(dataArray, *d)
}
}
return dataArray
}
func GetLastDataForCompteur(adresseCompteur string) *TeleinfoTable {
o := orm.NewOrm()
o.Using(database.Alias)
data := new(TeleinfoTable)
var maps []orm.Params
_, err := o.QueryTable(new(TeleinfoTable)).Filter("AdresseCompteur", adresseCompteur).OrderBy("HorodateGMT").Values(&maps)
if err == nil {
for _, m := range maps {
data.Id = utils.GetInt(m, "Id")
data.HorodateGMT = utils.GetTime(m, "HorodateGMT")
data.AdresseCompteur = utils.GetString(m, "AdresseCompteur")
data.OptionTarifaire = optionTarifaireTranslate[utils.GetString(m, "OptionTarifaire")]
data.OptionBase = utils.GetString(m, "OptionBase")
data.HeurePleinne = utils.GetInt(m, "HeurePleinne")
data.HeureCreuse = utils.GetInt(m, "HeureCreuse")
}
}
return data
}
//——————————————————————————————————————————————————————————————————————————————
// CompteurTeleinfoTable
//——————————————————————————————————————————————————————————————————————————————
type CompteurTeleinfoTable struct {
Id int64
AdresseCompteur string
Description string
}
func GetCompteurByAdresse(adresse string) *CompteurTeleinfoTable {
o := orm.NewOrm()
o.Using(database.Alias)
ret := new(CompteurTeleinfoTable)
var maps []orm.Params
_, err := o.QueryTable(new(CompteurTeleinfoTable)).Filter("AdresseCompteur", adresse).Values(&maps)
if err == nil {
for _, m := range maps {
ret.Id = utils.GetInt(m, "Id")
ret.AdresseCompteur = utils.GetString(m, "AdresseCompteur")
ret.Description = utils.GetString(m, "Description")
break
}
}
return ret
}
func GetAllCompteurIds() []int64 {
o := orm.NewOrm()
o.Using(database.Alias)
var ret []int64
var maps []orm.Params
_, err := o.QueryTable(new(CompteurTeleinfoTable)).Values(&maps)
if err == nil {
for _, m := range maps {
ret = append(ret, utils.GetInt(m, "Id"))
}
}
return ret
}
func GetAllCompteur() []CompteurTeleinfoTable {
o := orm.NewOrm()
o.Using(database.Alias)
var ret []CompteurTeleinfoTable
var maps []orm.Params
_, err := o.QueryTable(new(CompteurTeleinfoTable)).Values(&maps)
if err == nil {
for _, m := range maps {
r := new(CompteurTeleinfoTable)
r.Id = utils.GetInt(m, "Id")
r.AdresseCompteur = utils.GetString(m, "AdresseCompteur")
r.Description = utils.GetString(m, "Description")
ret = append(ret, *r)
}
}
return ret
}
func GetSensor(id int64) *CompteurTeleinfoTable {
o := orm.NewOrm()
o.Using(database.Alias)
var ret = new(CompteurTeleinfoTable)
var maps []orm.Params
_, err := o.QueryTable(new(CompteurTeleinfoTable)).Filter("Id", id).Values(&maps)
if err == nil {
for _, m := range maps {
ret.Id = utils.GetInt(m, "Id")
ret.AdresseCompteur = utils.GetString(m, "AdresseCompteur")
ret.Description = utils.GetString(m, "Description")
}
}
return ret
}
func UpdateCompteur(adresse, description string) {
o := orm.NewOrm()
o.Using(database.Alias)
s := GetCompteurByAdresse(adresse)
if o.Read(s) == nil {
s.AdresseCompteur = adresse
s.Description = description
o.Update(s)
}
}
func AddCompteur(adresse string) {
o := orm.NewOrm()
o.Using(database.Alias)
_, _ = o.Insert(&CompteurTeleinfoTable{AdresseCompteur: adresse})
}
func DeleteCompteurByAdresse(adresse string) {
o := orm.NewOrm()
o.Using(database.Alias)
o.Delete(&CompteurTeleinfoTable{AdresseCompteur: adresse})
}
func DeleteCompteur(compteurId int64) {
o := orm.NewOrm()
o.Using(database.Alias)
o.Delete(&CompteurTeleinfoTable{Id: compteurId})
}

View File

@ -25,6 +25,7 @@ var (
func init() {
log.SetLogger("console", "")
orm.RegisterModel(new(TempTable))
orm.DefaultRowsLimit = 4500
}
/**

View File

@ -1,7 +1,7 @@
package variables
const (
Version = "0.0.4.3"
Version = "0.0.5.0"
SessionName = "Session_Data_House"
@ -13,10 +13,13 @@ var (
AddTempRoute = "/add/temp/" + sensorMacRegex + "/:val([0-9]+)"
AddRelayRoute = "/add/relay/" + sensorMacRegex
TeleinfoAddRoute = "/teleinfo/add"
ViewTempRoute = "/view/temp"
ViewRelaysRoute = "/view/relay"
ViewRelayRoute = "/view/relay/" + sensorMacRegex
ViewTeleinfosRoute = "/view/teleinfo"
ViewTeleinfoRoute = "/view/teleinfo/:compteur([0-9A-Fa-f:]+)"
CommandRelayRoute = "/command/relay/" + sensorMacRegex
@ -24,4 +27,5 @@ var (
LoginRoute = "/login/:route(.*)"
LoginRouteNoRegex = "/login"
UserRoute = "/user"
)

View File

@ -11,6 +11,7 @@ func init() {
beego.Router(variables.AddTempRoute, &controllers.AddTempController{})
beego.Router(variables.AddRelayRoute, &controllers.AddRelayController{})
beego.Router(variables.TeleinfoAddRoute, &controllers.AddTeleinfoController{})
beego.Router(variables.ViewTempRoute, &controllers.ViewTempController{})
beego.Router(variables.ViewRelaysRoute, &controllers.ViewRelayController{})
@ -18,6 +19,9 @@ func init() {
beego.Router(variables.CommandRelayRoute, &controllers.CommandRelayController{})
beego.Router(variables.ViewTeleinfosRoute, &controllers.ViewTeleinfoController{})
beego.Router(variables.ViewTeleinfoRoute, &controllers.ViewTeleinfoController{})
beego.Router(variables.SensorsRoute, &controllers.SensorsController{})
beego.Router(variables.LoginRoute, &controllers.LoginController{})
beego.Router(variables.UserRoute, &controllers.UserController{})

View File

@ -0,0 +1,160 @@
/*
* Send TeleInfo via HTTP GET request to $host service.
* Read ERDF TeleInfo when received, then send it to the server.
* Version 1.0
*/
/*
* TODO : Gestion du temps pour n'envoyer que toute les minutes (ou un truc du genre)
*/
#include <ESP8266WiFi.h>
//----------------------------------------------------
const char* ssid = "TNCAP3F2E03";
const char* password = "73ABCCAA87";
//const char* host = "datahouse.kingpenguin.tk";
const char* host = "192.168.1.143";
const int httpPort = 8080;
const int DEFAULT_INTERVAL = 60000; // 60 sec
//----------------------------------------------------
String ADCO = "";
String OPTARIF = "";
String BASE = "";
String HCHP = "";
String HCHC = "";
//----------------------------------------------------
// Wait for x second.
void sleepSec(int sec) {
for (int i=0; i<1000; i++) {
delay(sec);
}
}
long nextInterval;
void sendDataToServer() {
// Use WiFiClient class to create TCP connections
WiFiClient client;
if (!client.connect(host, httpPort)) {
Serial.print("connection failed on host ");
Serial.print(host);
Serial.print(":");
Serial.println(host);
return;
}
// We now create a URI for the request
// TODO a finir
String url = "/teleinfo/add?ADCO="+ADCO+"&OPTARIF="+OPTARIF+"&BASE="+BASE+"&HCHC="+HCHC+"&HCHP="+HCHP;
ADCO = "";
OPTARIF = "";
BASE = "";
HCHC = "";
HCHP = "";
Serial.print("Requesting URL: ");
Serial.println(url);
// This will send the request to the server
client.println("GET "+url+" HTTP/1.1");
client.println("Host: "+String(host));
client.println("Connection: keep-alive");
// client.println("Connection: close");
client.println();
delay(10);
Serial.println();
String line = "";
while (client.available()) {
char c = client.read();
line += c;
}
Serial.println(line);
nextInterval = line.toInt();
if (nextInterval == 0) {
nextInterval = DEFAULT_INTERVAL;
}
nextInterval = millis() + nextInterval;
}
void setup() {
Serial.begin(1200);
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
if (Serial.available() > 0) {
String str = Serial.readStringUntil('\n');
if (millis() >= nextInterval) {
bool sendable = false;
int i = str.indexOf("ADCO");
if (i != -1) {
i = i + 4 +1;
ADCO = str.substring(i, i+12);
}
i = str.indexOf("OPTARIF");
if (i != -1) {
i = i + 7 +1;
OPTARIF = str.substring(i, i+4);
}
i = str.indexOf("BASE");
if (i != -1) {
i = i + 4 +1;
BASE = str.substring(i, i+9);
}
i = str.indexOf("HCHC");
if (i != -1) {
i = i + 4 +1;
HCHC = str.substring(i, i+9);
}
i = str.indexOf("HCHP");
if (i != -1) {
i = i + 4 +1;
HCHP = str.substring(i, i+9);
sendable = true;
}
if (sendable && ADCO != "") {
sendDataToServer();
}
}
}
}

View File

@ -24,11 +24,12 @@
{{end}}
><a href="/view/relay">Relais</a></li>
<!-- <li
{{if .IsViewElec}}
<li
{{if .IsViewTeleinfo}}
class="active"
{{end}}
><a href="/view/elec">Consommation electrique</a></li> -->
><a href="/view/teleinfo">Télé-Info</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{{if .IsAuthentificated}}

View File

@ -18,7 +18,7 @@
</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>
<li class="active"><a href="#"><strong>Liste des relays</strong></a></li>
{{range $key, $val := .relays}}
<li>
<a class="relayLink" id="{{$val.Mac}}" href="/view/relay/{{$val.Mac}}" >

View File

@ -54,5 +54,30 @@
</div>
</form>
{{end}}
<br/>
{{range $key, $val := .compteurs}}
<form method="POST" action="/sensors" class="form-inline">
<input type="hidden" name="type" value="compteur" />
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">{{$val.AdresseCompteur}}</h3>
<input type="hidden" name="adresse" value="{{$val.AdresseCompteur}}"/>
</div>
<div class="panel-body">
<div class="form-group">
<label>Nom du compteur : </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/>
{{end}}

59
views/teleinfo.tpl Normal file
View File

@ -0,0 +1,59 @@
{{template "base/base.html" .}}
{{define "meta"}}
{{end}}
{{define "extrajs"}}
{{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>Liste des compteurs</strong></a></li>
{{range $key, $val := .compteurs}}
<li>
<a class="relayLink" id="{{$val.AdresseCompteur}}" href="/view/teleinfo/{{$val.AdresseCompteur}}" >
{{if eq $val.Description ""}}
{{$val.AdresseCompteur}}
{{else}}
{{$val.Description}}
{{end}}
</a>
</li>
{{end}}
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<div class="col-sm-9">
{{template "content" .}}
</div>
</div>
{{end}}
{{define "content"}}
{{if .isCompteurSelected}}
<div class="jumbotron">
<center><h3><strong>{{.compteurDescription}}</strong></h3></center>
<hr/>
<h4>N° Compteur: <small>{{.dataCompteur.AdresseCompteur}}</small></h4>
<h4>Option tarifaire: <small>{{.dataCompteur.OptionTarifaire}}</small></p>
<h4>Option base: <small>{{.dataCompteur.OptionBase}}</small></h4>
<h4>Heure pleine: <small>{{.dataCompteur.HeurePleinne}} Wh</small></h4>
<h4>Heure creuse: <small>{{.dataCompteur.HeureCreuse}} Wh</small></h4>
</div>
{{end}}
{{end}}