package main import ( "database/sql" "encoding/json" "fmt" "html/template" "log" "net/http" "time" _ "github.com/mattn/go-sqlite3" ) type LDRReading struct { Value int `json:"value"` Timestamp time.Time `json:"timestamp"` } var db *sql.DB func initDB() { var err error db, err = sql.Open("sqlite3", "./ldr_readings.db") if err != nil { log.Fatal(err) } createTable := ` CREATE TABLE IF NOT EXISTS ldr_readings ( id INTEGER PRIMARY KEY AUTOINCREMENT, value INTEGER NOT NULL, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP );` _, err = db.Exec(createTable) if err != nil { log.Fatal(err) } } func handleLDRReading(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } var reading LDRReading if err := json.NewDecoder(r.Body).Decode(&reading); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } _, err := db.Exec("INSERT INTO ldr_readings (value, timestamp) VALUES (?, ?)", reading.Value, reading.Timestamp) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) } func handleGetReadings(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) return } period := r.URL.Query().Get("period") var query string var args []interface{} switch period { case "day": query = "SELECT value, timestamp FROM ldr_readings WHERE timestamp >= datetime('now', '-1 day') ORDER BY timestamp" case "week": query = "SELECT value, timestamp FROM ldr_readings WHERE timestamp >= datetime('now', '-7 day') ORDER BY timestamp" case "month": query = "SELECT value, timestamp FROM ldr_readings WHERE timestamp >= datetime('now', '-30 day') ORDER BY timestamp" default: query = "SELECT value, timestamp FROM ldr_readings ORDER BY timestamp" } rows, err := db.Query(query, args...) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } defer rows.Close() var readings []LDRReading for rows.Next() { var r LDRReading if err := rows.Scan(&r.Value, &r.Timestamp); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } readings = append(readings, r) } w.Header().Set("Content-Type", "application/json") w.Header().Set("Access-Control-Allow-Origin", "*") json.NewEncoder(w).Encode(readings) } func handleIndex(w http.ResponseWriter, r *http.Request) { tmpl := template.Must(template.ParseFiles("web/templates/index.html")) tmpl.Execute(w, nil) } func main() { initDB() defer db.Close() http.HandleFunc("/", handleIndex) http.HandleFunc("/api/ldr", handleLDRReading) http.HandleFunc("/api/readings", handleGetReadings) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static")))) fmt.Println("Server starting on :8080...") log.Fatal(http.ListenAndServe(":8080", nil)) }