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:
		
							
								
								
									
										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 (
 | 
			
		||||
	"mqttListener/Config"
 | 
			
		||||
	"mqttListener/models"
 | 
			
		||||
	"mqttListener/mqtt"
 | 
			
		||||
 | 
			
		||||
	//"mqttListener/cmd"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log"
 | 
			
		||||
 | 
			
		||||
	//"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"os/signal"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Env struct {
 | 
			
		||||
	db models.Datastore
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func main() {
 | 
			
		||||
 | 
			
		||||
	c := make(chan os.Signal, 1)
 | 
			
		||||
@@ -22,13 +29,38 @@ func main() {
 | 
			
		||||
	// DEBUG Config
 | 
			
		||||
	// fmt.Println("BrokerAddress = ", Config.BrokerAddress)
 | 
			
		||||
 | 
			
		||||
	db, err := models.NewDB("simple.sqlite")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	env := &Env{db}
 | 
			
		||||
 | 
			
		||||
	mqtt.Setup()
 | 
			
		||||
	mqtt.Connect()
 | 
			
		||||
	go mqtt.Listen()
 | 
			
		||||
 | 
			
		||||
	//cmd.Exec()
 | 
			
		||||
	http.HandleFunc("/devices", env.devicesIndex)
 | 
			
		||||
	go http.ListenAndServe(":3000", nil)
 | 
			
		||||
 | 
			
		||||
	fmt.Println("awaiting signal")
 | 
			
		||||
	<-c // wait for SIGTERM
 | 
			
		||||
	fmt.Println("exiting")
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user