Extend this program:
- add a database for devices - read devices from database and present this data on a simple web/REST interface The code or model is from a blog entry from Alex Edward: https://www.alexedwards.net/blog/organising-database-access
This commit is contained in:
parent
cf4274c1e1
commit
daa79b27ca
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
7
config.toml
Normal file
7
config.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[BROKER]
|
||||||
|
Address="s1.mimbach49.de"
|
||||||
|
Port=8883
|
||||||
|
ClientId = "mqttListener"
|
||||||
|
Username = "testuser"
|
||||||
|
Password = "xyz123"
|
||||||
|
EnableTLS = true
|
11
go.mod
Normal file
11
go.mod
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module mqttListener
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/eclipse/paho.mqtt.golang v1.2.0
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.2
|
||||||
|
github.com/mmcdole/gofeed v1.0.0
|
||||||
|
github.com/pelletier/go-toml v1.2.0
|
||||||
|
github.com/spf13/cobra v1.0.0
|
||||||
|
)
|
38
main.go
38
main.go
|
@ -2,16 +2,23 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mqttListener/Config"
|
"mqttListener/Config"
|
||||||
|
"mqttListener/models"
|
||||||
"mqttListener/mqtt"
|
"mqttListener/mqtt"
|
||||||
|
|
||||||
//"mqttListener/cmd"
|
"fmt"
|
||||||
|
"log"
|
||||||
|
|
||||||
//"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Env struct {
|
||||||
|
db models.Datastore
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
|
@ -22,13 +29,38 @@ func main() {
|
||||||
// DEBUG Config
|
// DEBUG Config
|
||||||
// fmt.Println("BrokerAddress = ", Config.BrokerAddress)
|
// fmt.Println("BrokerAddress = ", Config.BrokerAddress)
|
||||||
|
|
||||||
|
db, err := models.NewDB("simple.sqlite")
|
||||||
|
if err != nil {
|
||||||
|
log.Panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
env := &Env{db}
|
||||||
|
|
||||||
mqtt.Setup()
|
mqtt.Setup()
|
||||||
mqtt.Connect()
|
mqtt.Connect()
|
||||||
go mqtt.Listen()
|
go mqtt.Listen()
|
||||||
|
|
||||||
//cmd.Exec()
|
http.HandleFunc("/devices", env.devicesIndex)
|
||||||
|
go http.ListenAndServe(":3000", nil)
|
||||||
|
|
||||||
|
fmt.Println("awaiting signal")
|
||||||
<-c // wait for SIGTERM
|
<-c // wait for SIGTERM
|
||||||
|
fmt.Println("exiting")
|
||||||
|
|
||||||
mqtt.Disconnect()
|
mqtt.Disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (env *Env) devicesIndex(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != "GET" {
|
||||||
|
http.Error(w, http.StatusText(405), 405)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
devices, err := env.db.AllDevices()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, http.StatusText(500), 500)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, device := range devices {
|
||||||
|
fmt.Fprintf(w, "%s, %s, %s, £%.2f\n", device.ID, device.MAC, device.SN, device.LastMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
33
models/db.go
Normal file
33
models/db.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Datastore interface {
|
||||||
|
AllDevices() ([]*Device, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DB struct {
|
||||||
|
*sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDB(dataSourceName string) (*DB, error) {
|
||||||
|
db, err := sql.Open("sqlite3", dataSourceName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = db.Ping(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlStmt := "CREATE TABLE IF NOT EXISTS devices (id TEXT not null primary key, mac TEXT, sn TEXT, lastMsg TEXT);"
|
||||||
|
_, err = db.Exec(sqlStmt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &DB{db}, nil
|
||||||
|
}
|
36
models/devices.go
Normal file
36
models/devices.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package models
|
||||||
|
|
||||||
|
type Device struct {
|
||||||
|
ID string
|
||||||
|
MAC string
|
||||||
|
SN string
|
||||||
|
LastMsg string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (db *DB) AllDevices() ([]*Device, error) {
|
||||||
|
rows, err := db.Query("SELECT * FROM devices")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
devices := make([]*Device, 0)
|
||||||
|
for rows.Next() {
|
||||||
|
device := new(Device)
|
||||||
|
err := rows.Scan(&device.ID, &device.MAC, &device.SN, &device.LastMsg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
devices = append(devices, device)
|
||||||
|
}
|
||||||
|
if err = rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return devices, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user