From ed5c03ffec1d2facc2cdd0e875a88479863deaeb Mon Sep 17 00:00:00 2001 From: William Clark Date: Wed, 22 Nov 2023 11:35:15 +0000 Subject: [PATCH] web --- .gitea/webview0.png | Bin 11934 -> 64699 bytes README.md | 9 ++-- config.toml | 2 + main.go | 10 ++-- static/data-updater.js | 117 ++++++++++++++++++++++++++++++----------- templates/index.tmpl | 81 +++++++++++++++++++++++++--- web/gin.go | 14 ++++- 7 files changed, 184 insertions(+), 49 deletions(-) diff --git a/.gitea/webview0.png b/.gitea/webview0.png index 4c77b3ce84c8570d77bf335deef28a0cfe335ca7..d9f4f896b021b9ba7698adf12321cbafd54cd319 100644 GIT binary patch literal 64699 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 N%w5Ghxss2b{U2J7GhzS$ literal 11934 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 QjyXV1O8H&2#QWg?00;|`mjD0& diff --git a/README.md b/README.md index 8bfc7ca..1bd9418 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,9 @@ # TH7 -Seven-channel multiple thermocouple reader and logger HAT for the Raspberry Pi. - -![Alt](/.gitea/webview0.png "Web view demo") +Seven-channel multiple thermocouple reader and logger HAT for the Raspberry Pi. This software supports the following thermocouple types: + - B - E - J @@ -15,6 +14,7 @@ This software supports the following thermocouple types: - T Features not yet implemented but planned: + - More database logging options than SQLite3 - Advanced filtering, incl. user-selectable filtering stages and sample sizes - Several logging options at once, one local, one or more remote @@ -24,5 +24,6 @@ Features not yet implemented but planned: - Request dumps from filter stages for noise study - ... and more! - Note: Most thermocouples that have a coloured and a white lead, usually have the coloured one as the positive. + +![Alt](/.gitea/webview0.png "Web view demo") diff --git a/config.toml b/config.toml index 5a7dfde..f757ed4 100644 --- a/config.toml +++ b/config.toml @@ -25,9 +25,11 @@ filter.samples = 20 [Channel_3] type = 'T' +gain = 112.28821 [Channel_4] type = 'K' +gain = 2.8129883e2 [Channel_6] type = 'J' diff --git a/main.go b/main.go index c1b09a3..2985dc7 100644 --- a/main.go +++ b/main.go @@ -28,29 +28,29 @@ func main() { syscall.SIGHUP, syscall.SIGQUIT) - config, err := config.Load() + cfg, err := config.Load() if err != nil { log.Fatalf("Error loading config: %v", err) } - pcbPort, err = pcb.NewAdapter(config) + pcbPort, err = pcb.NewAdapter(cfg) if err != nil { log.Fatalf("Fatal error: %v\n", err) } defer pcbPort.Deinit() - corePort, err = core.NewAdapter(pcbPort, config) + corePort, err = core.NewAdapter(pcbPort, cfg) if err != nil { log.Fatalf("Error starting TH7 Adapter: %v\n", err) } - dbPort, err = db.NewAdapter(corePort, config) + dbPort, err = db.NewAdapter(corePort, cfg) if err != nil { log.Fatalf("Fatal error: %v\n", err) } defer dbPort.Close() - webPort = web.NewGinAdapter(corePort, config.Board.Port) + webPort = web.NewGinAdapter(corePort, cfg) go webPort.Run() sig := <-kill diff --git a/static/data-updater.js b/static/data-updater.js index fac9d57..0ed6b1e 100644 --- a/static/data-updater.js +++ b/static/data-updater.js @@ -1,34 +1,91 @@ -const vdd = document.getElementById('vdd'); -const vref = document.getElementById('vref'); -const vadj = document.getElementById('vadj'); -const ts = document.getElementById('timestamp'); -const table = document.getElementById('data'); +const thermocoupleTypeTable = ["uV", "B", "E", "J", "K", "N", "R", "S", "T"]; -let old_channel_count=0; +const elements = { + read: { + vdd: document.getElementById("vdd"), + vref: document.getElementById("vref"), + vadj: document.getElementById("vadj"), + ts: document.getElementById("timestamp"), + table: document.getElementById("data"), + }, + config: { + table: document.getElementById("thermocouple"), + }, +}; -async function update () { +let readOldChannelCount = 0; +let configOldChannelCount = 0; - data = await fetch("/data").then((data)=>{return data.json()}); - vdd.innerHTML = "VDD: " + parseFloat(data["ratio"]["pivdd"]); - vref.innerHTML = "VREF: " + parseFloat(data["ratio"]["vref"]); - vadj.innerHTML = "VADJ: " + parseFloat(data["ratio"]["vadj"]); - ts.innerHTML = "Last updated: " + data["time"]; - for (let i=0; i { - let unit = e["unit"]; - let value = e["value"]; - let channel = e["id"]; - - let row = table.insertRow(-1); - row.insertCell(0).innerText = channel; - row.insertCell(1).innerText = value; - row.insertCell(2).innerText = unit; - old_channel_count++; - }); +async function fetchData(url) { + const response = await fetch(url); + return response.json(); } -update(); -setInterval(update, 1000); \ No newline at end of file + +function clearTableBody(tableType) { + const table = elements[tableType].table; + const tbody = table.querySelector("tbody"); + + if (tbody) { + tbody.innerHTML = ""; + } else { + // If tbody doesn't exist, recreate it + const newTbody = document.createElement("tbody"); + table.appendChild(newTbody); + } +} + +function updateTable(data, tableType, oldChannelCount, updateFunction) { + clearTableBody(tableType); + + oldChannelCount = 0; + + data.channels.forEach((channel) => { + updateFunction(channel, tableType); + oldChannelCount++; + }); +} + +function updateReadTable(channel, tableType) { + const { value, id } = channel; + + const row = elements[tableType].table.querySelector("tbody").insertRow(-1); + row.insertCell(0).innerText = id; + row.insertCell(1).innerText = value; +} + +function updateConfigTable(channel, tableType) { + const { id, thermocouple, gain, offset, filter } = channel; + + const row = elements[tableType].table.querySelector("tbody").insertRow(-1); + row.insertCell(0).innerText = id; + row.insertCell(1).innerText = thermocoupleTypeTable[thermocouple]; + row.insertCell(2).innerText = gain; + row.insertCell(3).innerText = offset; + row.insertCell(4).innerText = filter.sample_size; + row.insertCell(5).innerText = filter.type; +} + +function updateOthers(data) { + const { ratio, time } = data; + elements.read.ts.innerText = time; + elements.read.vref.innerHTML = `VREF: ${ratio.vref}`; + elements.read.vadj.innerHTML = `VADJ: ${ratio.vadj}`; + elements.read.vdd.innerHTML = `VDD: ${ratio.pivdd}`; +} + +async function updateRead() { + const data = await fetchData("/data"); + updateTable(data, "read", readOldChannelCount, updateReadTable); + updateOthers(data); +} + +async function updateConfig() { + const data = await fetchData("/config"); + updateTable(data.config, "config", configOldChannelCount, updateConfigTable); +} + +updateRead(); +updateConfig(); + +setInterval(updateRead, 1000); +setInterval(updateConfig, 5000); diff --git a/templates/index.tmpl b/templates/index.tmpl index e1ab139..8525c09 100644 --- a/templates/index.tmpl +++ b/templates/index.tmpl @@ -5,23 +5,88 @@ - {{ .title }} + {{.title}} +

TH7

+ - - - - - + + + + + +
ChannelValueUnit
ChannelValue
+

VDD:

VREF:

VADJ:

Last updated:

+ +

Thermocouple config

+ + + + + + + + + + + + +
ChannelTypeGainOffsetFilter sizeFilter type
+ - -{{ end }} \ No newline at end of file +{{ end }} diff --git a/web/gin.go b/web/gin.go index 401d182..fd408e4 100644 --- a/web/gin.go +++ b/web/gin.go @@ -8,6 +8,7 @@ import ( "github.com/gin-gonic/gin" + "th7/data/config" "th7/data/core" "th7/ports" ) @@ -15,6 +16,7 @@ import ( type GinAdapter struct { router *gin.Engine corePort ports.CorePort + cfg config.Config port int } @@ -89,11 +91,18 @@ func (g *GinAdapter) IndexHandler(c *gin.Context) { }) } -func NewGinAdapter(corePort ports.CorePort, port int) *GinAdapter { +func (g *GinAdapter) ConfigHandler(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "config": g.cfg, + }) +} + +func NewGinAdapter(corePort ports.CorePort, cfg config.Config) *GinAdapter { var adapter GinAdapter adapter.corePort = corePort - adapter.port = port + adapter.port = cfg.Board.Port + adapter.cfg = cfg //adapter.router = gin.Default() adapter.router = gin.New() @@ -104,6 +113,7 @@ func NewGinAdapter(corePort ports.CorePort, port int) *GinAdapter { adapter.router.GET("/channel/:id", adapter.ChannelByIDHandler) adapter.router.GET("/time", adapter.TimestampHandler) adapter.router.GET("/data", adapter.DataHandler) + adapter.router.GET("/config", adapter.ConfigHandler) adapter.router.LoadHTMLGlob("./templates/*.tmpl") adapter.router.Static("/assets", "./static")