package main import ( "encoding/json" "fmt" "io" "log" "net/http" "os" "path/filepath" "time" ) var dataFile *os.File var berlinTZ *time.Location type VoltageData struct { Voltage float64 `json:"voltage"` } func init() { var err error berlinTZ, err = time.LoadLocation("Europe/Berlin") if err != nil { log.Fatalf("Failed to load Berlin timezone: %v", err) } } func initDataFile() { // Ensure the data/ directory exists if err := os.MkdirAll("data", os.ModePerm); err != nil { log.Fatalf("Failed to create data directory: %v", err) } // Generate a filename with timestamp in Berlin local time filename := filepath.Join("data", fmt.Sprintf("voltages_%s.csv", time.Now().In(berlinTZ).Format("20060102_150405"))) file, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { log.Fatalf("Failed to open data file: %v", err) } dataFile = file log.Printf("Logging voltage data to %s\n", filename) // Write CSV header _, _ = dataFile.WriteString("timestamp,voltage\n") } func handler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "POST only", http.StatusMethodNotAllowed) return } body, err := io.ReadAll(r.Body) if err != nil { http.Error(w, "read error", http.StatusBadRequest) return } defer r.Body.Close() // Parse JSON var v VoltageData if err := json.Unmarshal(body, &v); err != nil { http.Error(w, "invalid JSON", http.StatusBadRequest) return } // Get current timestamp in Berlin timestamp := time.Now().In(berlinTZ).Format("2006-01-02 15:04:05.000") // Print voltage to console fmt.Printf("Received voltage: %f at %s\n", v.Voltage, timestamp) // Append CSV line to file if dataFile != nil { if _, err := dataFile.WriteString(fmt.Sprintf("%s,%.6f\n", timestamp, v.Voltage)); err != nil { log.Printf("Failed to write to file: %v", err) } } w.WriteHeader(http.StatusOK) w.Write([]byte("ok")) } func main() { initDataFile() defer dataFile.Close() http.HandleFunc("/data", handler) addr := ":8080" log.Println("Listening on", addr) log.Fatal(http.ListenAndServe(addr, nil)) }