commit f2aae6125d55dc797a9dcf778904a3522ce37664 Author: Aaron Bieber Date: Tue Dec 1 07:22:27 2020 -0700 initial diff --git a/main.go b/main.go new file mode 100644 index 0000000..656496f --- /dev/null +++ b/main.go @@ -0,0 +1,150 @@ +package main + +import ( + "bufio" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "net/url" + "os" + "strconv" + "strings" + "time" +) + +// AcuTime is a representation of time from the accurite +type AcuTime struct { + time.Time +} + +var cTime = "2006-01-02 15:04:05" + +func (ct *AcuTime) UnmarshalJSON(b []byte) (err error) { + s := strings.Trim(string(b), "\"") + if s == "null" { + ct.Time = time.Time{} + return + } + ct.Time, err = time.Parse(cTime, s) + return +} + +func (ct *AcuTime) MarshalJSON() ([]byte, error) { + if ct.Time.UnixNano() == nilTime { + return []byte("null"), nil + } + return []byte(fmt.Sprintf("\"%s\"", ct.Time.Format(cTime))), nil +} + +var nilTime = (time.Time{}).UnixNano() + +func (ct *AcuTime) IsSet() bool { + return ct.UnixNano() != nilTime +} + +/* +// UnmarshalJSON specifies our custom format for timestamps +func (t AcuTime) UnmarshalJSON(a []byte) error { + // Mon Jan 2 15:04:05 MST 2006 + // 2018/02/15 11:25:27 + var err error + s := strings.Replace(string(a), `"`, "", -1) + t.Time, err = time.Parse(cTime, s) + return err +} +*/ + +// Entry is a single json blob that is output by rtl_433 +type Entry struct { + Time AcuTime `json:"time"` + Model string `json:"model"` + SensorID int `json:"sensor_id"` + Channel string `json:"channel"` + Sequence int `json:"sequence_num"` + Battery string `json:"battery"` + MessageTypeOne int + MessageTypeTwo int + MessageType int `json:"message_type"` + WindSpeed float64 `json:"wind_speed_mph"` + WindDirDeg float64 `json:"wind_dir_deg"` + WindDir string `json:"wind_dir"` + Rain float64 `json:"rainfall_accumulation_inch"` + TempF float64 `json:"temperature_F"` + Humidity int64 `json:"humidity"` +} + +func sendData(e Entry) error { + ws := strconv.FormatFloat(e.WindSpeed, 'f', -1, 64) + wdd := strconv.FormatFloat(e.WindDirDeg, 'f', -1, 64) + rain := strconv.FormatFloat(e.Rain, 'f', -1, 64) + tempf := strconv.FormatFloat(e.TempF, 'f', -1, 64) + humidity := strconv.FormatInt(e.Humidity, 10) + tm := e.Time.Format("2006-01-02T15:04:05.999Z") + fd := url.Values{ + "sensor": []string{"AcuRite"}, + "timestamp": []string{tm}, + "humidity": []string{humidity}, + "temp": []string{tempf}, + "rain": []string{rain}, + "wind_direction": []string{e.WindDir}, + "wind_dir_deg": []string{wdd}, + "wind_speed": []string{ws}, + "battery": []string{e.Battery}, + } + + resp, err := http.PostForm("https://data.bolddaemon.com/data/store", fd) + if err != nil { + return err + } + + defer resp.Body.Close() + body, berr := ioutil.ReadAll(resp.Body) + if berr != nil { + return berr + } + + log.Println(string(body)) + + return err +} + +func main() { + scanner := bufio.NewScanner(os.Stdin) + var m Entry + m.MessageTypeOne = 0 + m.MessageTypeTwo = 0 + for scanner.Scan() { + dec := json.NewDecoder(strings.NewReader(scanner.Text())) + if err := dec.Decode(&m); err == io.EOF { + break + } else if err != nil { + log.Println(err) + break + //log.Fatal(err) + } + if m.Sequence == 2 { + if m.MessageTypeOne == 0 { + m.MessageTypeOne = m.MessageType + } else { + if m.MessageTypeOne != 0 && m.MessageTypeTwo == 0 { + m.MessageTypeOne = m.MessageType + m.MessageTypeTwo = m.MessageType + + err := sendData(m) + if err != nil { + log.Fatal(err) + } + + m.MessageTypeOne = 0 + m.MessageTypeTwo = 0 + } + } + } + if err := scanner.Err(); err != nil { + fmt.Fprintln(os.Stderr, "ohgod", err) + } + } +}