Skip to content

Commit

Permalink
Add warehouse
Browse files Browse the repository at this point in the history
  • Loading branch information
kozaktomas committed Oct 1, 2024
1 parent b3cafeb commit eaf95fa
Show file tree
Hide file tree
Showing 12 changed files with 319 additions and 38 deletions.
84 changes: 72 additions & 12 deletions backend/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/sirupsen/logrus"
"io"
"net/http"
"strings"
"time"
)

Expand Down Expand Up @@ -159,25 +160,31 @@ func (hr *HandlerRepository) scaleDashboardHandler() func(http.ResponseWriter, *
return func(w http.ResponseWriter, r *http.Request) {
hr.scale.Recheck()

type warehouseItem struct {
Keg int `json:"keg"`
Amount int `json:"amount"`
}

type pubOutput struct {
IsOpen bool `json:"is_open"`
OpenedAt string `json:"opened_at"`
ClosedAt string `json:"closed_at"`
}

type output struct {
IsOk bool `json:"is_ok"`
BeersLeft int `json:"beers_left"`
LastWeight float64 `json:"last_weight"`
LastWeightFormated string `json:"last_weight_formated"`
LastAt string `json:"last_at"`
LastAtDuration string `json:"last_at_duration"`
Rssi float64 `json:"rssi"`
LastUpdate string `json:"last_update"`
LastUpdateDuration string `json:"last_update_duration"`
Pub pubOutput `json:"pub"`
ActiveKeg int `json:"active_keg"`
IsLow bool `json:"is_low"`
IsOk bool `json:"is_ok"`
BeersLeft int `json:"beers_left"`
LastWeight float64 `json:"last_weight"`
LastWeightFormated string `json:"last_weight_formated"`
LastAt string `json:"last_at"`
LastAtDuration string `json:"last_at_duration"`
Rssi float64 `json:"rssi"`
LastUpdate string `json:"last_update"`
LastUpdateDuration string `json:"last_update_duration"`
Pub pubOutput `json:"pub"`
ActiveKeg int `json:"active_keg"`
IsLow bool `json:"is_low"`
Warehouse []warehouseItem `json:"warehouse"`
}

last := hr.scale.GetLastMeasurement() // it could be fake measurement
Expand All @@ -188,6 +195,14 @@ func (hr *HandlerRepository) scaleDashboardHandler() func(http.ResponseWriter, *
return
}

warehouse := []warehouseItem{
{Keg: 10, Amount: hr.scale.Warehouse[0]},
{Keg: 15, Amount: hr.scale.Warehouse[1]},
{Keg: 20, Amount: hr.scale.Warehouse[2]},
{Keg: 30, Amount: hr.scale.Warehouse[3]},
{Keg: 50, Amount: hr.scale.Warehouse[4]},
}

data := output{
IsOk: hr.scale.IsOk(),
BeersLeft: hr.scale.BeersLeft,
Expand All @@ -205,6 +220,7 @@ func (hr *HandlerRepository) scaleDashboardHandler() func(http.ResponseWriter, *
},
ActiveKeg: hr.scale.ActiveKeg,
IsLow: hr.scale.IsLow,
Warehouse: warehouse,
}

// fake some result when we don't have anything
Expand All @@ -225,3 +241,47 @@ func (hr *HandlerRepository) scaleDashboardHandler() func(http.ResponseWriter, *
_, _ = w.Write(res)
}
}

func (hr *HandlerRepository) scaleWarehouseHandler() func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}

auth := r.Header.Get("Authorization")
if auth != hr.config.Password {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}

type input struct {
Keg int `json:"keg"`
Way string `json:"way"` // up or down
}

var data input
err := json.NewDecoder(r.Body).Decode(&data)
if err != nil {
http.Error(w, "Could not read post body", http.StatusBadRequest)
return
}

if strings.ToLower(data.Way) == "up" {
if err := hr.scale.IncreaseWarehouse(data.Keg); err != nil {
http.Error(w, "Could not increase warehouse", http.StatusInternalServerError)
return
}
}

if strings.ToLower(data.Way) == "down" {
if err := hr.scale.DecreaseWarehouse(data.Keg); err != nil {
http.Error(w, "Could not increase warehouse", http.StatusInternalServerError)
return
}
}

w.Header().Set("Content-Type", "application/json")
_, _ = w.Write(getOkJson())
}
}
1 change: 1 addition & 0 deletions backend/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func NewRouter(hr *HandlerRepository) *mux.Router {
router.HandleFunc("/api/scale/status", hr.scaleStatusHandler())
router.HandleFunc("/api/scale/print", hr.scalePrintHandler())
router.HandleFunc("/api/scale/dashboard", hr.scaleDashboardHandler())
router.HandleFunc("/api/scale/warehouse", hr.scaleWarehouseHandler())

router.HandleFunc("/api/pub/active_keg", hr.activeKegHandler())

Expand Down
53 changes: 47 additions & 6 deletions backend/scale.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ type Scale struct {
size int
valid int // number of valid measurements

BeersLeft int `json:"beers_left"` // how many beers are left in the keg
IsLow bool `json:"is_low"` // is the keg low and needs to be replaced soon
ActiveKeg int `json:"active_keg"` // int value of the active keg in liters
BeersLeft int `json:"beers_left"` // how many beers are left in the keg
IsLow bool `json:"is_low"` // is the keg low and needs to be replaced soon
Warehouse [5]int `json:"warehouse"` // warehouse of kegs [10l, 15l, 20l, 30l, 50l]

Pub Pub `json:"pub"`
ActiveKeg int `json:"active_keg"` // int value of the active keg in liters
Pub Pub `json:"pub"`

LastOk time.Time `json:"last_ok"`
Rssi float64 `json:"rssi"`
Expand All @@ -56,15 +57,16 @@ func NewScale(bufferSize int, monitor *Monitor, store Storage, logger *logrus.Lo
size: bufferSize,
valid: 0,

ActiveKeg: 0,
BeersLeft: 0,
IsLow: false,
Warehouse: [5]int{0, 0, 0, 0, 0},

Pub: Pub{
IsOpen: false,
OpenedAt: time.Now().Add(-9999 * time.Hour),
ClosedAt: time.Now().Add(-9999 * time.Hour),
},
ActiveKeg: 0,

LastOk: time.Now().Add(-9999 * time.Hour),

Expand Down Expand Up @@ -117,6 +119,11 @@ func (s *Scale) loadDataFromStore() {
if err == nil {
s.IsLow = isLow
}

warehouse, err := s.store.GetWarehouse()
if err == nil {
s.Warehouse = warehouse
}
}

func (s *Scale) AddMeasurement(weight float64) error {
Expand Down Expand Up @@ -173,7 +180,15 @@ func (s *Scale) AddMeasurement(weight float64) error {
return fmt.Errorf("could not store is_low: %w", serr)
}

// @todo: remove keg from warehouse
// remove keg from warehouse
index, err := GetWarehouseIndex(keg)
if err != nil {
return err
}
s.Warehouse[index]--
if serr := s.store.SetWarehouse(s.Warehouse); serr != nil {
return fmt.Errorf("could not update store warehouse: %w", serr)
}
}
}

Expand Down Expand Up @@ -322,3 +337,29 @@ func (s *Scale) SetActiveKeg(keg int) error {
s.ActiveKeg = keg
return s.store.SetActiveKeg(keg)
}

func (s *Scale) IncreaseWarehouse(keg int) error {
s.mux.Lock()
defer s.mux.Unlock()

index, err := GetWarehouseIndex(keg)
if err != nil {
return err
}

s.Warehouse[index]++
return s.store.SetWarehouse(s.Warehouse)
}

func (s *Scale) DecreaseWarehouse(keg int) error {
s.mux.Lock()
defer s.mux.Unlock()

index, err := GetWarehouseIndex(keg)
if err != nil {
return err
}

s.Warehouse[index]--
return s.store.SetWarehouse(s.Warehouse)
}
2 changes: 2 additions & 0 deletions backend/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ type Storage interface {
GetBeersLeft() (int, error) // get beers left
SetIsLow(isLow bool) error // set is low flag
GetIsLow() (bool, error) // get is low flag
SetWarehouse(warehouse [5]int) error // set warehouse
GetWarehouse() ([5]int, error) // get warehouse
}
9 changes: 9 additions & 0 deletions backend/store_fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,12 @@ func (s *FakeStore) SetIsLow(isLow bool) error {
func (s *FakeStore) GetIsLow() (bool, error) {
return s.isLow, nil
}

func (s *FakeStore) SetWarehouse(warehouse [5]int) error {
return nil
}

func (s *FakeStore) GetWarehouse() ([5]int, error) {
var warehouse = [5]int{1, 2, 3, 4, 5}
return warehouse, nil
}
35 changes: 35 additions & 0 deletions backend/store_redis.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import (
"bytes"
"context"
"encoding/gob"
"fmt"
"github.com/redis/go-redis/v9"
"strconv"
"strings"
)

const (
ActiveKegKey = "active_keg"
MeasurementListKey = "measurements"
IsLowKey = "is_low"
BeersLeftKey = "beers_left"
WarehouseKey = "warehouse"
)

type RedisStore struct {
Expand Down Expand Up @@ -87,3 +91,34 @@ func (s *RedisStore) SetBeersLeft(beersLeft int) error {
func (s *RedisStore) GetBeersLeft() (int, error) {
return s.Client.Get(context.Background(), BeersLeftKey).Int()
}

func (s *RedisStore) SetWarehouse(warehouse [5]int) error {
val := fmt.Sprintf("%d,%d,%d,%d,%d", warehouse[0], warehouse[1], warehouse[2], warehouse[3], warehouse[4])
return s.Client.Set(context.Background(), WarehouseKey, val, 0).Err()
}

func (s *RedisStore) GetWarehouse() ([5]int, error) {
res, err := s.Client.Get(context.Background(), "warehouse").Result()
if err != nil {
return [5]int{0, 0, 0, 0, 0}, err
}

var warehouse [5]int
parts := strings.Split(res, ",")

if len(parts) != 5 {
return [5]int{0, 0, 0, 0, 0}, fmt.Errorf("invalid warehouse format in the storage")
}

for i, part := range parts {
x, err := strconv.Atoi(part)
if err != nil {
return [5]int{0, 0, 0, 0, 0}, fmt.Errorf("invalid warehouse format in the storage")
}

warehouse[i] = x

}

return warehouse, nil
}
2 changes: 1 addition & 1 deletion backend/test.http
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ POST http://localhost:8080/api/scale/push
Content-Type: text/plain
Authorization: test

push|1234|-74|7000.0
push|1234|-74|16000.0

### Ping
POST http://localhost:8080/api/scale/push
Expand Down
21 changes: 21 additions & 0 deletions backend/warehouse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package main

import "fmt"

// GetWarehouseIndex returns the index of the keg in the warehouse array
func GetWarehouseIndex(keg int) (int, error) {
switch keg {
case 10:
return 0, nil
case 15:
return 1, nil
case 20:
return 2, nil
case 30:
return 3, nil
case 50:
return 4, nil
}

return 0, fmt.Errorf("invalid keg") // should never happen
}
24 changes: 23 additions & 1 deletion frontend/src/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,28 @@ function Dashboard() {
},
active_keg: 0,
is_low: false,
warehouse: [
{
"keg": 10,
"amount": 0
},
{
"keg": 15,
"amount": 0
},
{
"keg": 20,
"amount": 0
},
{
"keg": 30,
"amount": 0
},
{
"keg": 50,
"amount": 0
}
]
}

const [scale, setScale] = useState(defaultScale);
Expand Down Expand Up @@ -71,7 +93,7 @@ function Dashboard() {
setShowKeg(true)
}}/>

<Warehouse showCanvas={showWarehouse} setShowCanvas={setShowWarehouse}/>
<Warehouse warehouse={scale.warehouse} showCanvas={showWarehouse} setShowCanvas={setShowWarehouse} refresh={refresh}/>
<Keg keg={scale.active_keg} showCanvas={showKeg} setShowCanvas={setShowKeg} refresh={refresh}/>

<Row md={12} style={{textAlign: "center", marginTop: "30px"}}>
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/Menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ function Menu(props) {
props.showKeg()
}}>Keg</Nav.Link>

{/*<Nav.Link onClick={() => {*/}
{/* props.showWarehouse()*/}
{/*}}>Sklad</Nav.Link>*/}
<Nav.Link onClick={() => {
props.showWarehouse()
}}>Sklad</Nav.Link>

</Nav>
</Navbar.Collapse>
Expand Down
Loading

0 comments on commit eaf95fa

Please sign in to comment.