diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b6e2e83
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+onewire_exporter
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e2d7e36
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 Martin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e3bd4d4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# onewire_exporter
+
+Prometheus exporter for 1-wire temperature sensors connected to a Raspberry PI
+
+
\ No newline at end of file
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..d8fb1fa
--- /dev/null
+++ b/main.go
@@ -0,0 +1,95 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "os"
+ "path/filepath"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promhttp"
+ "github.com/prometheus/common/log"
+ yaml "gopkg.in/yaml.v2"
+)
+
+const version string = "0.1"
+
+type List struct {
+ Names map[string]string
+}
+
+var (
+ showVersion = flag.Bool("version", false, "Print version information.")
+ listenAddress = flag.String("listen-address", ":9330", "Address on which to expose metrics.")
+ metricsPath = flag.String("path", "/metrics", "Path under which to expose metrics.")
+ ignoreUnknown = flag.Bool("ignore", true, "Ignores sensors without a name")
+ nameFile = flag.String("names", "names.yaml", "File maping IDs to names")
+
+ list List
+)
+
+func init() {
+ flag.Usage = func() {
+ fmt.Println("Usage: onewire_exporter [ ... ]\n\nParameters:")
+ fmt.Println()
+ flag.PrintDefaults()
+ }
+}
+
+func main() {
+ flag.Parse()
+
+ if *showVersion {
+ printVersion()
+ os.Exit(0)
+ }
+
+ filename, _ := filepath.Abs(*nameFile)
+ yamlFile, err := ioutil.ReadFile(filename)
+
+ if err != nil {
+ log.Fatal("Can't read names file")
+ }
+
+ err = yaml.Unmarshal(yamlFile, &list)
+ if err != nil {
+ log.Fatal("Can't read names file")
+ }
+
+ startServer()
+}
+
+func printVersion() {
+ fmt.Println("onewire_exporter")
+ fmt.Printf("Version: %s\n", version)
+}
+
+func startServer() {
+ log.Infof("Starting onewire exporter (Version: %s)\n", version)
+ http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ w.Write([]byte(`
+
onewire Exporter (Version ` + version + `)
+
+ onewire Exporter
+ Metrics
+ More information:
+ github.com/l3akage/onewire_exporter
+
+ `))
+ })
+ http.HandleFunc(*metricsPath, handleMetricsRequest)
+
+ log.Infof("Listening for %s on %s\n", *metricsPath, *listenAddress)
+ log.Fatal(http.ListenAndServe(*listenAddress, nil))
+}
+
+func handleMetricsRequest(w http.ResponseWriter, r *http.Request) {
+ reg := prometheus.NewRegistry()
+ reg.MustRegister(&onewireCollector{})
+
+ promhttp.HandlerFor(reg, promhttp.HandlerOpts{
+ ErrorLog: log.NewErrorLogger(),
+ ErrorHandling: promhttp.ContinueOnError}).ServeHTTP(w, r)
+}
diff --git a/names.yaml b/names.yaml
new file mode 100644
index 0000000..c883eef
--- /dev/null
+++ b/names.yaml
@@ -0,0 +1,2 @@
+names:
+ id: test device
diff --git a/onewire_collector.go b/onewire_collector.go
new file mode 100644
index 0000000..8c1c629
--- /dev/null
+++ b/onewire_collector.go
@@ -0,0 +1,107 @@
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "regexp"
+ "strconv"
+ "strings"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/common/log"
+)
+
+const prefix = "onewire_"
+
+var (
+ upDesc *prometheus.Desc
+ tempDesc *prometheus.Desc
+)
+
+func init() {
+ upDesc = prometheus.NewDesc(prefix+"up", "Scrape was successful", nil, nil)
+ tempDesc = prometheus.NewDesc(prefix+"temp", "Air temperature (in degrees C)", []string{"id", "name"}, nil)
+}
+
+type Temp struct {
+ ID string
+ Value float64
+}
+
+type onewireCollector struct {
+}
+
+func getTemperatures() ([]Temp, error) {
+ reg, err := regexp.Compile("[^0-9]+")
+ if err != nil {
+ log.Fatal(err)
+ }
+ devices, err := ioutil.ReadDir("/sys/bus/w1/devices/")
+ if err != nil {
+ return nil, err
+ }
+ var values []Temp
+ for _, device := range devices {
+ if device.Name() == "w1_bus_master1" {
+ continue
+ }
+ content, err := ioutil.ReadFile("/sys/bus/w1/devices/" + device.Name() + "/w1_slave")
+ if err != nil {
+ log.Infof("Error reading device %s\n", device.Name())
+ continue
+ }
+ lines := strings.Split(string(content), "\n")
+ if len(lines) != 3 {
+ log.Infof("Unknown format for device %s\n", device.Name())
+ continue
+ }
+ if !strings.Contains(lines[0], "YES") {
+ log.Infof("CRC invalid for device %s\n", device.Name())
+ continue
+ }
+ data := strings.SplitAfter(lines[1], "t=")
+ if len(data) != 2 {
+ log.Infof("Temp value not found for device %s\n", device.Name())
+ continue
+ }
+ strValue := reg.ReplaceAllString(data[1], "")
+
+ tempInt, err := strconv.ParseFloat(strValue, 64)
+ if err != nil {
+ continue
+ }
+ values = append(values, Temp{
+ ID: device.Name(),
+ Value: tempInt / 1000.0,
+ })
+ }
+ return values, nil
+}
+
+func (c onewireCollector) Describe(ch chan<- *prometheus.Desc) {
+ ch <- upDesc
+ ch <- tempDesc
+}
+
+func (c onewireCollector) Collect(ch chan<- prometheus.Metric) {
+ values, err := getTemperatures()
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "error getting sensor data", err)
+ ch <- prometheus.MustNewConstMetric(upDesc, prometheus.GaugeValue, 0)
+ } else {
+ for _, sensor := range values {
+ n := list.Names[sensor.ID]
+ if n == "" {
+ if *ignoreUnknown == true {
+ log.Infof("Ingoring unknown device %s\n", sensor.ID)
+ continue
+ } else {
+ n = sensor.ID
+ }
+ }
+ l := []string{sensor.ID, n}
+ ch <- prometheus.MustNewConstMetric(tempDesc, prometheus.GaugeValue, float64(sensor.Value), l...)
+ }
+ }
+}
diff --git a/onewire_exporter.service b/onewire_exporter.service
new file mode 100644
index 0000000..8526eac
--- /dev/null
+++ b/onewire_exporter.service
@@ -0,0 +1,16 @@
+[Unit]
+Description=Prometheus onewire_exporter
+Wants=basic.target
+After=basic.target network.target
+
+[Service]
+User=pi
+Group=pi
+ExecStart=/home/pi/onewire_exporter -names=/home/pi/names.yaml
+
+ExecReload=/bin/kill -HUP $MAINPID
+KillMode=process
+Restart=always
+
+[Install]
+WantedBy=multi-user.target