diff --git a/conf/app.conf b/conf/app.conf index 2fd18b6..e277c82 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -13,3 +13,7 @@ SessionGCMaxLifetime = 3600 SessionHashFunc = sha1 SessionHashKey = chucknorriswillkickyourassandeatyoursoul SessionCookieLifeTime = 3600 + +JID = test@kingpenguin.tk +PWD = test +PORT = 5222 diff --git a/controllers/default.go b/controllers/default.go index f10d9b7..9b2a555 100644 --- a/controllers/default.go +++ b/controllers/default.go @@ -18,7 +18,7 @@ var ( ) func init() { - log.SetLogger("console", "") + log.SetLogger(variables.LogType, variables.LogParams) } type SensorPrint struct { diff --git a/controllers/relay.go b/controllers/relay.go index a90f294..fede7c5 100644 --- a/controllers/relay.go +++ b/controllers/relay.go @@ -102,9 +102,7 @@ func (c *CommandRelayController) Prepare() { func (c *CommandRelayController) Post() { mac := c.Ctx.Input.Param(":sensor") r := relay.GetRelayByMac(mac) - if r.Id != 0 { - httplib.Get("http://"+r.IpAddress+"/toggle").SetTimeout(3*time.Second, 3*time.Second).String() - } + r.Toggle() c.Ctx.Output.Body([]byte("")) } diff --git a/controllers/teleinfo.go b/controllers/teleinfo.go index 8045c56..c8abee5 100644 --- a/controllers/teleinfo.go +++ b/controllers/teleinfo.go @@ -5,6 +5,9 @@ import ( "git.kingpenguin.tk/chteufleur/datahouse.git/models/variables" "git.kingpenguin.tk/chteufleur/datahouse.git/models/teleinfo" + + "html/template" + "strconv" ) //—————————————————————————————————————————————————————————————————————————————— @@ -57,12 +60,48 @@ func (c *ViewTeleinfoController) Get() { 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 + desc := cpt.Description + if desc == "" { + desc = cpt.AdresseCompteur } + c.Data["compteurDescription"] = desc + dataPower := formatDataSensorTeleInfo(teleinfo.GetAllDataForCompteur(cpt.AdresseCompteur)) + c.Data["dataPower"] = template.JS(dataPower) } c.TplNames = "teleinfo.tpl" } + + +func formatDataSensorTeleInfo(values []teleinfo.TeleinfoTable) string { + ret := "" + for a := 0; a < 2; a++ { + ret += "{name : \"" + if a == 0 { + ret += "Heure Pleines" + } else { + ret += "Heure Creuses" + } + ret += "\",marker : {enabled : true, radius : 3}, data : [" + for i := 0; i < len(values); i++ { + if i > 0 { + ret += "," + } + // TODO faire la dérivé de la puissance pour avoir les variations plutot que l'évolution de la puissance + horodate := strconv.FormatInt((values[i].HorodateGMT.Unix()+int64(timezoneOffset))*1000, 10) + value := "" + if a == 0 { + value = strconv.FormatInt(values[i].HeurePleinne, 10) + } else { + value = strconv.FormatInt(values[i].HeureCreuse, 10) + } + ret += "[" + horodate + "," + value + "]" + } + ret += "]}" + + if a == 0 { + ret += "," + } + } + return ret +} diff --git a/controllers/viewLog.go b/controllers/viewLog.go new file mode 100644 index 0000000..0af9f52 --- /dev/null +++ b/controllers/viewLog.go @@ -0,0 +1,64 @@ +package controllers + +import ( + "github.com/astaxie/beego" + "github.com/gorilla/websocket" + + "git.kingpenguin.tk/chteufleur/datahouse.git/models/variables" + "git.kingpenguin.tk/chteufleur/datahouse.git/watchlog" + + "net/http" +) + + + +type WebSocketController struct { + beego.Controller +} + +func (c *WebSocketController) Prepare() { + sess := c.GetSession(variables.SessionName) + if sess == nil { + c.Redirect(variables.LoginRouteNoRegex+variables.UserRoute, 302) + } else { + c.Data["IsAuthentificated"] = true + } + + c.Data["IsLog"] = true + c.Data["version"] = variables.Version +} + + +// Get method handles GET requests for WebSocketController. +func (c *WebSocketController) Get() { + c.Data["hostWS"] = "ws://"+c.Ctx.Request.Host+variables.WebSocketLogRoute + c.TplNames = "watchlog.tpl" +} + + + + +// Join method handles WebSocket requests for WebSocketController. +func (this *WebSocketController) Join() { + // Upgrade from http request to WebSocket. + ws, err := websocket.Upgrade(this.Ctx.ResponseWriter, this.Ctx.Request, nil, 1024, 1024) + if _, ok := err.(websocket.HandshakeError); ok { + http.Error(this.Ctx.ResponseWriter, "Not a websocket handshake", 400) + return + } else if err != nil { + beego.Error("Cannot setup WebSocket connection:", err) + return + } + + watchlog.ListWebSocket.PushFront(ws) + + + // Message receive loop. + for { + _, _, err := ws.ReadMessage() + if err != nil { + return + } + } + this.Ctx.Output.Body([]byte("")) +} diff --git a/main.go b/main.go index 3793e0d..256cfc4 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,9 @@ import ( _ "git.kingpenguin.tk/chteufleur/datahouse.git/models/temperature" "git.kingpenguin.tk/chteufleur/datahouse.git/models/user" _ "git.kingpenguin.tk/chteufleur/datahouse.git/routers" + "git.kingpenguin.tk/chteufleur/datahouse.git/xmpp" + "git.kingpenguin.tk/chteufleur/datahouse.git/watchlog" + "git.kingpenguin.tk/chteufleur/datahouse.git/models/variables" "github.com/astaxie/beego" "github.com/astaxie/beego/logs" @@ -18,7 +21,7 @@ var ( ) func init() { - log.SetLogger("console", "") + log.SetLogger(variables.LogType, variables.LogParams) url := "" db := "" if database.DatabaseInstance == database.MySQL { @@ -51,6 +54,7 @@ func main() { if !user.IsUserExist("admin") { user.AddUser("admin", "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918") } - + go xmpp_manager.Run() + go watchlog.Run() beego.Run() } diff --git a/models/relay/relay.go b/models/relay/relay.go index 7012458..93e2afc 100644 --- a/models/relay/relay.go +++ b/models/relay/relay.go @@ -2,9 +2,12 @@ package relay import ( "github.com/astaxie/beego/orm" + "github.com/astaxie/beego/httplib" "git.kingpenguin.tk/chteufleur/datahouse.git/models/database" "git.kingpenguin.tk/chteufleur/datahouse.git/models/utils" + + "time" ) type RelayTable struct { @@ -120,3 +123,11 @@ func DeleteSensor(id int64) { o.Using(database.Alias) o.Delete(&RelayTable{Id: id}) } + +func (relay *RelayTable) Toggle() (error) { + var err error + if relay.Id != 0 { + _, err = httplib.Get("http://"+relay.IpAddress+"/toggle").SetTimeout(3*time.Second, 3*time.Second).String() + } + return err +} diff --git a/models/teleinfo/teleinfo.go b/models/teleinfo/teleinfo.go index 8dea874..c7d7d1c 100644 --- a/models/teleinfo/teleinfo.go +++ b/models/teleinfo/teleinfo.go @@ -6,6 +6,7 @@ import ( "git.kingpenguin.tk/chteufleur/datahouse.git/models/database" "git.kingpenguin.tk/chteufleur/datahouse.git/models/utils" + "git.kingpenguin.tk/chteufleur/datahouse.git/models/variables" "time" ) @@ -26,7 +27,7 @@ var ( ) func init() { - log.SetLogger("console", "") + log.SetLogger(variables.LogType, variables.LogParams) orm.RegisterModel(new(TeleinfoTable), new(CompteurTeleinfoTable)) orm.DefaultRowsLimit = 4500 @@ -114,6 +115,11 @@ func GetLastDataForCompteur(adresseCompteur string) *TeleinfoTable { return data } +func DeleteDataCompteur(adresseCompteur string) { + o := orm.NewOrm() + o.Using(database.Alias) + o.Delete(&TeleinfoTable{AdresseCompteur: adresseCompteur}) +} @@ -220,10 +226,15 @@ func DeleteCompteurByAdresse(adresse string) { o := orm.NewOrm() o.Using(database.Alias) o.Delete(&CompteurTeleinfoTable{AdresseCompteur: adresse}) + + DeleteDataCompteur(adresse) } func DeleteCompteur(compteurId int64) { + compteur := GetSensor(compteurId) o := orm.NewOrm() o.Using(database.Alias) o.Delete(&CompteurTeleinfoTable{Id: compteurId}) + + DeleteDataCompteur(compteur.AdresseCompteur) } diff --git a/models/temperature/temp/temp.go b/models/temperature/temp/temp.go index 5e9c7dc..fc02153 100644 --- a/models/temperature/temp/temp.go +++ b/models/temperature/temp/temp.go @@ -6,6 +6,7 @@ import ( "git.kingpenguin.tk/chteufleur/datahouse.git/models/database" "git.kingpenguin.tk/chteufleur/datahouse.git/models/utils" + "git.kingpenguin.tk/chteufleur/datahouse.git/models/variables" "time" ) @@ -25,7 +26,7 @@ var ( ) func init() { - log.SetLogger("console", "") + log.SetLogger(variables.LogType, variables.LogParams) orm.RegisterModel(new(TempTableTmp)) } diff --git a/models/temperature/temperature.go b/models/temperature/temperature.go index 2f9599b..424df81 100644 --- a/models/temperature/temperature.go +++ b/models/temperature/temperature.go @@ -6,6 +6,7 @@ import ( "git.kingpenguin.tk/chteufleur/datahouse.git/models/database" "git.kingpenguin.tk/chteufleur/datahouse.git/models/utils" + "git.kingpenguin.tk/chteufleur/datahouse.git/models/variables" "time" ) @@ -23,7 +24,7 @@ var ( ) func init() { - log.SetLogger("console", "") + log.SetLogger(variables.LogType, variables.LogParams) orm.RegisterModel(new(TempTable)) orm.DefaultRowsLimit = 4500 } diff --git a/models/variables/variables.go b/models/variables/variables.go index 778f2e2..08157ea 100644 --- a/models/variables/variables.go +++ b/models/variables/variables.go @@ -1,31 +1,51 @@ package variables const ( - Version = "0.0.5.0" + Version = "0.1.2" SessionName = "Session_Data_House" sensorMacRegex = ":sensor([0-9A-Fa-f:]+)" + + logFile = "file" + LogFileName = "filename" + LogFilePath = "datahouse.log" + logConsole = "console" ) var ( - RootRoute = "/" +/* +———————————————————————————————————————————————————————————————————————————————— + Routes +———————————————————————————————————————————————————————————————————————————————— +*/ + RootRoute = "/" - AddTempRoute = "/add/temp/" + sensorMacRegex + "/:val([0-9]+)" - AddRelayRoute = "/add/relay/" + sensorMacRegex - TeleinfoAddRoute = "/teleinfo/add" + 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:]+)" + ViewLogRoute = "/view/log" + WebSocketLogRoute = "/view/log/join" - CommandRelayRoute = "/command/relay/" + sensorMacRegex + CommandRelayRoute = "/command/relay/" + sensorMacRegex - SensorsRoute = "/sensors" - LoginRoute = "/login/:route(.*)" - LoginRouteNoRegex = "/login" - UserRoute = "/user" + SensorsRoute = "/sensors" + LoginRoute = "/login/:route(.*)" + LoginRouteNoRegex = "/login" + UserRoute = "/user" + + /* + ———————————————————————————————————————————————————————————————————————————————— + Logs + ———————————————————————————————————————————————————————————————————————————————— + */ + LogType = logFile + LogParams = "{\""+LogFileName+"\":\""+LogFilePath+"\"}" ) diff --git a/routers/router.go b/routers/router.go index d873f39..6673652 100644 --- a/routers/router.go +++ b/routers/router.go @@ -16,6 +16,8 @@ func init() { beego.Router(variables.ViewTempRoute, &controllers.ViewTempController{}) beego.Router(variables.ViewRelaysRoute, &controllers.ViewRelayController{}) beego.Router(variables.ViewRelayRoute, &controllers.ViewRelayController{}) + beego.Router(variables.ViewLogRoute, &controllers.WebSocketController{}) + beego.Router(variables.WebSocketLogRoute, &controllers.WebSocketController{}, "get:Join") beego.Router(variables.CommandRelayRoute, &controllers.CommandRelayController{}) @@ -25,4 +27,5 @@ func init() { beego.Router(variables.SensorsRoute, &controllers.SensorsController{}) beego.Router(variables.LoginRoute, &controllers.LoginController{}) beego.Router(variables.UserRoute, &controllers.UserController{}) + } diff --git a/sensors/TeleInfo/TeleInfo.ino b/sensors/TeleInfo/TeleInfo.ino index 1966cbb..c498f4e 100644 --- a/sensors/TeleInfo/TeleInfo.ino +++ b/sensors/TeleInfo/TeleInfo.ino @@ -4,20 +4,25 @@ * Version 1.0 */ - -/* - * TODO : Gestion du temps pour n'envoyer que toute les minutes (ou un truc du genre) - */ #include +#define startFrame 0x02 +#define endFrame 0x03 +#define startLine 0x0A +#define endLine 0x0D +#define space 0x20 //---------------------------------------------------- +/* const char* ssid = "TNCAP3F2E03"; const char* password = "73ABCCAA87"; +*/ +const char* ssid = "L0AD"; +const char* password = ""; -//const char* host = "datahouse.kingpenguin.tk"; -const char* host = "192.168.1.143"; -const int httpPort = 8080; + +const char* host = "datahouse.kingpenguin.tk"; +const int httpPort = 80; const int DEFAULT_INTERVAL = 60000; // 60 sec //---------------------------------------------------- @@ -37,7 +42,7 @@ void sleepSec(int sec) { -long nextInterval; +long nextInterval = millis() + DEFAULT_INTERVAL; void sendDataToServer() { // Use WiFiClient class to create TCP connections @@ -46,18 +51,12 @@ void sendDataToServer() { Serial.print("connection failed on host "); Serial.print(host); Serial.print(":"); - Serial.println(host); + Serial.println(httpPort); 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); @@ -85,6 +84,19 @@ void sendDataToServer() { nextInterval = millis() + nextInterval; } +bool isDigitSelf(char c) { + return c >= 48 && c <= 57; +} + +bool isNumberSelf(String s) { + for (int i=0; i<(s.length()); i++){ + if (!isDigitSelf(s[i])) { + return false; + } + } + return true; +} + void setup() { Serial.begin(1200); @@ -110,48 +122,79 @@ void setup() { Serial.println(WiFi.localIP()); } +String label = ""; +String value = ""; +char checksum = 0; + +void GetTeleInfo() { + String TeleInfo = ""; + char charIn = 0; + + int index = 0; // 0 - label ; 1 - value ; 2 - checksum + label = ""; + value = ""; + checksum = 0; + + if (Serial.available() > 0) { + while (charIn != startLine) { + charIn = Serial.read() & 0x7F; + } + while (charIn != endLine) { + // label + if (Serial.available() > 0) { + charIn = Serial.read() & 0x7F; + if (charIn != space) { + if (index == 0) { + label += charIn; + } else if (index == 1) { + value += charIn; + } else if (index == 2) { + checksum = charIn; + index++; + } + } else { + index++; + } + } + } + } +} + + +bool checkSumVerif() { + char sum=0; + String trame = label + " " + value; + for (int i=0; i<(trame.length()); i++){ + sum += trame[i]; + } + sum = (sum & 0x3F) + 0x20; + return sum == checksum; +} + void loop() { - if (Serial.available() > 0) { - String str = Serial.readStringUntil('\n'); + GetTeleInfo(); + if (checkSumVerif()) { + Serial.println(label+" "+value+" "+checksum); + + if (label == "ADCO" && isNumberSelf(value)) { + ADCO = value; + } + if (label == "OPTARIF") { + OPTARIF = value; + } + if (label == "BASE") { + BASE = value; + } + if (label == "HCHC" && isNumberSelf(value)) { + HCHC = value; + } + if (label == "HCHP" && isNumberSelf(value)) { + HCHP = value; + } + 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(); - } + sendDataToServer(); } } } diff --git a/views/base/navbar.html b/views/base/navbar.html index 1cf0bed..38410f3 100644 --- a/views/base/navbar.html +++ b/views/base/navbar.html @@ -16,7 +16,7 @@ {{if .IsViewTemp}} class="active" {{end}} - >Temperatures + >Températures