Skip to content

Instantly share code, notes, and snippets.

@fuba
Forked from oquno/udco2s.py
Last active March 2, 2024 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fuba/d2608ff4d9a7342e1695adad1906f64a to your computer and use it in GitHub Desktop.
Save fuba/d2608ff4d9a7342e1695adad1906f64a to your computer and use it in GitHub Desktop.
UD-CO2S にシリアル接続してデータを JSON ファイルに上書きし続けるスクリプト を go でサーバにしたやつ
package main
import (
"encoding/json"
"flag"
"fmt"
"io"
"net/http"
"os"
"os/signal"
"regexp"
"strconv"
"syscall"
"time"
"github.com/tarm/serial"
)
type SensorData struct {
Time int64 `json:"time"`
CO2PPM int `json:"co2ppm"`
Humidity float64 `json:"humidity"`
Temperature float64 `json:"temperature"`
}
func (s SensorData) toString() string {
return fmt.Sprintf("Time: %d, CO2PPM: %d, Humidity: %.2f, Temperature: %.2f", s.Time, s.CO2PPM, s.Humidity, s.Temperature)
}
var currentData SensorData
var running = true
func main() {
port := flag.String("p", "8080", "Port number")
flag.Parse()
go startSerial("/dev/ttyACM0")
http.HandleFunc("/sensor.json", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(currentData)
})
go http.ListenAndServe(":"+*port, nil)
// Set up signal handling
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGHUP)
go func() {
for {
sig := <-sigChan
switch sig {
case syscall.SIGHUP:
fmt.Println(sig.String() + " signal received, stopping...")
running = false
return
}
}
}()
// Wait for the signal handler to stop the program
for running {
time.Sleep(1 * time.Second)
}
fmt.Println("Program stopped")
}
func startSerial(dev string) {
cfg := &serial.Config{Name: dev, Baud: 115200, ReadTimeout: time.Second * 6}
s, err := serial.OpenPort(cfg)
if err != nil {
fmt.Println("Error opening serial port:", err)
return
}
defer s.Close()
_, err = s.Write([]byte("STA\r\n"))
if err != nil {
fmt.Println("Error writing to serial port:", err)
return
}
buf := make([]byte, 128)
_, err = s.Read(buf)
if err != nil {
fmt.Println("Error reading from serial port:", err)
return
}
regex := regexp.MustCompile(`CO2=(?P<co2>\d+),HUM=(?P<hum>\d+\.\d+),TMP=(?P<tmp>-?\d+\.\d+)`)
for running {
n, err := s.Read(buf)
if err != nil {
if err != io.EOF {
fmt.Println("Error reading from serial port:", err)
}
break
}
str := string(buf[:n])
matches := regex.FindStringSubmatch(str)
if matches != nil {
co2, _ := strconv.Atoi(matches[1])
hum, _ := strconv.ParseFloat(matches[2], 64)
tmp, _ := strconv.ParseFloat(matches[3], 64)
currentData = SensorData{
Time: time.Now().Unix(),
CO2PPM: co2,
Humidity: hum,
Temperature: tmp,
}
fmt.Println(currentData.toString())
}
}
_, err = s.Write([]byte("STP\r\n"))
if err != nil {
fmt.Println("Error writing to serial port:", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment