Compare commits
6 Commits
8f0fd525d9
...
water
Author | SHA1 | Date | |
---|---|---|---|
4efce925f0 | |||
c85d0d1f68 | |||
b76d394b16 | |||
ce31b61b1b | |||
9cf9fb7263 | |||
d6d09abe9f |
@@ -82,7 +82,7 @@ func moisture() (types.Telemetry, error) {
|
|||||||
// re-calculate to %
|
// re-calculate to %
|
||||||
// 100 % := 3.0 V
|
// 100 % := 3.0 V
|
||||||
// 0 % := 0.0 V
|
// 0 % := 0.0 V
|
||||||
ret.Value = -0.03*ret.Value + 3
|
ret.Value = -33.333*ret.Value + 100
|
||||||
ret.Unit = "%"
|
ret.Unit = "%"
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
apiservice_devices "waterservice/internal/apiservice/devices"
|
apiservice_devices "waterservice/internal/apiservice/devices"
|
||||||
|
"waterservice/internal/app/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
type state string
|
type state string
|
||||||
@@ -22,6 +23,7 @@ type State struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
storage_path = "/var/lib/waterservice/state/state.json"
|
||||||
StateOn state = "on"
|
StateOn state = "on"
|
||||||
StateOff state = "off"
|
StateOff state = "off"
|
||||||
)
|
)
|
||||||
@@ -31,12 +33,14 @@ var (
|
|||||||
|
|
||||||
state_cache map[string]State
|
state_cache map[string]State
|
||||||
state_mutex sync.Mutex
|
state_mutex sync.Mutex
|
||||||
|
store storage.Storage
|
||||||
cb_register_off registerOffSwitch
|
cb_register_off registerOffSwitch
|
||||||
cb_unregister_off registerOffSwitch
|
cb_unregister_off registerOffSwitch
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||||
|
store.SetPath(storage_path)
|
||||||
state_cache = map[string]State{}
|
state_cache = map[string]State{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +50,10 @@ func AddHandler() {
|
|||||||
|
|
||||||
func Start() {
|
func Start() {
|
||||||
state_mutex.Lock()
|
state_mutex.Lock()
|
||||||
|
res, err := store.Read()
|
||||||
|
if err != nil {
|
||||||
|
logger.Print(err)
|
||||||
|
// build default state_cache
|
||||||
for _, device := range apiservice_devices.GetDevices().Devices {
|
for _, device := range apiservice_devices.GetDevices().Devices {
|
||||||
tmp := State{
|
tmp := State{
|
||||||
Name: device.Name,
|
Name: device.Name,
|
||||||
@@ -54,6 +62,12 @@ func Start() {
|
|||||||
}
|
}
|
||||||
state_cache[device.Name] = tmp
|
state_cache[device.Name] = tmp
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
err = json.Unmarshal(res, &state_cache)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
state_mutex.Unlock()
|
state_mutex.Unlock()
|
||||||
|
|
||||||
go poll_states()
|
go poll_states()
|
||||||
@@ -84,6 +98,15 @@ func SetState(st State) error {
|
|||||||
tmp := state_cache[dev.Name]
|
tmp := state_cache[dev.Name]
|
||||||
tmp.State = st.State
|
tmp.State = st.State
|
||||||
state_cache[dev.Name] = tmp
|
state_cache[dev.Name] = tmp
|
||||||
|
res, err := json.Marshal(state_cache)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print("unable to store state cache")
|
||||||
|
} else {
|
||||||
|
err = store.Write(res)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
state_mutex.Unlock()
|
state_mutex.Unlock()
|
||||||
if cb_register_off != nil && cb_unregister_off != nil {
|
if cb_register_off != nil && cb_unregister_off != nil {
|
||||||
if st.State == StateOn {
|
if st.State == StateOn {
|
||||||
@@ -104,6 +127,15 @@ func SetRuntime(name string, runtime time.Duration) {
|
|||||||
tmp := state_cache[name]
|
tmp := state_cache[name]
|
||||||
tmp.Runtime = runtime
|
tmp.Runtime = runtime
|
||||||
state_cache[name] = tmp
|
state_cache[name] = tmp
|
||||||
|
res, err := json.Marshal(state_cache)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print("unable to store state cache")
|
||||||
|
} else {
|
||||||
|
err = store.Write(res)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
state_mutex.Unlock()
|
state_mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,6 +198,15 @@ func handle_patch(r *http.Request) error {
|
|||||||
tmp := state_cache[dev.Name]
|
tmp := state_cache[dev.Name]
|
||||||
tmp.State = st.State
|
tmp.State = st.State
|
||||||
state_cache[dev.Name] = tmp
|
state_cache[dev.Name] = tmp
|
||||||
|
res, err := json.Marshal(state_cache)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print("unable to store state cache")
|
||||||
|
} else {
|
||||||
|
err = store.Write(res)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
state_mutex.Unlock()
|
state_mutex.Unlock()
|
||||||
if cb_register_off != nil && cb_unregister_off != nil {
|
if cb_register_off != nil && cb_unregister_off != nil {
|
||||||
if st.State == StateOn {
|
if st.State == StateOn {
|
||||||
@@ -213,6 +254,15 @@ func poll_states() {
|
|||||||
tmp := state_cache[dev.Name]
|
tmp := state_cache[dev.Name]
|
||||||
tmp.State = status
|
tmp.State = status
|
||||||
state_cache[dev.Name] = tmp
|
state_cache[dev.Name] = tmp
|
||||||
|
res, err := json.Marshal(state_cache)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print(err)
|
||||||
|
} else {
|
||||||
|
err = store.Write(res)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
state_mutex.Unlock()
|
state_mutex.Unlock()
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second * 10)
|
time.Sleep(time.Second * 10)
|
||||||
|
@@ -27,7 +27,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SetConfigFilePath(path string) {
|
func SetConfigFilePath(path string) {
|
||||||
store.Path = path
|
store.SetPath(path)
|
||||||
res, err := store.Read()
|
res, err := store.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Print("unable to read config")
|
logger.Print("unable to read config")
|
||||||
|
@@ -31,17 +31,17 @@ func init() {
|
|||||||
app_state_cache.Mode = ModeManual
|
app_state_cache.Mode = ModeManual
|
||||||
|
|
||||||
// override defaults with stored values
|
// override defaults with stored values
|
||||||
store.Path = app_state_storage_path
|
store.SetPath(app_state_storage_path)
|
||||||
res, err := store.Read()
|
res, err := store.Read()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Print("unable to read app state cache")
|
logger.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app_state_mutex.Lock()
|
app_state_mutex.Lock()
|
||||||
err = json.Unmarshal(res, &app_state_cache)
|
err = json.Unmarshal(res, &app_state_cache)
|
||||||
app_state_mutex.Unlock()
|
app_state_mutex.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Print("unable to evaluate config data")
|
logger.Print(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,10 +50,13 @@ func SetMode(mode AppMode) {
|
|||||||
app_state_cache.Mode = mode
|
app_state_cache.Mode = mode
|
||||||
res, err := json.Marshal(app_state_cache)
|
res, err := json.Marshal(app_state_cache)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Print("unable to store app state cache")
|
logger.Print(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
store.Write(res)
|
err = store.Write(res)
|
||||||
|
if err != nil {
|
||||||
|
logger.Print(err)
|
||||||
|
}
|
||||||
app_state_mutex.Unlock()
|
app_state_mutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +80,7 @@ func app_state_saver() {
|
|||||||
res, err := json.Marshal(app_state_cache)
|
res, err := json.Marshal(app_state_cache)
|
||||||
app_state_mutex.Unlock()
|
app_state_mutex.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Print("unable to marshal object to json")
|
logger.Print(err)
|
||||||
time.Sleep(time.Minute)
|
time.Sleep(time.Minute)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -87,6 +90,8 @@ func app_state_saver() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func poll_auto_off() {
|
func poll_auto_off() {
|
||||||
|
now := time.Now()
|
||||||
|
today := time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location())
|
||||||
for {
|
for {
|
||||||
app_state_mutex.Lock()
|
app_state_mutex.Lock()
|
||||||
for i, od := range app_state_cache.off_devices {
|
for i, od := range app_state_cache.off_devices {
|
||||||
@@ -115,6 +120,20 @@ func poll_auto_off() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
app_state_mutex.Unlock()
|
app_state_mutex.Unlock()
|
||||||
|
|
||||||
|
// check date change
|
||||||
|
now := time.Now()
|
||||||
|
if now.After(today) {
|
||||||
|
logger.Print("date change detected")
|
||||||
|
// reset date
|
||||||
|
today = time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, now.Location())
|
||||||
|
devices := apiservice_devices.GetDevices()
|
||||||
|
for _, d := range devices.Devices {
|
||||||
|
// reset run times
|
||||||
|
apiservice_state.SetRuntime(d.Name, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
time.Sleep(time.Second)
|
time.Sleep(time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,7 +142,6 @@ func register_off_device(dev apiservice_devices.Device) {
|
|||||||
for _, od := range app_state_cache.off_devices {
|
for _, od := range app_state_cache.off_devices {
|
||||||
if od.device.Name == dev.Name {
|
if od.device.Name == dev.Name {
|
||||||
// device already in off list
|
// device already in off list
|
||||||
// FIXME: update off time
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,13 +1,14 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Storage struct {
|
type Storage struct {
|
||||||
Path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -18,17 +19,24 @@ func init() {
|
|||||||
logger.SetFlags(log.Llongfile | log.Ltime)
|
logger.SetFlags(log.Llongfile | log.Ltime)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage Storage) Read() ([]byte, error) {
|
func (s *Storage) SetPath(path string) {
|
||||||
data, err := os.ReadFile(storage.Path)
|
s.path = path
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Storage) Read() ([]byte, error) {
|
||||||
|
if len(s.path) == 0 {
|
||||||
|
return nil, errors.New("path not set")
|
||||||
|
}
|
||||||
|
data, err := os.ReadFile(s.path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("unable to read %s (%s)", storage.Path, err.Error())
|
logger.Printf("unable to read %s (%s)", s.path, err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (storage Storage) Write(data []byte) error {
|
func (s Storage) Write(data []byte) error {
|
||||||
dir := filepath.Dir(storage.Path)
|
dir := filepath.Dir(s.path)
|
||||||
_, err := os.Stat(dir)
|
_, err := os.Stat(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
@@ -42,9 +50,9 @@ func (storage Storage) Write(data []byte) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = os.WriteFile(storage.Path, data, 0644)
|
err = os.WriteFile(s.path, data, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Printf("unable to store %s (%s)", storage.Path, err.Error())
|
logger.Printf("unable to store %s (%s)", s.path, err.Error())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -119,13 +119,11 @@
|
|||||||
|
|
||||||
function check(checkbox, name) {
|
function check(checkbox, name) {
|
||||||
var obj;
|
var obj;
|
||||||
console.log("name: ", name);
|
|
||||||
if(checkbox.checked) {
|
if(checkbox.checked) {
|
||||||
obj = '{"name":"' + name + '","state":"on"}'
|
obj = '{"name":"' + name + '","state":"on"}'
|
||||||
} else {
|
} else {
|
||||||
obj = '{"name":"' + name + '","state":"off"}'
|
obj = '{"name":"' + name + '","state":"off"}'
|
||||||
}
|
}
|
||||||
console.log(obj);
|
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
xhr.open("PATCH", "/state");
|
xhr.open("PATCH", "/state");
|
||||||
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
|
xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");
|
||||||
|
Reference in New Issue
Block a user