136 lines
3.0 KiB
Go
136 lines
3.0 KiB
Go
package shroom_internals
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"log"
|
|
"net"
|
|
"sync"
|
|
)
|
|
|
|
func newlinePos(s []byte) int {
|
|
for i, v := range s {
|
|
if v == '\n' {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
type ShroomData struct {
|
|
Time uint64
|
|
Temperature float32
|
|
Humidity float32
|
|
HumidifierVolts float32
|
|
Status uint32
|
|
}
|
|
|
|
type ShroomStatusData struct {
|
|
Status uint32
|
|
NumConnections int
|
|
}
|
|
|
|
type ShroomStatus struct {
|
|
Status uint32
|
|
NumConnections int
|
|
Lock sync.RWMutex
|
|
}
|
|
|
|
func InitTcpServer(db *sql.DB, status *ShroomStatus) {
|
|
// TODO start TCP server for the pipe from the raspberry pi
|
|
ln, err := net.Listen("tcp", ":9876")
|
|
if err != nil {
|
|
log.Fatal("unable to open tcp server: ", err)
|
|
}
|
|
go func() {
|
|
for {
|
|
conn, err := ln.Accept()
|
|
if err != nil {
|
|
log.Println("tcp accept error: ", err)
|
|
continue
|
|
}
|
|
status.Lock.Lock()
|
|
status.NumConnections += 1
|
|
status.Lock.Unlock()
|
|
|
|
defer func() {
|
|
status.Lock.Lock()
|
|
status.NumConnections -= 1
|
|
status.Lock.Unlock()
|
|
log.Println("connection disconnected")
|
|
}()
|
|
|
|
log.Println("connection started")
|
|
|
|
go func() {
|
|
// TODO deal with the write side of the connection
|
|
}()
|
|
|
|
// deal with the read side of the connection
|
|
buf := make([]byte, 128)
|
|
left := buf
|
|
|
|
for {
|
|
num_read, err := conn.Read(left)
|
|
left = left[num_read:]
|
|
//log.Println("buf ", buf)
|
|
//log.Println("left ", left)
|
|
|
|
if err != nil {
|
|
log.Println("tcp read error: ", err)
|
|
_ = conn.Close()
|
|
log.Println("disconnected from client")
|
|
break
|
|
}
|
|
// parse the message to see if it's finished
|
|
unread := buf[:len(buf)-len(left)]
|
|
|
|
for newlinePos(unread) != -1 {
|
|
end := newlinePos(unread)
|
|
line := unread[:end]
|
|
unread = unread[end+1:]
|
|
|
|
//log.Println("line ", line)
|
|
//log.Println("unread ", unread)
|
|
// skip empty lines
|
|
if len(line) == 0 {
|
|
continue
|
|
}
|
|
data := ShroomData{
|
|
Time: 0,
|
|
Temperature: -1,
|
|
Humidity: -1,
|
|
HumidifierVolts: -1,
|
|
Status: 0,
|
|
}
|
|
err := json.Unmarshal(line, &data)
|
|
if err != nil {
|
|
log.Println("unable to read humdifier data: ", err)
|
|
log.Println(string(line))
|
|
log.Println(line)
|
|
continue
|
|
}
|
|
if data.Time > 0 && data.Temperature > 0 && data.Humidity > 0 && data.HumidifierVolts > 0 {
|
|
// we got a data packet
|
|
_, err = db.Exec("INSERT INTO shrooms (time, temperature, humidity, humidifier_volts) VALUES (?, ?, ?, ?)",
|
|
data.Time, data.Temperature, data.Humidity, data.HumidifierVolts)
|
|
if err != nil {
|
|
log.Println("unable to write to database: ", err)
|
|
}
|
|
} else if data.Status > 0 {
|
|
status.Lock.Lock()
|
|
// TODO change to have more detailed data
|
|
status.Status = data.Status
|
|
status.Lock.Unlock()
|
|
} else {
|
|
log.Println("unknown packet: ", line)
|
|
}
|
|
}
|
|
// shift the remaining data back to the start of the buffer
|
|
copy(buf[:len(unread)], unread)
|
|
left = buf[len(unread):]
|
|
}
|
|
}
|
|
}()
|
|
}
|