Compare commits
10 Commits
7113e69a91
...
b387657f5a
| Author | SHA1 | Date |
|---|---|---|
|
|
b387657f5a | |
|
|
213e1305d9 | |
|
|
8378253574 | |
|
|
aa1259b3dc | |
|
|
c8ebf02e30 | |
|
|
87891cfd0d | |
|
|
f4ed7afc59 | |
|
|
2e630d4fe1 | |
|
|
a804cc70f5 | |
|
|
84d7c000ae |
|
|
@ -2,10 +2,12 @@ appname = DataHouse
|
||||||
httpport = 8080
|
httpport = 8080
|
||||||
runmode = dev
|
runmode = dev
|
||||||
|
|
||||||
mysqluser = "root"
|
database = mysql
|
||||||
mysqlpass = "toto"
|
mysqluser = "datahouse_user"
|
||||||
|
mysqlpass = "datahouse_user_password"
|
||||||
mysqlurls = "127.0.0.1"
|
mysqlurls = "127.0.0.1"
|
||||||
mysqldb = "orm_test"
|
mysqldb = "datahouse"
|
||||||
|
row_limit = 100000
|
||||||
|
|
||||||
sessionon = true
|
sessionon = true
|
||||||
SessionProvider = memory
|
SessionProvider = memory
|
||||||
|
|
@ -16,4 +18,7 @@ SessionCookieLifeTime = 3600
|
||||||
|
|
||||||
JID = test@kingpenguin.tk
|
JID = test@kingpenguin.tk
|
||||||
PWD = test
|
PWD = test
|
||||||
|
SERVER = 51.254.205.203
|
||||||
PORT = 5222
|
PORT = 5222
|
||||||
|
TIMER_PING = 60
|
||||||
|
XMPP_DEBUG = true
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
|
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/notification"
|
||||||
"git.kingpenguin.tk/chteufleur/datahouse.git/models/sensor"
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/sensor"
|
||||||
"git.kingpenguin.tk/chteufleur/datahouse.git/models/temperature"
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/temperature"
|
||||||
temperatureTmp "git.kingpenguin.tk/chteufleur/datahouse.git/models/temperature/temp"
|
temperatureTmp "git.kingpenguin.tk/chteufleur/datahouse.git/models/temperature/temp"
|
||||||
|
|
@ -38,6 +39,14 @@ func (c *AddTempController) Get() {
|
||||||
s = sensor.GetSensorByMac(mac)
|
s = sensor.GetSensorByMac(mac)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notification treatment
|
||||||
|
for _, notifId := range s.GetNotificationsIds() {
|
||||||
|
notif := notification.GetNotificationCondition(notifId)
|
||||||
|
if notif != nil {
|
||||||
|
notif.Notify(int64(val), s.GetName()+": "+valStr+"°C")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addToTempBdd(s, val)
|
addToTempBdd(s, val)
|
||||||
saveInBDD(s, val)
|
saveInBDD(s, val)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,8 +51,9 @@ func (c *LoginController) Post() {
|
||||||
|
|
||||||
login := c.GetString("login")
|
login := c.GetString("login")
|
||||||
passwd := c.GetString("password")
|
passwd := c.GetString("password")
|
||||||
|
token := c.GetString("token")
|
||||||
|
|
||||||
if !isLoginOK(login, passwd) {
|
if !isLoginOK(login, passwd, token) {
|
||||||
c.Abort("403")
|
c.Abort("403")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +65,7 @@ func (c *LoginController) Post() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isLoginOK(lgn, pwd string) bool {
|
func isLoginOK(lgn, pwd, token string) bool {
|
||||||
ret := false
|
ret := false
|
||||||
usr := user.GetUserByLogin(lgn)
|
usr := user.GetUserByLogin(lgn)
|
||||||
if usr.Id == 0 {
|
if usr.Id == 0 {
|
||||||
|
|
@ -74,9 +75,9 @@ func isLoginOK(lgn, pwd string) bool {
|
||||||
log.Info("Standard auth")
|
log.Info("Standard auth")
|
||||||
ret = pwd != "" && pwd == usr.Password
|
ret = pwd != "" && pwd == usr.Password
|
||||||
|
|
||||||
if !ret && usr.JID != "" {
|
if !ret && usr.JID != "" && token != "" {
|
||||||
log.Info("Auth by JID")
|
log.Info("Auth by JID")
|
||||||
resp, _ := http.Get(UrlXmppAuth + "?domain=datahouse.kingpenguin.tk&method=POST&jid=" + usr.JID + "&transaction_id=datahouse")
|
resp, _ := http.Get(UrlXmppAuth + "?domain=datahouse.kingpenguin.tk&method=POST&jid=" + usr.JID + "&transaction_id=" + token)
|
||||||
httpStatusCode := resp.StatusCode
|
httpStatusCode := resp.StatusCode
|
||||||
if resp != nil && httpStatusCode == 200 {
|
if resp != nil && httpStatusCode == 200 {
|
||||||
ret = true
|
ret = true
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,124 @@
|
||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego"
|
||||||
|
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/notification"
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/sensor"
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/user"
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/variables"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NotificationsController struct {
|
||||||
|
beego.Controller
|
||||||
|
}
|
||||||
|
|
||||||
|
type NotificationView struct {
|
||||||
|
Id int64
|
||||||
|
Condition string
|
||||||
|
Value int64
|
||||||
|
Sensor string
|
||||||
|
}
|
||||||
|
|
||||||
|
type SensorView struct {
|
||||||
|
MAC string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *NotificationsController) Prepare() {
|
||||||
|
sess := c.GetSession(variables.SessionName)
|
||||||
|
if sess == nil {
|
||||||
|
c.Redirect(variables.LoginRouteNoRegex+variables.UserRoute, 302)
|
||||||
|
} else {
|
||||||
|
c.Data["IsAuthentificated"] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Data["IsNotifications"] = true
|
||||||
|
c.Data["version"] = variables.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *NotificationsController) Get() {
|
||||||
|
var notifications []NotificationView
|
||||||
|
var notifIds []int64
|
||||||
|
u := c.getUserLogin()
|
||||||
|
if u != nil {
|
||||||
|
notif := notification.GetNotificationConditionByUser(u.Id)
|
||||||
|
for _, nv := range notif {
|
||||||
|
n := new(NotificationView)
|
||||||
|
n.Id = nv.Id
|
||||||
|
n.Condition = nv.Condition
|
||||||
|
n.Value = nv.Value
|
||||||
|
|
||||||
|
sensr := sensor.GetSensorByNotificationId(n.Id)
|
||||||
|
if sensr != nil {
|
||||||
|
n.Sensor = sensr.GetName()
|
||||||
|
notifications = append(notifications, *n)
|
||||||
|
notifIds = append(notifIds, n.Id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.Data["notifications"] = notifications
|
||||||
|
|
||||||
|
var snsrs []SensorView
|
||||||
|
sensors := sensor.GetAllSensor()
|
||||||
|
for _, s := range sensors {
|
||||||
|
snsrs = append(snsrs, SensorView{MAC: s.SensorMAC, Name: s.GetName()})
|
||||||
|
}
|
||||||
|
c.Data["sensors"] = snsrs
|
||||||
|
|
||||||
|
c.TplName = "notifications.tpl"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *NotificationsController) Post() {
|
||||||
|
u := c.getUserLogin()
|
||||||
|
|
||||||
|
action := c.Input().Get("action")
|
||||||
|
notifIdStr := c.Input().Get("id")
|
||||||
|
condition := c.Input().Get("condition")
|
||||||
|
valueStr := c.Input().Get("value")
|
||||||
|
sensMAC := c.Input().Get("sensor-mac")
|
||||||
|
|
||||||
|
notifId, errNotifId := strconv.ParseInt(notifIdStr, 10, 64)
|
||||||
|
value, errValue := strconv.ParseInt(valueStr, 10, 64)
|
||||||
|
|
||||||
|
if action == "modif" && errNotifId == nil && errValue == nil {
|
||||||
|
if notification.UpdateNotificationCondition(notifId, u.Id, condition, value) == nil {
|
||||||
|
oldSensor := sensor.GetSensorByNotificationId(notifId)
|
||||||
|
newSensor := sensor.GetSensorByMac(sensMAC)
|
||||||
|
if oldSensor.Id != 0 && newSensor.Id != 0 && oldSensor.Id != newSensor.Id {
|
||||||
|
oldSensor.DeleteNotification(notifId)
|
||||||
|
newSensor.AddNotification(notifId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if action == "delete" && errNotifId == nil && errValue == nil {
|
||||||
|
notification.DeleteNotificationCondition(notifId)
|
||||||
|
sens := sensor.GetSensorByNotificationId(notifId)
|
||||||
|
if sens.Id != 0 {
|
||||||
|
sens.DeleteNotification(notifId)
|
||||||
|
}
|
||||||
|
} else if action == "add" && errValue == nil {
|
||||||
|
sens := sensor.GetSensorByMac(sensMAC)
|
||||||
|
if sens.Id != 0 {
|
||||||
|
notifId, err := notification.AddNotificationCondition(u.Id, condition, value)
|
||||||
|
if err == nil {
|
||||||
|
sens.AddNotification(notifId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Redirect(variables.NotificationsRoute, 302)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *NotificationsController) getUserLogin() *user.User {
|
||||||
|
ret := new(user.User)
|
||||||
|
|
||||||
|
login := c.GetSession(variables.SessionName)
|
||||||
|
switch lo := login.(type) {
|
||||||
|
case string:
|
||||||
|
ret = user.GetUserByLogin(lo)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
//——————————————————————————————————————————————————————————————————————————————
|
//——————————————————————————————————————————————————————————————————————————————
|
||||||
|
|
@ -62,7 +63,8 @@ func (c *ViewTeleinfoController) Prepare() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *ViewTeleinfoController) Get() {
|
func (c *ViewTeleinfoController) Get() {
|
||||||
c.Data["compteurs"] = teleinfo.GetAllCompteur()
|
compteurs := teleinfo.GetAllCompteur()
|
||||||
|
c.Data["compteurs"] = compteurs
|
||||||
|
|
||||||
adresse := c.Ctx.Input.Param(":compteur")
|
adresse := c.Ctx.Input.Param(":compteur")
|
||||||
cpt := teleinfo.GetCompteurByAdresse(adresse)
|
cpt := teleinfo.GetCompteurByAdresse(adresse)
|
||||||
|
|
@ -75,13 +77,47 @@ func (c *ViewTeleinfoController) Get() {
|
||||||
desc = cpt.AdresseCompteur
|
desc = cpt.AdresseCompteur
|
||||||
}
|
}
|
||||||
c.Data["compteurDescription"] = desc
|
c.Data["compteurDescription"] = desc
|
||||||
dataPower := formatDataSensorTeleInfo(teleinfo.GetAllDataForCompteur(cpt.AdresseCompteur))
|
compteurs := teleinfo.GetAllDataForCompteur(cpt.AdresseCompteur)
|
||||||
|
c.Data["lastHorodate"] = getHorodateHighchart(compteurs[len(compteurs)-1].HorodateGMT)
|
||||||
|
dataPower := formatDataSensorTeleInfo(compteurs)
|
||||||
c.Data["dataPower"] = template.JS(dataPower)
|
c.Data["dataPower"] = template.JS(dataPower)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.TplName = "teleinfo.tpl"
|
c.TplName = "teleinfo.tpl"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *ViewTeleinfoController) Post() {
|
||||||
|
currentTimeStr := c.GetString("currentTime")
|
||||||
|
adresse := c.Ctx.Input.Param(":compteur")
|
||||||
|
currentTime, err := strconv.ParseInt(currentTimeStr, 10, 64)
|
||||||
|
if err == nil {
|
||||||
|
dateGMT := time.Unix(currentTime/1000-int64(timezoneOffset), 0)
|
||||||
|
data := teleinfo.GetNextData(adresse, dateGMT)
|
||||||
|
dataStr := formatDataToJsonTeleInfo(data)
|
||||||
|
c.Ctx.Output.Body([]byte(dataStr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHorodateHighchart(date time.Time) string {
|
||||||
|
return strconv.FormatInt((date.Unix()+int64(timezoneOffset))*1000, 10)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatDataToJsonTeleInfo(values []teleinfo.TeleinfoTable) string {
|
||||||
|
ret := ""
|
||||||
|
ret += "{\"values\": ["
|
||||||
|
for i := 0; i < len(values); i++ {
|
||||||
|
if i > 0 {
|
||||||
|
ret += ","
|
||||||
|
}
|
||||||
|
horodate := getHorodateHighchart(values[i].HorodateGMT)
|
||||||
|
value := strconv.FormatInt(values[i].PuissanceApparente, 10)
|
||||||
|
ret += "[" + horodate + "," + value + "]"
|
||||||
|
}
|
||||||
|
ret += "]}"
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func formatDataSensorTeleInfo(values []teleinfo.TeleinfoTable) string {
|
func formatDataSensorTeleInfo(values []teleinfo.TeleinfoTable) string {
|
||||||
ret := ""
|
ret := ""
|
||||||
ret += "{name : \"Puissance apparente (VA)\",marker : {enabled : true, radius : 3}, data : ["
|
ret += "{name : \"Puissance apparente (VA)\",marker : {enabled : true, radius : 3}, data : ["
|
||||||
|
|
|
||||||
6
main.go
6
main.go
|
|
@ -62,7 +62,7 @@ func main() {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
models.ChanRuns <- watchlog.EndRun
|
models.ChanRuns <- watchlog.EndRun
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
// models.ChanRuns <- xmpp_manager.EndRun
|
go xmpp_manager.Run()
|
||||||
|
|
||||||
beego.Run()
|
beego.Run()
|
||||||
}
|
}
|
||||||
|
|
@ -72,10 +72,6 @@ func reborn() {
|
||||||
action := <-models.ChanRuns
|
action := <-models.ChanRuns
|
||||||
|
|
||||||
switch action {
|
switch action {
|
||||||
case xmpp_manager.EndRun:
|
|
||||||
go xmpp_manager.Run()
|
|
||||||
log.Info("XMPP Started")
|
|
||||||
|
|
||||||
case watchlog.EndRun:
|
case watchlog.EndRun:
|
||||||
go watchlog.Run()
|
go watchlog.Run()
|
||||||
log.Info("Watchlog Started")
|
log.Info("Watchlog Started")
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,167 @@
|
||||||
|
package notification
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/orm"
|
||||||
|
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/xmpp"
|
||||||
|
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/database"
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/user"
|
||||||
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
UPPER = ">"
|
||||||
|
UPPER_OR_EQUALS = ">="
|
||||||
|
LOWER = "<"
|
||||||
|
LOWER_OR_EQUALS = "<="
|
||||||
|
EQUALS = "=="
|
||||||
|
NOT_EQUALS = "!="
|
||||||
|
)
|
||||||
|
|
||||||
|
type NotificationCondition struct {
|
||||||
|
Id int64
|
||||||
|
UserId int64
|
||||||
|
Condition string
|
||||||
|
Value int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
orm.RegisterModel(new(NotificationCondition))
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddNotificationCondition(userId int64, condition string, value int64) (int64, error) {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
return o.Insert(&NotificationCondition{UserId: userId, Condition: condition, Value: value})
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateNotificationCondition(id, userId int64, condition string, value int64) error {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
|
||||||
|
n := GetNotificationCondition(id)
|
||||||
|
if o.Read(n) == nil {
|
||||||
|
n.UserId = userId
|
||||||
|
n.Condition = condition
|
||||||
|
n.Value = value
|
||||||
|
_, err := o.Update(n)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DeleteNotificationCondition(id int64) {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
o.Delete(&NotificationCondition{Id: id})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAllNotificationConditionIds() []int64 {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
|
||||||
|
notif := new(NotificationCondition)
|
||||||
|
var ret []int64
|
||||||
|
var maps []orm.Params
|
||||||
|
_, err := o.QueryTable(notif).Values(&maps)
|
||||||
|
if err == nil {
|
||||||
|
for _, m := range maps {
|
||||||
|
ret = append(ret, utils.GetInt(m, "Id"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAllNotificationCondition() []NotificationCondition {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
|
||||||
|
notif := new(NotificationCondition)
|
||||||
|
var maps []orm.Params
|
||||||
|
var ret []NotificationCondition
|
||||||
|
_, err := o.QueryTable(notif).Values(&maps)
|
||||||
|
if err == nil {
|
||||||
|
for _, m := range maps {
|
||||||
|
n := new(NotificationCondition)
|
||||||
|
n.Id = utils.GetInt(m, "Id")
|
||||||
|
n.UserId = utils.GetInt(m, "UserId")
|
||||||
|
n.Condition = utils.GetString(m, "Condition")
|
||||||
|
n.Value = utils.GetInt(m, "Value")
|
||||||
|
ret = append(ret, *n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetNotificationConditionByUser(idUser int64) []NotificationCondition {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
|
||||||
|
var ret []NotificationCondition
|
||||||
|
var maps []orm.Params
|
||||||
|
_, err := o.QueryTable(new(NotificationCondition)).Filter("UserId", idUser).Values(&maps)
|
||||||
|
if err == nil {
|
||||||
|
for _, m := range maps {
|
||||||
|
n := new(NotificationCondition)
|
||||||
|
n.Id = utils.GetInt(m, "Id")
|
||||||
|
n.UserId = utils.GetInt(m, "UserId")
|
||||||
|
n.Condition = utils.GetString(m, "Condition")
|
||||||
|
n.Value = utils.GetInt(m, "Value")
|
||||||
|
ret = append(ret, *n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetNotificationCondition(id int64) *NotificationCondition {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
|
||||||
|
var ret = new(NotificationCondition)
|
||||||
|
var maps []orm.Params
|
||||||
|
_, err := o.QueryTable(new(NotificationCondition)).Filter("Id", id).Values(&maps)
|
||||||
|
if err == nil {
|
||||||
|
for _, m := range maps {
|
||||||
|
ret.Id = utils.GetInt(m, "Id")
|
||||||
|
ret.UserId = utils.GetInt(m, "UserId")
|
||||||
|
ret.Condition = utils.GetString(m, "Condition")
|
||||||
|
ret.Value = utils.GetInt(m, "Value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NotificationCondition) IsConditionValidate(val int64) bool {
|
||||||
|
ret := false
|
||||||
|
|
||||||
|
if n.Condition == UPPER {
|
||||||
|
ret = (val > n.Value)
|
||||||
|
} else if n.Condition == UPPER_OR_EQUALS {
|
||||||
|
ret = (val >= n.Value)
|
||||||
|
} else if n.Condition == LOWER {
|
||||||
|
ret = (val < n.Value)
|
||||||
|
} else if n.Condition == LOWER_OR_EQUALS {
|
||||||
|
ret = (val <= n.Value)
|
||||||
|
} else if n.Condition == EQUALS {
|
||||||
|
ret = (val == n.Value)
|
||||||
|
} else if n.Condition == NOT_EQUALS {
|
||||||
|
ret = (val != n.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NotificationCondition) Notify(val int64, message string) {
|
||||||
|
if n.IsConditionValidate(val) {
|
||||||
|
u := user.GetUser(n.UserId)
|
||||||
|
if u != nil && u.JID != "" {
|
||||||
|
xmpp_manager.SendMessage(u.JID, "", "["+n.Condition+" "+strconv.FormatInt(n.Value, 10)+"] "+message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,17 +1,25 @@
|
||||||
package sensor
|
package sensor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/astaxie/beego/orm"
|
"github.com/astaxie/beego/orm"
|
||||||
|
|
||||||
"git.kingpenguin.tk/chteufleur/datahouse.git/models/database"
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/database"
|
||||||
"git.kingpenguin.tk/chteufleur/datahouse.git/models/utils"
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
NOTIFICATION_DELIMITER = ","
|
||||||
|
)
|
||||||
|
|
||||||
type SensorTable struct {
|
type SensorTable struct {
|
||||||
Id int64
|
Id int64
|
||||||
SensorMAC string
|
SensorMAC string
|
||||||
Description string
|
Description string
|
||||||
Interval int64
|
Interval int64
|
||||||
|
Notifications string
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -32,6 +40,7 @@ func GetSensorByMac(sensorMac string) *SensorTable {
|
||||||
ret.SensorMAC = utils.GetString(m, "SensorMAC")
|
ret.SensorMAC = utils.GetString(m, "SensorMAC")
|
||||||
ret.Description = utils.GetString(m, "Description")
|
ret.Description = utils.GetString(m, "Description")
|
||||||
ret.Interval = utils.GetInt(m, "Interval")
|
ret.Interval = utils.GetInt(m, "Interval")
|
||||||
|
ret.Notifications = utils.GetString(m, "Notifications")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -70,6 +79,7 @@ func GetAllSensor() []SensorTable {
|
||||||
r.SensorMAC = utils.GetString(m, "SensorMAC")
|
r.SensorMAC = utils.GetString(m, "SensorMAC")
|
||||||
r.Description = utils.GetString(m, "Description")
|
r.Description = utils.GetString(m, "Description")
|
||||||
r.Interval = utils.GetInt(m, "Interval")
|
r.Interval = utils.GetInt(m, "Interval")
|
||||||
|
r.Notifications = utils.GetString(m, "Notifications")
|
||||||
|
|
||||||
ret = append(ret, *r)
|
ret = append(ret, *r)
|
||||||
}
|
}
|
||||||
|
|
@ -91,6 +101,19 @@ func GetSensor(id int64) *SensorTable {
|
||||||
ret.SensorMAC = utils.GetString(m, "SensorMAC")
|
ret.SensorMAC = utils.GetString(m, "SensorMAC")
|
||||||
ret.Description = utils.GetString(m, "Description")
|
ret.Description = utils.GetString(m, "Description")
|
||||||
ret.Interval = utils.GetInt(m, "Interval")
|
ret.Interval = utils.GetInt(m, "Interval")
|
||||||
|
ret.Notifications = utils.GetString(m, "Notifications")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetSensorByNotificationId(notifId int64) *SensorTable {
|
||||||
|
var ret *SensorTable = nil
|
||||||
|
allSensors := GetAllSensor()
|
||||||
|
for _, s := range allSensors {
|
||||||
|
if s.IsContainNotificationId(notifId) {
|
||||||
|
ret = &s
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
|
|
@ -108,6 +131,33 @@ func UpdateSensor(mac, description string, interval int64) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ss *SensorTable) update() {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
|
||||||
|
mac := ss.SensorMAC
|
||||||
|
s := GetSensorByMac(mac)
|
||||||
|
if o.Read(s) == nil {
|
||||||
|
s.Description = ss.Description
|
||||||
|
s.Interval = ss.Interval
|
||||||
|
s.Notifications = ss.Notifications
|
||||||
|
o.Update(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateSensorWithNotifications(mac, description string, interval int64, notifications string) {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
|
||||||
|
s := GetSensorByMac(mac)
|
||||||
|
if o.Read(s) == nil {
|
||||||
|
s.Description = description
|
||||||
|
s.Interval = interval
|
||||||
|
s.Notifications = notifications
|
||||||
|
o.Update(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func AddSensor(sensorMac string) {
|
func AddSensor(sensorMac string) {
|
||||||
o := orm.NewOrm()
|
o := orm.NewOrm()
|
||||||
o.Using(database.Alias)
|
o.Using(database.Alias)
|
||||||
|
|
@ -125,3 +175,58 @@ func DeleteSensor(sensorId int64) {
|
||||||
o.Using(database.Alias)
|
o.Using(database.Alias)
|
||||||
o.Delete(&SensorTable{Id: sensorId})
|
o.Delete(&SensorTable{Id: sensorId})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SensorTable) GetName() string {
|
||||||
|
ret := s.Description
|
||||||
|
if s.Description == "" {
|
||||||
|
ret = s.SensorMAC
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SensorTable) GetNotificationsIds() []int64 {
|
||||||
|
var ret []int64
|
||||||
|
for _, idStr := range strings.Split(s.Notifications, NOTIFICATION_DELIMITER) {
|
||||||
|
id, err := strconv.Atoi(idStr)
|
||||||
|
if err == nil {
|
||||||
|
ret = append(ret, int64(id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SensorTable) IsContainNotificationId(idNotif int64) bool {
|
||||||
|
for _, b := range strings.Split(s.Notifications, NOTIFICATION_DELIMITER) {
|
||||||
|
bb, err := strconv.Atoi(b)
|
||||||
|
if err == nil && int64(bb) == idNotif {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SensorTable) AddNotification(notifId int64) {
|
||||||
|
if s.Notifications != "" {
|
||||||
|
s.Notifications += NOTIFICATION_DELIMITER
|
||||||
|
}
|
||||||
|
s.Notifications += strconv.FormatInt(notifId, 10)
|
||||||
|
s.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SensorTable) DeleteNotification(notifId int64) {
|
||||||
|
newNotificationStr := ""
|
||||||
|
for _, idStr := range strings.Split(s.Notifications, NOTIFICATION_DELIMITER) {
|
||||||
|
id, err := strconv.Atoi(idStr)
|
||||||
|
if err == nil {
|
||||||
|
if int64(id) != notifId {
|
||||||
|
if newNotificationStr != "" {
|
||||||
|
newNotificationStr += NOTIFICATION_DELIMITER
|
||||||
|
}
|
||||||
|
newNotificationStr += idStr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Notifications = newNotificationStr
|
||||||
|
s.update()
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,38 @@ func GetLastDataForCompteur(adresseCompteur string) *TeleinfoTable {
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetNextData(addressCompteur string, from time.Time) []TeleinfoTable {
|
||||||
|
o := orm.NewOrm()
|
||||||
|
o.Using(database.Alias)
|
||||||
|
|
||||||
|
var dataArray []TeleinfoTable
|
||||||
|
var maps []orm.Params
|
||||||
|
_, err := o.QueryTable(new(TeleinfoTable)).Filter("AdresseCompteur", addressCompteur).Filter("HorodateGMT__gt", from).OrderBy("HorodateGMT").Values(&maps)
|
||||||
|
if err == nil {
|
||||||
|
for _, m := range maps {
|
||||||
|
dataTime := utils.GetTime(m, "HorodateGMT")
|
||||||
|
if dataTime.After(from) {
|
||||||
|
d := new(TeleinfoTable)
|
||||||
|
d.Id = utils.GetInt(m, "Id")
|
||||||
|
d.HorodateGMT = dataTime
|
||||||
|
|
||||||
|
d.AdresseCompteur = utils.GetString(m, "AdresseCompteur")
|
||||||
|
d.OptionTarifaire = optionTarifaireTranslate[utils.GetString(m, "OptionTarifaire")]
|
||||||
|
d.OptionBase = utils.GetInt(m, "OptionBase")
|
||||||
|
|
||||||
|
d.IntensiteSouscrite = utils.GetInt(m, "IntensiteSouscrite")
|
||||||
|
d.IntensiteInstantanne = utils.GetInt(m, "IntensiteInstantanne")
|
||||||
|
d.IntensiteMax = utils.GetInt(m, "IntensiteMax")
|
||||||
|
|
||||||
|
d.PuissanceApparente = utils.GetInt(m, "PuissanceApparente")
|
||||||
|
|
||||||
|
dataArray = append(dataArray, *d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dataArray
|
||||||
|
}
|
||||||
|
|
||||||
func DeleteDataCompteur(adresseCompteur string) {
|
func DeleteDataCompteur(adresseCompteur string) {
|
||||||
o := orm.NewOrm()
|
o := orm.NewOrm()
|
||||||
o.Using(database.Alias)
|
o.Using(database.Alias)
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,9 @@ type TempTable struct {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
timezoneName, timezoneOffset = time.Now().Zone()
|
timezoneName, timezoneOffset = time.Now().Zone()
|
||||||
timezoneLocation = time.FixedZone(timezoneName, timezoneOffset)
|
timezoneLocation = time.FixedZone(timezoneName, timezoneOffset)
|
||||||
deltaTimeCompressData = 1440 * time.Hour
|
deltaTimeCompressData = 1440 * time.Hour
|
||||||
log = logs.NewLogger(10000)
|
log = logs.NewLogger(10000)
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -46,19 +46,19 @@ func AddData(sensor, value int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddDataWithHorodate(id, sensor, value int64, horodateGMT time.Time) {
|
func AddDataWithHorodate(id, sensor, value int64, horodateGMT time.Time) {
|
||||||
log.Info("Add Temperature {sensor: %s, value: %d, horodateGNT: %v}", sensor, value, horodateGMT)
|
log.Info("Add Temperature {sensor: %s, value: %d, horodateGNT: %v}", sensor, value, horodateGMT)
|
||||||
o := orm.NewOrm()
|
o := orm.NewOrm()
|
||||||
o.Using(database.Alias)
|
o.Using(database.Alias)
|
||||||
|
|
||||||
tmpTable := new(TempTable)
|
tmpTable := new(TempTable)
|
||||||
tmpTable.Id = id
|
tmpTable.Id = id
|
||||||
tmpTable.Value = value
|
tmpTable.Value = value
|
||||||
tmpTable.SensorID = sensor
|
tmpTable.SensorID = sensor
|
||||||
tmpTable.HorodateGMT = horodateGMT
|
tmpTable.HorodateGMT = horodateGMT
|
||||||
_, err := o.Insert(tmpTable)
|
_, err := o.Insert(tmpTable)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("Error on insert temperature ", err)
|
log.Info("Error on insert temperature ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAllTempForSensor(sensorId int64) []TempTable {
|
func GetAllTempForSensor(sensorId int64) []TempTable {
|
||||||
|
|
@ -112,8 +112,8 @@ func DeleteTemperatureBySenor(sensorId int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteTemperatureById(tempId int64) {
|
func DeleteTemperatureById(tempId int64) {
|
||||||
log.Info("Delete temperatures id : %d", tempId)
|
log.Info("Delete temperatures id : %d", tempId)
|
||||||
o := orm.NewOrm()
|
o := orm.NewOrm()
|
||||||
o.Using(database.Alias)
|
o.Using(database.Alias)
|
||||||
o.Delete(&TempTable{Id: tempId})
|
o.Delete(&TempTable{Id: tempId})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,14 @@ package utils
|
||||||
import (
|
import (
|
||||||
"github.com/astaxie/beego/orm"
|
"github.com/astaxie/beego/orm"
|
||||||
|
|
||||||
|
"crypto/rand"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
dictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||||
|
)
|
||||||
|
|
||||||
func GetString(m orm.Params, param string) string {
|
func GetString(m orm.Params, param string) string {
|
||||||
ret := ""
|
ret := ""
|
||||||
switch i := m[param].(type) {
|
switch i := m[param].(type) {
|
||||||
|
|
@ -38,3 +43,14 @@ func GetTime(m orm.Params, param string) time.Time {
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TokenGenerator(length int) string {
|
||||||
|
var bytes = make([]byte, length)
|
||||||
|
if _, err := rand.Read(bytes); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
for k, v := range bytes {
|
||||||
|
bytes[k] = dictionary[v%byte(len(dictionary))]
|
||||||
|
}
|
||||||
|
return string(bytes)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,17 +14,17 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
/*
|
/*
|
||||||
————————————————————————————————————————————————————————————————————————————————
|
————————————————————————————————————————————————————————————————————————————————
|
||||||
Routes
|
Routes
|
||||||
————————————————————————————————————————————————————————————————————————————————
|
————————————————————————————————————————————————————————————————————————————————
|
||||||
*/
|
*/
|
||||||
RootRoute = "/"
|
RootRoute = "/"
|
||||||
|
|
||||||
AddTempRoute = "/add/temp/" + sensorMacRegex + "/:val([0-9]+)"
|
AddTempRoute = "/add/temp/" + sensorMacRegex + "/:val([-]{0,1}[0-9]+)"
|
||||||
AddRelayRoute = "/add/relay/" + sensorMacRegex
|
AddRelayRoute = "/add/relay/" + sensorMacRegex
|
||||||
TeleinfoAddRoute = "/teleinfo/add"
|
TeleinfoAddRoute = "/teleinfo/add"
|
||||||
AddSoilMoistRoute = "/add/soil" /* Route for soil moisture sensors*/
|
AddSoilMoistRoute = "/add/soil" /* Route for soil moisture sensors*/
|
||||||
|
|
||||||
ViewTempRoute = "/view/temp"
|
ViewTempRoute = "/view/temp"
|
||||||
ViewRelaysRoute = "/view/relay"
|
ViewRelaysRoute = "/view/relay"
|
||||||
|
|
@ -34,19 +34,19 @@ var (
|
||||||
ViewLogRoute = "/view/log"
|
ViewLogRoute = "/view/log"
|
||||||
WebSocketLogRoute = "/view/log/join"
|
WebSocketLogRoute = "/view/log/join"
|
||||||
|
|
||||||
CommandRelayRoute = "/command/relay/" + sensorMacRegex
|
CommandRelayRoute = "/command/relay/" + sensorMacRegex
|
||||||
|
|
||||||
SensorsRoute = "/sensors"
|
SensorsRoute = "/sensors"
|
||||||
LoginRoute = "/login/:route(.*)"
|
LoginRoute = "/login/:route(.*)"
|
||||||
LoginRouteNoRegex = "/login"
|
LoginRouteNoRegex = "/login"
|
||||||
UserRoute = "/user"
|
UserRoute = "/user"
|
||||||
|
NotificationsRoute = "/notifications"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
————————————————————————————————————————————————————————————————————————————————
|
————————————————————————————————————————————————————————————————————————————————
|
||||||
Logs
|
Logs
|
||||||
————————————————————————————————————————————————————————————————————————————————
|
————————————————————————————————————————————————————————————————————————————————
|
||||||
*/
|
*/
|
||||||
LogType = logFile
|
LogType = logFile
|
||||||
LogParams = "{\""+LogFileName+"\":\""+LogFilePath+"\"}"
|
LogParams = "{\"" + LogFileName + "\":\"" + LogFilePath + "\"}"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -28,5 +28,6 @@ func init() {
|
||||||
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{})
|
||||||
|
beego.Router(variables.NotificationsRoute, &controllers.NotificationsController{})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@
|
||||||
class="active"
|
class="active"
|
||||||
{{end}}
|
{{end}}
|
||||||
><a href="/user">Utilisateur</a></li>
|
><a href="/user">Utilisateur</a></li>
|
||||||
|
<li
|
||||||
|
{{if .IsNotifications}}
|
||||||
|
class="active"
|
||||||
|
{{end}}
|
||||||
|
><a href="/notifications">Notifications</a></li>
|
||||||
{{end}}
|
{{end}}
|
||||||
<li
|
<li
|
||||||
{{if .IsSensor}}
|
{{if .IsSensor}}
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,16 @@
|
||||||
<form id="loginForm" class="form-signin" action="/login" method="POST">
|
<form id="loginForm" class="form-signin" action="/login" method="POST">
|
||||||
<h2 class="form-signin-heading">Login</h2>
|
<h2 class="form-signin-heading">Login</h2>
|
||||||
<label for="inputEmail" class="sr-only">Email address</label>
|
<label for="inputEmail" class="sr-only">Email address</label>
|
||||||
<input id="inputLogin" name="login" class="form-control" placeholder="Login" required autofocus>
|
<input name="token" type="hidden" id="token-value" value="" />
|
||||||
|
<input id="inputLogin" name="login" class="form-control" placeholder="Login" required autofocus />
|
||||||
<label for="inputPassword" class="sr-only">Password</label>
|
<label for="inputPassword" class="sr-only">Password</label>
|
||||||
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" required>
|
<input type="password" id="inputPassword" name="password" class="form-control" placeholder="Password" />
|
||||||
<!-- <div class="checkbox">
|
<!-- <div class="checkbox">
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" value="remember-me"> Remember me
|
<input type="checkbox" value="remember-me"> Remember me
|
||||||
</label>
|
</label>
|
||||||
</div> -->
|
</div> -->
|
||||||
|
<center><p id="token-value-txt"></p></center>
|
||||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Laisse moi entrer</button>
|
<button class="btn btn-lg btn-primary btn-block" type="submit">Laisse moi entrer</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
@ -51,8 +53,14 @@
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
|
||||||
<script src="/static/js/jquery.sha256.min.js"></script>
|
<script src="/static/js/jquery.sha256.min.js"></script>
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
|
var rand = function() {
|
||||||
|
return Math.random().toString(36).substr(2);
|
||||||
|
}
|
||||||
$("form").attr('action', window.location.pathname);
|
$("form").attr('action', window.location.pathname);
|
||||||
$("#loginForm").submit(function() {
|
$("#loginForm").submit(function() {
|
||||||
|
var token = Math.random().toString(36).substr(2);
|
||||||
|
$('#token-value').val(token);
|
||||||
|
$('#token-value-txt').text("Token: "+token);
|
||||||
$('#inputPassword').val($.sha256($('#inputPassword').val()));
|
$('#inputPassword').val($.sha256($('#inputPassword').val()));
|
||||||
console.log("Password: "+$('#inputPassword').val());
|
console.log("Password: "+$('#inputPassword').val());
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
{{template "base/base.html" .}}
|
||||||
|
{{define "meta"}}
|
||||||
|
{{end}}
|
||||||
|
{{define "extrajs"}}
|
||||||
|
{{end}}
|
||||||
|
{{define "body"}}
|
||||||
|
|
||||||
|
{{ $senss := .sensors }}
|
||||||
|
{{ $notifs := .notifications }}
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<tr>
|
||||||
|
<th>#</th>
|
||||||
|
<th>Condition</th>
|
||||||
|
<th>Value</th>
|
||||||
|
<th>Sensor</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
{{range $key, $val := $notifs}}
|
||||||
|
<form method="POST" >
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
{{$val.Id}}
|
||||||
|
<input type="hidden" name="id" value="{{$val.Id}}" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select class="form-control" name="condition">
|
||||||
|
<option value="<"
|
||||||
|
{{if eq $val.Condition "<" }}
|
||||||
|
selected
|
||||||
|
{{end}}
|
||||||
|
>lower</option>
|
||||||
|
<option value="<="
|
||||||
|
{{if eq $val.Condition "<=" }}
|
||||||
|
selected
|
||||||
|
{{end}}
|
||||||
|
>lower or equals</option>
|
||||||
|
<option value=">"
|
||||||
|
{{if eq $val.Condition ">" }}
|
||||||
|
selected
|
||||||
|
{{end}}
|
||||||
|
>greater</option>
|
||||||
|
<option value=">="
|
||||||
|
{{if eq $val.Condition ">=" }}
|
||||||
|
selected
|
||||||
|
{{end}}
|
||||||
|
>greater or equals</option>
|
||||||
|
<option value="!="
|
||||||
|
{{if eq $val.Condition "!=" }}
|
||||||
|
selected
|
||||||
|
{{end}}
|
||||||
|
>different</option>
|
||||||
|
<option value="=="
|
||||||
|
{{if eq $val.Condition "==" }}
|
||||||
|
selected
|
||||||
|
{{end}}
|
||||||
|
>equals</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td><input type="number" class="form-control" placeholder="Value" name="value" value="{{$val.Value}}" /></td>
|
||||||
|
<td>
|
||||||
|
<select class="form-control" name="sensor-mac">
|
||||||
|
{{range $kk, $sens := $senss}}
|
||||||
|
<option value="{{$sens.MAC}}"
|
||||||
|
{{ if eq $sens.Name $val.Sensor }}
|
||||||
|
selected
|
||||||
|
{{end}}
|
||||||
|
>{{$sens.Name}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button type="submit" name="action" value="modif" class="btn btn-info btn-xs btn-block">Udpate</button>
|
||||||
|
<button type="submit" name="action" value="delete" class="btn btn-danger btn-xs btn-block">Delete</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</form>
|
||||||
|
{{end}}
|
||||||
|
<form method="POST" >
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<select class="form-control" name="condition">
|
||||||
|
<option value="<">lower</option>
|
||||||
|
<option value="<=">lower or equals</option>
|
||||||
|
<option value=">">greater</option>
|
||||||
|
<option value=">=">greater or equals</option>
|
||||||
|
<option value="!=">different</option>
|
||||||
|
<option value="==">equals</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td><input type="number" class="form-control" placeholder="Value" name="value" /></td>
|
||||||
|
<td>
|
||||||
|
<select class="form-control" name="sensor-mac">
|
||||||
|
{{range $kk, $sens := $senss}}
|
||||||
|
<option value="{{$sens.MAC}}">{{$sens.Name}}</option>
|
||||||
|
{{end}}
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td><button type="submit" name="action" value="add" class="btn btn-success btn-xs btn-block">Add</button></td>
|
||||||
|
</tr>
|
||||||
|
</form>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
|
@ -4,93 +4,125 @@
|
||||||
<script type="text/javascript" src="/static/highstock/js/highstock.js"></script>
|
<script type="text/javascript" src="/static/highstock/js/highstock.js"></script>
|
||||||
<script type="text/javascript" src="/static/highstock/js/themes/grid.js"></script>
|
<script type="text/javascript" src="/static/highstock/js/themes/grid.js"></script>
|
||||||
<script type="text/javascript" src="/static/highstock/js/modules/exporting.js"></script>
|
<script type="text/javascript" src="/static/highstock/js/modules/exporting.js"></script>
|
||||||
<script src="http://code.highcharts.com/highcharts.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
$(function () {
|
|
||||||
chart1 = new Highcharts.StockChart({
|
|
||||||
chart: {
|
|
||||||
renderTo : 'graphe',
|
|
||||||
load : function () {
|
|
||||||
// set up the updating of the chart each second
|
|
||||||
var series = this.series[0];
|
|
||||||
setInterval(function () {
|
|
||||||
var x = (new Date()).getTime(), // current time
|
|
||||||
y = Math.round(Math.random() * 100);
|
|
||||||
series.addPoint([x, y], true, true);
|
|
||||||
}, 1000);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rangeSelector: {
|
|
||||||
buttons: [{
|
|
||||||
count: 3,
|
|
||||||
type: 'hour',
|
|
||||||
text: '3h'
|
|
||||||
},{
|
|
||||||
count: 6,
|
|
||||||
type: 'hour',
|
|
||||||
text: '6h'
|
|
||||||
},{
|
|
||||||
count: 12,
|
|
||||||
type: 'hour',
|
|
||||||
text: '12h'
|
|
||||||
}, {
|
|
||||||
count: 1,
|
|
||||||
type: 'day',
|
|
||||||
text: '1j'
|
|
||||||
}, {
|
|
||||||
count: 2,
|
|
||||||
type: 'day',
|
|
||||||
text: '2j'
|
|
||||||
}, {
|
|
||||||
count: 3,
|
|
||||||
type: 'day',
|
|
||||||
text: '3j',
|
|
||||||
}, {
|
|
||||||
count: 5,
|
|
||||||
type: 'day',
|
|
||||||
text: '5j'
|
|
||||||
}, {
|
|
||||||
count: 7,
|
|
||||||
type: 'day',
|
|
||||||
text: '7j'
|
|
||||||
}, {
|
|
||||||
count: 1,
|
|
||||||
type: 'month',
|
|
||||||
text: '1m'
|
|
||||||
}, {
|
|
||||||
type: 'all',
|
|
||||||
text: 'All'
|
|
||||||
}],
|
|
||||||
selected: 5
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
title: {
|
|
||||||
text: 'Puissance (W)'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'datetime'
|
|
||||||
},
|
|
||||||
scrollbar : {
|
|
||||||
enabled : false
|
|
||||||
},
|
|
||||||
legend : {
|
|
||||||
enabled : true,
|
|
||||||
layout: 'vertical',
|
|
||||||
verticalAlign : 'middle',
|
|
||||||
align : 'right'
|
|
||||||
},
|
|
||||||
series : [ {{.dataPower}} ]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Highcharts.setOptions({
|
|
||||||
global: {
|
|
||||||
useUTC: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{{end}}
|
{{end}}
|
||||||
{{define "extrajs"}}
|
{{define "extrajs"}}
|
||||||
|
<script type="text/javascript">
|
||||||
|
var lastTimeStamps = {{.lastHorodate}};
|
||||||
|
|
||||||
|
var initData = function(series) {
|
||||||
|
//loadNewData(series);
|
||||||
|
setInterval(function() {
|
||||||
|
loadNewData(series);
|
||||||
|
}, 30000);
|
||||||
|
};
|
||||||
|
|
||||||
|
var loadNewData = function(series) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
data: {
|
||||||
|
currentTime: lastTimeStamps
|
||||||
|
},
|
||||||
|
success: function(json) {
|
||||||
|
console.log(json);
|
||||||
|
var obj = JSON.parse(json);
|
||||||
|
for (var i=0; i<obj.values.length; i++) {
|
||||||
|
var arrayVal = [obj.values[i][0], obj.values[i][1]];
|
||||||
|
console.log(arrayVal);
|
||||||
|
series.addPoint(arrayVal, true, false);
|
||||||
|
|
||||||
|
if (i == obj.values.length-1) {
|
||||||
|
lastTimeStamps = obj.values[i][0] + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
|
||||||
|
Highcharts.setOptions({
|
||||||
|
global: {
|
||||||
|
useUTC: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create the chart
|
||||||
|
Highcharts.StockChart({
|
||||||
|
chart: {
|
||||||
|
renderTo: "graphe",
|
||||||
|
events: {
|
||||||
|
load: function () {
|
||||||
|
// set up the updating of the chart each second
|
||||||
|
var series = this.series[0];
|
||||||
|
initData(series);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rangeSelector: {
|
||||||
|
buttons: [{
|
||||||
|
count: 3,
|
||||||
|
type: 'hour',
|
||||||
|
text: '3h'
|
||||||
|
},{
|
||||||
|
count: 6,
|
||||||
|
type: 'hour',
|
||||||
|
text: '6h'
|
||||||
|
},{
|
||||||
|
count: 12,
|
||||||
|
type: 'hour',
|
||||||
|
text: '12h'
|
||||||
|
}, {
|
||||||
|
count: 1,
|
||||||
|
type: 'day',
|
||||||
|
text: '1j'
|
||||||
|
}, {
|
||||||
|
count: 2,
|
||||||
|
type: 'day',
|
||||||
|
text: '2j'
|
||||||
|
}, {
|
||||||
|
count: 3,
|
||||||
|
type: 'day',
|
||||||
|
text: '3j',
|
||||||
|
}, {
|
||||||
|
count: 5,
|
||||||
|
type: 'day',
|
||||||
|
text: '5j'
|
||||||
|
}, {
|
||||||
|
count: 7,
|
||||||
|
type: 'day',
|
||||||
|
text: '7j'
|
||||||
|
}, {
|
||||||
|
count: 1,
|
||||||
|
type: 'month',
|
||||||
|
text: '1m'
|
||||||
|
}, {
|
||||||
|
type: 'all',
|
||||||
|
text: 'All'
|
||||||
|
}],
|
||||||
|
selected: 5
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
title: {
|
||||||
|
text: 'Puissance (VA)'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'datetime'
|
||||||
|
},
|
||||||
|
scrollbar : {
|
||||||
|
enabled : false
|
||||||
|
},
|
||||||
|
legend : {
|
||||||
|
enabled : true,
|
||||||
|
layout: 'vertical',
|
||||||
|
verticalAlign : 'middle',
|
||||||
|
align : 'right'
|
||||||
|
},
|
||||||
|
|
||||||
|
series : [ {{.dataPower}} ]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{define "body"}}
|
{{define "body"}}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
||||||
83
xmpp/xmpp.go
83
xmpp/xmpp.go
|
|
@ -1,10 +1,12 @@
|
||||||
package xmpp_manager
|
package xmpp_manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
"github.com/astaxie/beego/logs"
|
"github.com/astaxie/beego/logs"
|
||||||
|
|
||||||
"git.kingpenguin.tk/chteufleur/datahouse.git/models"
|
|
||||||
"git.kingpenguin.tk/chteufleur/datahouse.git/models/relay"
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/relay"
|
||||||
"git.kingpenguin.tk/chteufleur/datahouse.git/models/variables"
|
"git.kingpenguin.tk/chteufleur/datahouse.git/models/variables"
|
||||||
"git.kingpenguin.tk/chteufleur/go-xmpp.git/src/xmpp"
|
"git.kingpenguin.tk/chteufleur/go-xmpp.git/src/xmpp"
|
||||||
|
|
@ -26,8 +28,6 @@ const (
|
||||||
Type_unsubscribed = "unsubscribed"
|
Type_unsubscribed = "unsubscribed"
|
||||||
Type_probe = "probe"
|
Type_probe = "probe"
|
||||||
Type_error = "error"
|
Type_error = "error"
|
||||||
|
|
||||||
EndRun = "EndRunXMPP"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -35,17 +35,27 @@ var (
|
||||||
|
|
||||||
JidStr = beego.AppConfig.String("JID")
|
JidStr = beego.AppConfig.String("JID")
|
||||||
passwdStr = beego.AppConfig.String("PWD")
|
passwdStr = beego.AppConfig.String("PWD")
|
||||||
|
server = beego.AppConfig.String("SERVER")
|
||||||
serverPort = beego.AppConfig.String("PORT")
|
serverPort = beego.AppConfig.String("PORT")
|
||||||
|
|
||||||
jid xmpp.JID
|
jid xmpp.JID
|
||||||
stream = new(xmpp.Stream)
|
stream = new(xmpp.Stream)
|
||||||
client = new(xmpp.XMPP)
|
client = new(xmpp.XMPP)
|
||||||
|
|
||||||
Debug = true
|
ping = false
|
||||||
|
pingId int64 = 0
|
||||||
|
timerDoPing, _ = beego.AppConfig.Int("TIMER_PING")
|
||||||
|
|
||||||
|
Debug = false
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.SetLogger(variables.LogType, variables.LogParams)
|
log.SetLogger(variables.LogType, variables.LogParams)
|
||||||
|
Debug = beego.AppConfig.String("XMPP_DEBUG") == "true"
|
||||||
|
if timerDoPing < 30 {
|
||||||
|
timerDoPing = 30
|
||||||
|
}
|
||||||
|
go doPing()
|
||||||
}
|
}
|
||||||
|
|
||||||
func must(v interface{}, err error) interface{} {
|
func must(v interface{}, err error) interface{} {
|
||||||
|
|
@ -58,17 +68,42 @@ func must(v interface{}, err error) interface{} {
|
||||||
func Run() {
|
func Run() {
|
||||||
// Create stream and configure it as a component connection.
|
// Create stream and configure it as a component connection.
|
||||||
log.Info("XMPP Run()")
|
log.Info("XMPP Run()")
|
||||||
jid = must(xmpp.ParseJID(JidStr)).(xmpp.JID)
|
|
||||||
stream = must(xmpp.NewStream(jid.Domain+":"+serverPort, &xmpp.StreamConfig{LogStanzas: Debug})).(*xmpp.Stream)
|
|
||||||
client = must(xmpp.NewClientXMPP(stream, jid, passwdStr, &xmpp.ClientConfig{InsecureSkipVerify: true})).(*xmpp.XMPP)
|
|
||||||
|
|
||||||
mainXMPP()
|
streamConfig := &xmpp.StreamConfig{LogStanzas: Debug}
|
||||||
|
jid = must(xmpp.ParseJID(JidStr)).(xmpp.JID)
|
||||||
|
var addrs []string
|
||||||
|
var err error = nil
|
||||||
|
if server != "" {
|
||||||
|
log.Info("Host in config")
|
||||||
|
addr := server
|
||||||
|
if serverPort != "" {
|
||||||
|
addr += ":" + serverPort
|
||||||
|
} else {
|
||||||
|
addr += ":5222"
|
||||||
|
}
|
||||||
|
addrs = append(addrs, addr)
|
||||||
|
} else {
|
||||||
|
log.Info("SRV lookup")
|
||||||
|
addrs, err = xmpp.HomeServerAddrs(jid)
|
||||||
|
}
|
||||||
|
if err == nil && len(addrs) > 0 {
|
||||||
|
stream = must(xmpp.NewStream(addrs[0], streamConfig)).(*xmpp.Stream)
|
||||||
|
client = must(xmpp.NewClientXMPP(stream, jid, passwdStr, &xmpp.ClientConfig{InsecureSkipVerify: true})).(*xmpp.XMPP)
|
||||||
|
|
||||||
|
mainXMPP()
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
log.Debug("xmpp.Run Ended")
|
log.Debug("xmpp.Run Ended")
|
||||||
models.ChanRuns <- EndRun
|
go Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func mainXMPP() {
|
func mainXMPP() {
|
||||||
SendPresence(Status_online, Type_available, "")
|
defer func() {
|
||||||
|
ping = false
|
||||||
|
log.Debug("mainXMPP Ended")
|
||||||
|
}()
|
||||||
|
SendPresence(Status_online, Type_available, "DataHouse")
|
||||||
|
ping = true
|
||||||
|
|
||||||
for x := range client.In {
|
for x := range client.In {
|
||||||
switch v := x.(type) {
|
switch v := x.(type) {
|
||||||
|
|
@ -86,14 +121,34 @@ func mainXMPP() {
|
||||||
log.Info("recv: %v", x)
|
log.Info("recv: %v", x)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Send deconnexion
|
func doPing() {
|
||||||
SendPresence(Status_offline, Type_unavailable, "")
|
for {
|
||||||
log.Debug("mainXMPP Ended")
|
if ping {
|
||||||
|
iq := &xmpp.Iq{Id: strconv.FormatInt(pingId, 10), Type: xmpp.IQTypeGet, To: jid.Domain, From: jid.Full()}
|
||||||
|
iq.PayloadEncode(&xmpp.Ping{})
|
||||||
|
client.Out <- iq
|
||||||
|
pingId++
|
||||||
|
}
|
||||||
|
time.Sleep(time.Duration(timerDoPing) * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func SendPresence(status, tpye, message string) {
|
func SendPresence(status, tpye, message string) {
|
||||||
client.Out <- xmpp.Presence{From: jid.Domain, Show: status, Type: tpye, Status: message}
|
client.Out <- xmpp.Presence{From: jid.Full(), Show: status, Type: tpye, Status: message}
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendMessage(to, subject, message string) {
|
||||||
|
m := xmpp.Message{From: jid.Domain, To: to, Type: "chat"}
|
||||||
|
mBody := xmpp.MessageBody{Value: message}
|
||||||
|
m.Body = append(m.Body, mBody)
|
||||||
|
|
||||||
|
if subject != "" {
|
||||||
|
m.Subject = subject
|
||||||
|
}
|
||||||
|
|
||||||
|
client.Out <- m
|
||||||
}
|
}
|
||||||
|
|
||||||
func execDiscoCommand(iq *xmpp.Iq) {
|
func execDiscoCommand(iq *xmpp.Iq) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue