cc 3 роки тому
батько
коміт
a4ffa0c5fe

Різницю між файлами не показано, бо вона завелика
+ 611 - 872
domoticz/inject_meter_history.py


+ 14 - 0
graphite-ingest/Dockerfile

@@ -0,0 +1,14 @@
+FROM balenalib/raspberry-pi-python:3.10-buster
+
+ENV DEBIAN_FRONTEND=noninteractive \
+    DEBIAN_PRIORITY=critical \
+    DEBCONF_NOWARNINGS=yes
+
+RUN apt-get update && apt-get install netcat
+RUN pip install flask statsd
+
+CMD python -u /app/server.py
+
+EXPOSE 80
+
+COPY server.py /app/server.py

+ 87 - 0
graphite-ingest/server.py

@@ -0,0 +1,87 @@
+import logging, os
+from functools import wraps
+
+from flask import Flask, request
+app = Flask(__name__)
+
+log = logging.getLogger('werkzeug')
+#~ log.setLevel(logging.ERROR)
+app.logger.disabled = True
+log.disabled = True
+
+log = logging.getLogger()
+log.setLevel(logging.DEBUG)
+
+streamhandler = logging.StreamHandler()
+streamhandler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s",'%Y-%m-%d %X'))
+log.addHandler(streamhandler)
+
+
+from statsd import StatsClient
+statsd_host = os.environ.get('STATSD_HOST', 'host.docker.internal')
+log.info('using statsd at %s:%s' % (statsd_host, 8125))
+statsd = StatsClient(statsd_host, 8125)
+
+def login_required(f):
+    @wraps(f)
+    def wrapped_view(**kwargs):
+        auth = request.authorization
+        if not (auth and auth.username == 'xxx' and auth.password == '123'):
+            return ('Unauthorized', 401, {
+                'WWW-Authenticate': 'Basic realm="Login Required"'
+            })
+
+        return f(**kwargs)
+
+    return wrapped_view
+
+
+OLD_VALUES = {}
+
+@app.route("/api")
+@login_required
+def api():
+    try:
+        args = request.args
+        name = args['name'].lower()
+        # XXX: domoticz doesnt send spaced named (is buggy)
+        # this was only a failed hack, but let's keep it
+        name = name.replace(' ', '-')
+
+        # ugly fugly
+        name = name.replace('ü', 'ue').replace('ä', 'ae').replace('ö', 'oe')
+        name = name.replace('ã¼', 'ue').replace('ã¶', 'oe').replace('ã¤', 'ae')
+
+        type = args['type']
+        value = args['value']
+
+        #~ log.info('%r' % args)
+        if type == 'power_instant':
+            v = int(float(value))
+            log.debug('%s %s: %s' % (type, name, v))
+            statsd.gauge('domo.%s.power_instant' % name, v)
+        elif type == 'temp':
+            v = float(value)
+            log.debug('%s %s: %s' % (type, name, v))
+            statsd.gauge('domo.%s.temp' % name, v)
+
+        elif type == 'power_usage':
+            v = int(float(value))
+            old_v = int(float(OLD_VALUES.get((name, type), v)))
+            delta = v - old_v
+            if delta > 0:
+                log.debug('%s %s: %s' % (type, name, delta))
+                statsd.incr('domo.%s.power_usage' % name, delta)
+
+        OLD_VALUES[(name, type)] = value
+        return ''
+    except Exception:
+        log.exception('arror during api')
+
+@app.route("/")
+def index():
+    return '<br/>'.join('%s %s: %s' % (name, type, v) for (name, type), v in OLD_VALUES.items())
+
+if __name__ == '__main__':
+    log.info('startup flask')
+    app.run(debug=False, host='0.0.0.0', port=80)

+ 4 - 24
graphite/Dockerfile

@@ -1,25 +1,5 @@
-FROM resin/rpi-raspbian:jessie-20170531
+FROM graphiteapp/graphite-statsd
+# for service commands
+RUN apk add tcpdump
 
-RUN apt-get -y update \
-  && apt-get -y upgrade \
-  && apt-get -y install vim \
-  nginx \
-  python-dev \
-  python-flup \
-  python-pip \
-  python-ldap \
-  expect \
-  git \
-  memcached \
-  sqlite3 \
-  libffi-dev \
-  libcairo2 \
-  libcairo2-dev \
-  python-cairo \
-  python-rrdtool \
-  pkg-config \
-  nodejs \
-  && rm -rf /var/lib/apt/lists/*
-
-ENV CONTAINER_TIMEZONE=Europe/Berlin
-ENV DEBIAN_FRONTEND noninteractive
+COPY storage-schemas.conf /opt/graphite/conf/storage-schemas.conf

+ 32 - 0
graphite/storage-schemas.conf

@@ -0,0 +1,32 @@
+# Schema definitions for Whisper files. Entries are scanned in order,
+# and first match wins. This file is scanned for changes every 60 seconds.
+#
+# Definition Syntax:
+#
+#    [name]
+#    pattern = regex
+#    retentions = timePerPoint:timeToStore, timePerPoint:timeToStore, ...
+#
+# Remember: To support accurate aggregation from higher to lower resolution
+#           archives, the precision of a longer retention archive must be
+#           cleanly divisible by precision of next lower retention archive.
+#
+#           Valid:    60s:7d,300s:30d (300/60 = 5)
+#           Invalid:  180s:7d,300s:30d (300/180 = 3.333)
+#
+
+# Carbon's internal metrics. This entry should match what is specified in
+# CARBON_METRIC_PREFIX and CARBON_METRIC_INTERVAL settings
+[carbon]
+pattern = ^carbon\.
+retentions = 10s:6h,1m:90d
+
+[highres_domoticz]
+pattern = ^domo\.
+retentions = 5s:24h,1m:14d,10m:3600d
+
+
+[default_1min_for_1day]
+pattern = .*
+retentions = 10s:6h,1m:6d,10m:1800d
+

+ 2 - 2
hosts.yml

@@ -30,7 +30,7 @@ all:
       ansible_ssh_host: waldbeere.fritz.box
     stachelbeere:
       ansible_ssh_host: stachelbeere.fritz.box
-    #~ brombeere:
-      #~ ansible_ssh_host: brombeere.fritz.box
+    brombeere:
+      ansible_ssh_host: brombeere.fritz.box
 
 

+ 1 - 1
jlab/Dockerfile

@@ -1,7 +1,7 @@
 # This file creates a container that runs a jupyter lab server on Raspberry Pi
 # Originally from: https://github.com/mkjiang/rpi-jupyter/blob/master/Dockerfile and https://github.com/kidig/rpi-jupyter-lab/blob/master/Dockerfile
 
-FROM balenalib/raspberry-pi-python:3.9-stretch-build
+FROM balenalib/raspberry-pi-python:3.10-buster-build
 
 WORKDIR /root
 

+ 36 - 6
services.yml

@@ -46,6 +46,11 @@ domoticz:
       - /mnt/ssdext/data/domoticz:/opt/domoticz/userdata
     ports: 8080:80
     devices: /dev/ttyUSB0
+    extra_hosts:
+      # reaching graphite-ingest locally
+      # if we use FQDN - nginx (ngp) has a high load
+      # maybe HTTPS decryption is slow on raspi 3 (himbeere)
+      host.docker.internal: host-gateway
     env:
       TZ: Europe/Amsterdam
       WWW_PORT: 80
@@ -101,18 +106,43 @@ grafana:
 
 graphite: # https://hub.docker.com/r/graphiteapp/graphite-statsd/
   host: himbeere
+  fqdn: graphite.cere.duckdns.org
   docker:
-    #~ build: graphite
-    image: graphiteapp/graphite-statsd
+    build: graphite
+    #~ image: graphiteapp/graphite-statsd
     volumes:
       - /mnt/ssdext/data/graphite/storage:/opt/graphite/storage
       - /mnt/ssdext/data/graphite/log:/var/log
       - /mnt/ssdext/data/graphite/redis:/var/lib/redis
       #~ - /mnt/ssdext/data/graphite/logs:/var/log/supervisor
-    #~ ports:
-      #~ - 13080:8000
-      #~ - 8125:8125/udp
-      #~ - 8126:8126
+    ports:
+      - 0.0.0.0:8125:8125/udp
+    #~ env:
+      #~ GRAPHITE_STATSD_HOST: 0.0.0.0
+  commands:
+    # dump incoming udp traffic
+    dump_8125: tcpdump -i eth0 udp port 8125 -vv -X
+    # dump outgoing traffic - see bucky.conf/statsd_flush_time
+    #~ dump_2003: tcpdump -i eth0 tcp port 2003 -vv -X
+    # tail bucky logs
+    #~ tail_bucky: supervisorctl tail bucky
+
+graphite-ingest: # ingest data into graphite via http
+  fqdn: ingest.cere.duckdns.org
+  docker:
+    build: graphite-ingest
+    #~ links: graphite:graphite
+    init: true
+    ports:
+      # accessed from domoticz
+      - 0.0.0.0:25080:80
+    env:
+      STATSD_HOST: host.docker.internal
+    extra_hosts:
+      host.docker.internal: host-gateway
+  commands:
+    test_8125: /bin/bash -c 'echo "deploys.test.myservice:1|c" | nc -w 1 -u host.docker.internal 8125'
+
 
 netdata:
   host: himbeere

Деякі файли не було показано, через те що забагато файлів було змінено