2023-12-12 21:07:04 +00:00
|
|
|
package api
|
2023-12-05 17:22:12 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
2023-12-06 19:21:54 +00:00
|
|
|
cfg "th7/config"
|
2023-12-05 17:22:12 +00:00
|
|
|
"th7/data/config"
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
ErrConfigChannelNotFound = errors.New("a configured channel with this ID was not found")
|
|
|
|
ErrConfigRestrictedDB = errors.New("access to the DB map is restricted")
|
|
|
|
)
|
|
|
|
|
|
|
|
func (g *GinAdapter) getConfigByID(id int) (config.Channel, error) {
|
|
|
|
for channel := range g.cfg.Channels {
|
|
|
|
if g.cfg.Channels[channel].Id == id {
|
|
|
|
return g.cfg.Channels[channel], nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return config.Channel{}, ErrConfigChannelNotFound
|
|
|
|
}
|
|
|
|
|
|
|
|
// check if a supplied key string is in the device struct (TH7)
|
|
|
|
func configDeviceIsValidKey(key string) bool {
|
|
|
|
|
|
|
|
key = strings.ToLower(key)
|
|
|
|
|
|
|
|
for k := range deviceKeys {
|
|
|
|
if key == deviceKeys[k] {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func configDeviceIsValidValue(key string, value string) bool {
|
|
|
|
// all the values are bools for now
|
|
|
|
value = strings.ToLower(value)
|
|
|
|
return (value == "true" || value == "false")
|
|
|
|
}
|
|
|
|
|
|
|
|
// this doesn't actually do anything to program state... yet
|
|
|
|
func (g *GinAdapter) updateConfigDevice(key string, value string) error {
|
|
|
|
bValue, err := strconv.ParseBool(value)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
key = strings.ToLower(key)
|
|
|
|
|
|
|
|
// might have to sync these writes ?
|
|
|
|
// go doesn't have switch case fall-thru
|
|
|
|
switch key {
|
|
|
|
case "led":
|
|
|
|
g.cfg.Board.Led = bValue
|
|
|
|
|
|
|
|
case "nolog":
|
|
|
|
g.cfg.Board.NoLog = bValue
|
|
|
|
|
|
|
|
case "noweb":
|
|
|
|
g.cfg.Board.NoWeb = bValue
|
|
|
|
|
|
|
|
case "debug":
|
|
|
|
g.cfg.Board.Debug = bValue
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GinAdapter) validConfigChannel(id int) bool {
|
|
|
|
|
|
|
|
for c := range g.cfg.Channels {
|
|
|
|
if g.cfg.Channels[c].Id == id {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func configChannelIsValidKey(key string) bool {
|
|
|
|
|
|
|
|
key = strings.ToLower(key)
|
|
|
|
|
|
|
|
for k := range channelKeys {
|
|
|
|
if key == channelKeys[k] {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GinAdapter) configChannelUpdateValue(id int, key string, value string) error {
|
|
|
|
|
2023-12-06 19:21:54 +00:00
|
|
|
var cfgChannelPtr *config.Channel
|
|
|
|
|
2023-12-05 17:22:12 +00:00
|
|
|
key = strings.ToLower(key)
|
|
|
|
value = strings.ToLower(value)
|
2023-12-06 19:21:54 +00:00
|
|
|
|
2023-12-05 17:22:12 +00:00
|
|
|
foundChannel := false
|
|
|
|
|
|
|
|
// find the channel, given and checked by id
|
|
|
|
for k := range g.cfg.Channels {
|
|
|
|
if g.cfg.Channels[k].Id == id {
|
|
|
|
cfgChannelPtr = &(g.cfg.Channels[k])
|
|
|
|
foundChannel = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if !foundChannel {
|
|
|
|
return ErrConfigChannelNotFound
|
|
|
|
}
|
|
|
|
|
|
|
|
switch key {
|
|
|
|
case "thermocouple":
|
2023-12-06 19:21:54 +00:00
|
|
|
tc, err := cfg.GetThermocoupleType(value)
|
2023-12-05 17:22:12 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
cfgChannelPtr.Thermo = tc
|
|
|
|
case "gain":
|
|
|
|
fValue, err := strconv.ParseFloat(value, 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
cfgChannelPtr.Gain = fValue
|
|
|
|
case "offset":
|
|
|
|
fValue, err := strconv.ParseFloat(value, 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
cfgChannelPtr.Offset = fValue
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
func (g *GinAdapter) GetConfigChannelByIdHandler(c *gin.Context) {
|
|
|
|
var timestamp string
|
|
|
|
id, err := strconv.Atoi(c.Param("id"))
|
|
|
|
|
|
|
|
if err != nil {
|
2023-12-06 19:21:54 +00:00
|
|
|
c.String(http.StatusBadRequest, err.Error())
|
2023-12-05 17:22:12 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
channel, err := g.getConfigByID(id)
|
|
|
|
if err != nil {
|
2023-12-06 19:21:54 +00:00
|
|
|
c.String(http.StatusBadRequest, err.Error())
|
2023-12-05 17:22:12 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
timestamp = g.getTimestamp()
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
"channel": channel,
|
|
|
|
"time": timestamp,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GinAdapter) GetConfigChannelsHandler(c *gin.Context) {
|
|
|
|
timestamp := g.getTimestamp()
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
"channels": g.cfg.Channels,
|
|
|
|
"time": timestamp,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GinAdapter) GetConfigDeviceHandler(c *gin.Context) {
|
|
|
|
timestamp := g.getTimestamp()
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
"channels": g.cfg.Board,
|
|
|
|
"time": timestamp,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GinAdapter) GetConfigDBHandler(c *gin.Context) {
|
|
|
|
var timestamp string
|
|
|
|
|
2023-12-12 21:07:04 +00:00
|
|
|
if g.cfg.API.Restricted {
|
2023-12-06 19:21:54 +00:00
|
|
|
c.String(http.StatusForbidden, ErrConfigRestrictedDB.Error())
|
2023-12-05 17:22:12 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
timestamp = g.getTimestamp()
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
|
|
"db": g.cfg.DB,
|
|
|
|
"time": timestamp,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GinAdapter) SetConfigDeviceHandler(c *gin.Context) {
|
|
|
|
var req PostRequest
|
|
|
|
|
|
|
|
if err := c.ShouldBind(&req); err != nil {
|
|
|
|
c.String(http.StatusBadRequest, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
validKey := configDeviceIsValidKey(req.Key)
|
|
|
|
if !validKey {
|
|
|
|
c.String(http.StatusBadRequest, "invalid device config key")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
validValue := configDeviceIsValidValue(req.Key, req.Value)
|
|
|
|
if !validValue {
|
|
|
|
c.String(http.StatusBadRequest, "invalid device config value")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
err := g.updateConfigDevice(req.Key, req.Value)
|
|
|
|
if err != nil {
|
|
|
|
c.String(http.StatusBadRequest, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.String(http.StatusOK, "OK")
|
|
|
|
}
|
|
|
|
|
|
|
|
// this function can only modify already set up channels, for now.
|
|
|
|
func (g *GinAdapter) SetConfigChannelByIdHandler(c *gin.Context) {
|
|
|
|
|
|
|
|
var req PostRequest
|
|
|
|
id, err := strconv.Atoi(c.Param("id"))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
c.String(http.StatusBadRequest, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
validChannel := g.validConfigChannel(id)
|
|
|
|
if !validChannel {
|
|
|
|
c.String(http.StatusBadRequest, "channel not initially configured. TODO fix")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := c.ShouldBind(&req); err != nil {
|
|
|
|
c.String(http.StatusBadRequest, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
validKey := configChannelIsValidKey(req.Key)
|
|
|
|
if !validKey {
|
|
|
|
c.String(http.StatusBadRequest, "invalid channel config key")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
err = g.configChannelUpdateValue(id, req.Key, req.Value)
|
|
|
|
if err != nil {
|
|
|
|
c.String(http.StatusBadRequest, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.String(http.StatusOK, "OK")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GinAdapter) SetConfigDBHandler(c *gin.Context) {
|
|
|
|
|
|
|
|
var req PostRequest
|
|
|
|
|
2023-12-12 21:07:04 +00:00
|
|
|
if g.cfg.API.Restricted {
|
2023-12-05 17:22:12 +00:00
|
|
|
c.String(http.StatusForbidden, ErrConfigRestrictedDB.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := c.ShouldBind(&req); err != nil {
|
|
|
|
c.String(http.StatusBadRequest, err.Error())
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// what could go wrong?
|
|
|
|
g.cfg.DB[req.Key] = req.Value
|
|
|
|
|
|
|
|
c.String(http.StatusOK, "OK")
|
|
|
|
}
|