From a28e59085a0b24f89a288134d2866c56341be444 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jari-Matti=20M=C3=A4kel=C3=A4?= <jmjmak@utu.fi>
Date: Sat, 31 May 2025 20:03:17 +0300
Subject: [PATCH] Update examples

---
 stuff/api-examples/README.md                  |  7 ++
 stuff/api-examples/test-collectd.sh           | 23 -------
 stuff/api-examples/test-sut-old.sh            | 25 ++++----
 stuff/api-examples/test-sut.sh                | 31 +++++----
 stuff/api-examples/test.py                    | 39 -----------
 stuff/client-library/{README => README.md}    | 18 ++++++
 stuff/client-library/powergoblin.py           | 36 +++++------
 stuff/client-library/powergoblin.sh           | 29 ++++-----
 stuff/client-library/seleniumdriver.py        |  2 +-
 stuff/client-library/test.py                  |  2 +-
 stuff/client-library/test.sh                  |  2 +-
 stuff/collectd-example/README.md              | 14 ++++
 stuff/collectd-nvml/README.md                 | 36 +++++++++++
 stuff/collectd-nvml/collect.sh                | 64 +++++++++++++++++++
 stuff/collectd-rapl/README.md                 | 17 ++++-
 stuff/collectd-rapl/collect.sh                |  1 +
 .../{docker => docker-example}/.gitlab-ci.yml |  0
 stuff/{docker => docker-example}/Dockerfile   |  0
 stuff/{docker => docker-example}/README.md    |  7 ++
 stuff/docker-example/original.py              | 35 ++++++++++
 .../{docker => docker-example}/powergoblin.py | 36 +++++------
 .../{docker => docker-example}/simulation.py  | 14 ++--
 stuff/report-example/README.md                | 42 +++++++-----
 stuff/report-example/test-report.sh           | 26 ++++++++
 stuff/report-example/test-sut.sh              | 36 -----------
 stuff/rpi-dietpi/README.md                    |  2 +
 stuff/rpi-dietpi/rpi.sh                       |  2 +-
 27 files changed, 334 insertions(+), 212 deletions(-)
 create mode 100644 stuff/api-examples/README.md
 delete mode 100755 stuff/api-examples/test-collectd.sh
 delete mode 100644 stuff/api-examples/test.py
 rename stuff/client-library/{README => README.md} (67%)
 create mode 100644 stuff/collectd-nvml/README.md
 create mode 100755 stuff/collectd-nvml/collect.sh
 rename stuff/{docker => docker-example}/.gitlab-ci.yml (100%)
 rename stuff/{docker => docker-example}/Dockerfile (100%)
 rename stuff/{docker => docker-example}/README.md (81%)
 create mode 100644 stuff/docker-example/original.py
 rename stuff/{docker => docker-example}/powergoblin.py (85%)
 rename stuff/{docker => docker-example}/simulation.py (85%)
 create mode 100755 stuff/report-example/test-report.sh
 delete mode 100755 stuff/report-example/test-sut.sh
 create mode 100644 stuff/rpi-dietpi/README.md

diff --git a/stuff/api-examples/README.md b/stuff/api-examples/README.md
new file mode 100644
index 0000000..370fc2b
--- /dev/null
+++ b/stuff/api-examples/README.md
@@ -0,0 +1,7 @@
+---
+name: Client script example
+author: Captain Planet
+---
+
+This folder contains client side scripts for interfacing
+with PowerGoblin, without the client library.
diff --git a/stuff/api-examples/test-collectd.sh b/stuff/api-examples/test-collectd.sh
deleted file mode 100755
index 95673bc..0000000
--- a/stuff/api-examples/test-collectd.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-
-HOST=localhost:8080
-
-msg_get() {
-  curl "http://$HOST/api/v2/$*"
-  echo
-}
-
-msg_post_file() {
-  curl --data-binary "@$1" "http://$HOST/api/v2/$2"
-  echo
-}
-
-if [ ! -e "collected.zip" ]; then
-  echo Need a collectd.zip to run. Either use the one from the test directory or generate a new file.
-  exit 1
-fi
-
-msg_get cmd/startSession
-msg_post_file collected.zip session/latest/import/collectd
-msg_get session/latest/sync/`date +%s%N`
-msg_get session/latest/close
-msg_get session/latest/store
diff --git a/stuff/api-examples/test-sut-old.sh b/stuff/api-examples/test-sut-old.sh
index d9e1fa4..e1079ff 100755
--- a/stuff/api-examples/test-sut-old.sh
+++ b/stuff/api-examples/test-sut-old.sh
@@ -3,25 +3,26 @@
 # API v1 (PowerGoblin 1.x aka old version)
 #
 # The script should be run on the same system.
-# Adjust the HOST parameter if necessary
+# Requires 'curl'.
+# Adjust the HOST parameter if necessary.
 
 HOST=localhost:8080
 
-msg_get() {
+pg_get() {
   curl "http://$HOST/$*"
 }
 
-msg_get api/v1/measurement/start/TestScenario1
-msg_get api/v1/meter/rename/SP3-99%20IN/PSU
-msg_get api/v1/measurement/rename/Dummy%20test
-msg_get api/v1/run/start/sut
+pg_get api/v1/measurement/start/TestScenario1
+pg_get api/v1/meter/rename/SP3-99%20IN/PSU
+pg_get api/v1/measurement/rename/Dummy%20test
+pg_get api/v1/run/start/sut
 sleep 1
-msg_get api/v1/run/stop/sut
-msg_get api/v1/run/start/sut
+pg_get api/v1/run/stop/sut
+pg_get api/v1/run/start/sut
 sleep 1
-msg_get api/v1/run/stop/sut
+pg_get api/v1/run/stop/sut
 
 sleep 0.5
-msg_get api/v1/measurement/stop/TestScenario1
-msg_get api/v1/session/close
-msg_get api/v1/session/store
+pg_get api/v1/measurement/stop/TestScenario1
+pg_get api/v1/session/close
+pg_get api/v1/session/store
diff --git a/stuff/api-examples/test-sut.sh b/stuff/api-examples/test-sut.sh
index b78deac..6443563 100755
--- a/stuff/api-examples/test-sut.sh
+++ b/stuff/api-examples/test-sut.sh
@@ -1,30 +1,33 @@
 #!/bin/sh
-# simple script for testing the functionality of the built-in HTTP server
-# API v2
+# A simple script for testing the functionality of the built-in HTTP server
 #
 # The script should be run on the same system.
-# Adjust the HOST parameter if necessary
+# Requires 'curl'.
+# Adjust the HOST parameter if necessary.
 
 HOST=localhost:8080
 
-msg_get() {
+pg_get() {
   curl "http://$HOST/api/v2/$*"
 }
 
-msg_get cmd/startSession
-msg_get session/latest/rename/CLI%20tool%20measurements
-msg_get session/latest/meter/SP3-fc/rename/out1/PSU
-msg_get session/latest/measurement/start
-msg_get session/latest/measurement/rename/Sleep
+pg_post_file() {
+  curl --data-binary "@$2" "http://$HOST/api/v2/$1"
+}
+
+pg_get cmd/startSession
+pg_post_file session/latest/import/template README.md
+pg_get session/latest/measurement/start
+pg_get session/latest/measurement/rename/Sleep
 
 for i in $(seq 10); do
-  msg_get session/latest/run/start
+  pg_get session/latest/run/start
   sleep 1.5
-  msg_get session/latest/run/stop
+  pg_get session/latest/run/stop
 done
 
 sleep 0.5
 
-msg_get session/latest/measurement/stop
-msg_get session/latest/close
-msg_get session/latest/store
+pg_get session/latest/measurement/stop
+pg_get session/latest/close
+pg_get session/latest/store
diff --git a/stuff/api-examples/test.py b/stuff/api-examples/test.py
deleted file mode 100644
index 94c4277..0000000
--- a/stuff/api-examples/test.py
+++ /dev/null
@@ -1,39 +0,0 @@
-
-import requests                                                                                                                             
-import json                                                                                                                             
-
-class GoblinClient:
-  def __init__(self, host):
-    self.host = host
-    
-  def get(self, url):                                                                                                                        
-    return requests.get(self.host + "/" + url)                                                                                                   
-                                                                                                                                             
-  def post_json(self, url, json):                                                                                                                       
-    return requests.post(self.host + "/" + url, json = json)    
-                                                                           
-  def post_text(self, url, text):                                                                                                                       
-    return requests.post(self.host + "/" + url, data = text, headers={'Content-Type': 'text/plain'})
-
-  def post_file(self, url, file):
-    with open(file, 'rb') as payload:
-      headers = {'content-type': 'application/x-zip'}
-      return requests.post(self.host + "/" + url, data=payload, verify=False, headers=headers)
-
-  def interpret(self, result):
-    return json.loads(result.content)["result"]
-
-# --- Examples ---
-
-c = GoblinClient("http://localhost:8080")
-# GET example
-#meters = c.get("api/v1/session/meters")
-#print(c.interpret(meters))
-
-# POST examples
-#data = { "triggerType" : "Run", "unit" : "SUT", "message": "Starting", "type": "trigger" }
-#c.post_json("api/v1/trigger", json = data)
-
-#c.post_text("api/v1/session/rename", text = "foobar")
-
-c.post_file("api/v1/import/collectd", "collectd2.zip")
diff --git a/stuff/client-library/README b/stuff/client-library/README.md
similarity index 67%
rename from stuff/client-library/README
rename to stuff/client-library/README.md
index e724937..2f428c5 100644
--- a/stuff/client-library/README
+++ b/stuff/client-library/README.md
@@ -1,7 +1,25 @@
+---
+name: Client library example
+author: Captain Planet
+---
+
 This folder contains client side library scripts for interfacing
 with PowerGoblin, written in Bash and Python, and also examples of
 their use.
 
+Library scripts:
+
+- `intel-rapl.py`
+- `powergoblin.py`
+- `powergoblin.sh`
+- `seleniumdriver.py`
+
+Usage examples:
+
+- `test.py`
+- `test.sh`
+- `test-selenium.py`
+
 On Arch Linux, the following (AUR) packages need to be
 installed to run the Selenium measurement:
 
diff --git a/stuff/client-library/powergoblin.py b/stuff/client-library/powergoblin.py
index 5952894..5176c20 100755
--- a/stuff/client-library/powergoblin.py
+++ b/stuff/client-library/powergoblin.py
@@ -50,16 +50,13 @@ class PowerGoblin:
     return str(round(time.time() * 1000))
 
 class Collectd:
-  def __init__(self, target = "/tmp/collectd/", interval = "0.1", rapl = False):
+  def __init__(self, target = "/tmp/collectd/", interval = "0.1", rapl = False, nvml = False):
     self.conf_file = "collectd.conf"
-    if rapl:
-      with open(self.conf_file, "w") as f:
-        f.write(f"""
+    base = f"""
 Interval ${interval}
 
 LoadPlugin cpu
 LoadPlugin csv
-LoadPlugin python
 LoadPlugin interface
 LoadPlugin load
 LoadPlugin memory
@@ -68,29 +65,26 @@ LoadPlugin memory
   DataDir "{target}"
   StoreRates false
 </Plugin>
+"""
+    raplCode = f"""
+LoadPlugin python
 
 <Plugin python>
 ModulePath "."
 LogTraces true
 Import "intel_rapl"
 </Plugin>
-""")
-    else:
-      with open(self.conf_file, "w") as f:
-        f.write(f"""
-Interval ${interval}
-
-LoadPlugin cpu
-LoadPlugin csv
-LoadPlugin interface
-LoadPlugin load
-LoadPlugin memory
+"""
+    nvmlCode = f"""
+LoadPlugin gpu_nvidia
+"""
+    if rapl:
+      base = base + raplCode
+    if nvml:
+      base = base + nvmlCode
 
-<Plugin csv>
-  DataDir "{target}"
-  StoreRates false
-</Plugin>
-""")
+    with open(self.conf_file, "w") as f:
+      f.write(base)
     self.process = subprocess.Popen(["/usr/sbin/collectd", "-fC", self.conf_file])
     self.target = target
 
diff --git a/stuff/client-library/powergoblin.sh b/stuff/client-library/powergoblin.sh
index aba04f5..10611dd 100755
--- a/stuff/client-library/powergoblin.sh
+++ b/stuff/client-library/powergoblin.sh
@@ -15,6 +15,7 @@
 #
 # export COLLECTD_INTERVAL=0.1
 # export COLLECTD_RAPL=N
+# export COLLECTD_NVML=N
 # collectd_start /tmp/collectd
 # collectd_stop
 # pg_post_file session/latest/import/collectd "$(collectd_dump)"
@@ -75,6 +76,7 @@ COLLECTD_CONFIGURATION=collectd.conf
 COLLECTD_TARGET=collected.zip
 COLLECTD_DATA=/tmp/collectd
 COLLECTD_RAPL=N
+COLLECTD_NVML=N
 
 collectd_start() {
   if [ "$1" != "" ]; then
@@ -102,13 +104,11 @@ collectd_start() {
 
   mkdir -p "${COLLECTD_DATA}"
 
-  if [ "${COLLECTD_RAPL}" == Y ]; then
-    cat << EOF > "$CONF"
+  cat << EOF > "$CONF"
 Interval ${COLLECTD_INTERVAL}
 
 LoadPlugin cpu
 LoadPlugin csv
-LoadPlugin python
 LoadPlugin interface
 LoadPlugin load
 LoadPlugin memory
@@ -118,26 +118,23 @@ LoadPlugin memory
   StoreRates false
 </Plugin>
 
+EOF
+  if [ "${COLLECTD_RAPL}" == Y ]; then
+    cat << EOF >> "$CONF"
+LoadPlugin python
+
 <Plugin python>
 ModulePath "."
 LogTraces true
 Import "intel_rapl"
 </Plugin>
-EOF
-  else
-    cat << EOF > "$CONF"
-Interval ${COLLECTD_INTERVAL}
 
-LoadPlugin cpu
-LoadPlugin csv
-LoadPlugin interface
-LoadPlugin load
-LoadPlugin memory
+EOF
+  fi
+  if [ "${COLLECTD_NVML}" == Y ]; then
+    cat << EOF >> "$CONF"
+LoadPlugin gpu_nvidia
 
-<Plugin csv>
-  DataDir "${COLLECTD_DATA}"
-  StoreRates false
-</Plugin>
 EOF
   fi
 
diff --git a/stuff/client-library/seleniumdriver.py b/stuff/client-library/seleniumdriver.py
index a04bbf1..c9761f2 100755
--- a/stuff/client-library/seleniumdriver.py
+++ b/stuff/client-library/seleniumdriver.py
@@ -35,7 +35,7 @@ class SeleniumDriver:
     pg = self.powergoblin.host
 
     try:
-      return self.driver.execute_script(f"await fetch(\"{pg}/{cmd}\")")
+      return self.driver.execute_script(f"await fetch(\"{pg}{cmd}\")")
     except JavascriptException as err:
       print(err)
       return None
diff --git a/stuff/client-library/test.py b/stuff/client-library/test.py
index a7513f3..fd53f77 100755
--- a/stuff/client-library/test.py
+++ b/stuff/client-library/test.py
@@ -6,7 +6,7 @@ import time
 pg = PowerGoblin("localhost:8080")
 
 pg.get("cmd/startSession")
-pg.get("session/latest/rename/CLI%20tool%20measurements")
+pg.post_file("session/latest/import/template", "README.md")
 
 cd = Collectd(target = "/tmp/collectd/", rapl = False)
 
diff --git a/stuff/client-library/test.sh b/stuff/client-library/test.sh
index 51a3aac..e7a60e9 100755
--- a/stuff/client-library/test.sh
+++ b/stuff/client-library/test.sh
@@ -7,7 +7,7 @@ export HOST=localhost:8080
 export HTTPCLIENT=curl
 
 pg_get cmd/startSession
-pg_get session/latest/rename/CLI%20tool%20measurements
+pg_post_file session/latest/import/template README.md
 
 export COLLECTD_RAPL=N
 
diff --git a/stuff/collectd-example/README.md b/stuff/collectd-example/README.md
index 96c80b2..9c83687 100644
--- a/stuff/collectd-example/README.md
+++ b/stuff/collectd-example/README.md
@@ -13,6 +13,20 @@ communicating with PowerGoblin. It is assumed that PowerGoblin also runs
 on the same system. In practice, it would be better to run it on a separate
 system.
 
+Preparations (background shell):
+
+```shell
+$ wget https://tech.utugit.fi/soft/tools/power/powergoblin/powergoblin.jar
+$ java -jar powergoblin.jar
+```
+
+Usage:
+
+```shell
+$ cp ../client-library/powergoblin.sh .
+$ ./collect.sh
+```
+
 You will need to customize the script to suit your needs. In the beginning of
 the file, there are parameters for configuring names, number of runs, and
 other settings. The actual code that will be measured is located on lines 28
diff --git a/stuff/collectd-nvml/README.md b/stuff/collectd-nvml/README.md
new file mode 100644
index 0000000..deb451a
--- /dev/null
+++ b/stuff/collectd-nvml/README.md
@@ -0,0 +1,36 @@
+---
+name: System utility benchmarks with NVML
+author: Captain Planet
+---
+
+The purpose of this example is to demonstrate how to measure the
+resource consumption of a GPU provided by the CUDA and Nvidia
+drivers.
+
+The script assumes that `collectd` and `cuda` have been installed.
+The client library (see `client-library/powergoblin.sh`) is used for
+communicating with PowerGoblin. It is assumed that PowerGoblin also runs
+on the same system. In practice, it would be better to run it on a separate
+system.
+
+The script also makes use of NVML counters for energy measurements.
+
+Preparations (background shell):
+
+```shell
+$ wget https://tech.utugit.fi/soft/tools/power/powergoblin/powergoblin.jar
+$ java -jar powergoblin.jar
+```
+
+Usage:
+
+```shell
+$ cp ../client-library/powergoblin.sh .
+$ ./collect.sh
+```
+
+You will need to customize the script to suit your needs. In the beginning of
+the file, there are parameters for configuring names, number of runs, and
+other settings. The actual code that will be measured is located on lines 29
+and 47.
+
diff --git a/stuff/collectd-nvml/collect.sh b/stuff/collectd-nvml/collect.sh
new file mode 100755
index 0000000..40cf6de
--- /dev/null
+++ b/stuff/collectd-nvml/collect.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+# You can use this as a template for your measurements.
+# This depends on the `powergoblin.sh` in `client-library/`
+
+source powergoblin.sh
+
+export HOST=localhost:8080
+export MEASUREMENT1="Sleep 1000ms"
+export MEASUREMENT2="Sleep 2000ms"
+export RUNS=5
+export HTTPCLIENT=curl
+export COLLECTD_NVML=Y
+
+pg_get cmd/startSession
+pg_post_file session/latest/import/template README.md
+pg_get session/latest/resource/fanspeed,frequency,percent,power/include
+
+collectd_start /tmp/collectd
+
+# ---
+
+pg_get session/latest/measurement/start
+pg_get session/latest/measurement/rename/${MEASUREMENT1}
+
+for i in $(seq $RUNS); do
+  echo "Run $i"
+  pg_get session/latest/run/start
+
+  sleep 1
+
+  pg_get session/latest/run/stop
+done
+
+pg_get session/latest/measurement/stop
+
+sleep 0.5
+
+# ---
+
+pg_get session/latest/measurement/start
+pg_get session/latest/measurement/rename/${MEASUREMENT2}
+
+for i in $(seq $RUNS); do
+  echo "Run $i"
+  pg_get session/latest/run/start
+
+  sleep 2
+
+  pg_get session/latest/run/stop
+done
+
+pg_get session/latest/measurement/stop
+
+sleep 0.5
+
+# ---
+
+collectd_stop
+
+date +%s%N | pg_post session/latest/sync
+pg_post_file session/latest/import/collectd "$(collectd_dump)"
+
+pg_get session/latest/close
+pg_get session/latest/remove
diff --git a/stuff/collectd-rapl/README.md b/stuff/collectd-rapl/README.md
index 8e80c53..edd669f 100644
--- a/stuff/collectd-rapl/README.md
+++ b/stuff/collectd-rapl/README.md
@@ -14,14 +14,25 @@ on the same system. In practice, it would be better to run it on a separate
 system.
 
 The script also makes use of RAPL counters for energy measurements.
-You may need to change the permissions of counter variables:
+You may need to change the permissions of counter variables.
+
+Preparations (background shell):
 
 ```shell
+$ wget https://tech.utugit.fi/soft/tools/power/powergoblin/powergoblin.jar
+$ java -jar powergoblin.jar
 # chown -R $USER /sys/devices/virtual/powercap/intel-rapl
 ```
 
+Usage:
+
+```shell
+$ cp ../client-library/powergoblin.sh .
+$ ./collect.sh
+```
+
 You will need to customize the script to suit your needs. In the beginning of
 the file, there are parameters for configuring names, number of runs, and
-other settings. The actual code that will be measured is located on lines 28
-and 46.
+other settings. The actual code that will be measured is located on lines 29
+and 47.
 
diff --git a/stuff/collectd-rapl/collect.sh b/stuff/collectd-rapl/collect.sh
index b195789..5a0aae5 100755
--- a/stuff/collectd-rapl/collect.sh
+++ b/stuff/collectd-rapl/collect.sh
@@ -13,6 +13,7 @@ export COLLECTD_RAPL=Y
 
 pg_get cmd/startSession
 pg_post_file session/latest/import/template README.md
+pg_get session/latest/resource/counter/include
 
 collectd_start /tmp/collectd
 
diff --git a/stuff/docker/.gitlab-ci.yml b/stuff/docker-example/.gitlab-ci.yml
similarity index 100%
rename from stuff/docker/.gitlab-ci.yml
rename to stuff/docker-example/.gitlab-ci.yml
diff --git a/stuff/docker/Dockerfile b/stuff/docker-example/Dockerfile
similarity index 100%
rename from stuff/docker/Dockerfile
rename to stuff/docker-example/Dockerfile
diff --git a/stuff/docker/README.md b/stuff/docker-example/README.md
similarity index 81%
rename from stuff/docker/README.md
rename to stuff/docker-example/README.md
index 8b2572c..0ef2986 100644
--- a/stuff/docker/README.md
+++ b/stuff/docker-example/README.md
@@ -6,6 +6,13 @@ author: Captain Planet
 The purpose of this example is to demonstrate how to perform
 energy measurements of a system packaged as a Docker container.
 
+Preparations (background shell):
+
+```shell
+$ wget https://tech.utugit.fi/soft/tools/power/powergoblin/powergoblin.jar
+$ java -jar powergoblin.jar
+```
+
 Usage:
 
 ```shell
diff --git a/stuff/docker-example/original.py b/stuff/docker-example/original.py
new file mode 100644
index 0000000..0a8e5ff
--- /dev/null
+++ b/stuff/docker-example/original.py
@@ -0,0 +1,35 @@
+# Sample: Generates lists of random numbers and sorts them
+
+import time
+import random
+
+def milli_time():
+    return round(time.time() * 1000)
+
+def gen(n):
+    return [random.randint(1, 1000) for _ in range(n)]
+
+def sort(arr):
+    if len(arr) <= 1:
+        return arr
+    pivot = arr[len(arr) // 2]
+    left = [x for x in arr if x < pivot]
+    middle = [x for x in arr if x == pivot]
+    right = [x for x in arr if x > pivot]
+    return sort(left) + middle + sort(right)
+
+def do_computation():
+    start = milli_time()
+    msg = time.ctime()
+    print("Computing..", flush = True)
+    while milli_time() < start + 2000:
+      n = 100000
+      nums = gen(n)
+      sort(nums)
+      msg2 = time.ctime()
+      if msg != msg2:
+          print(msg2, flush = True)
+          msg = msg2
+    print("Done", flush = True)
+
+do_computation()
diff --git a/stuff/docker/powergoblin.py b/stuff/docker-example/powergoblin.py
similarity index 85%
rename from stuff/docker/powergoblin.py
rename to stuff/docker-example/powergoblin.py
index 5952894..5176c20 100755
--- a/stuff/docker/powergoblin.py
+++ b/stuff/docker-example/powergoblin.py
@@ -50,16 +50,13 @@ class PowerGoblin:
     return str(round(time.time() * 1000))
 
 class Collectd:
-  def __init__(self, target = "/tmp/collectd/", interval = "0.1", rapl = False):
+  def __init__(self, target = "/tmp/collectd/", interval = "0.1", rapl = False, nvml = False):
     self.conf_file = "collectd.conf"
-    if rapl:
-      with open(self.conf_file, "w") as f:
-        f.write(f"""
+    base = f"""
 Interval ${interval}
 
 LoadPlugin cpu
 LoadPlugin csv
-LoadPlugin python
 LoadPlugin interface
 LoadPlugin load
 LoadPlugin memory
@@ -68,29 +65,26 @@ LoadPlugin memory
   DataDir "{target}"
   StoreRates false
 </Plugin>
+"""
+    raplCode = f"""
+LoadPlugin python
 
 <Plugin python>
 ModulePath "."
 LogTraces true
 Import "intel_rapl"
 </Plugin>
-""")
-    else:
-      with open(self.conf_file, "w") as f:
-        f.write(f"""
-Interval ${interval}
-
-LoadPlugin cpu
-LoadPlugin csv
-LoadPlugin interface
-LoadPlugin load
-LoadPlugin memory
+"""
+    nvmlCode = f"""
+LoadPlugin gpu_nvidia
+"""
+    if rapl:
+      base = base + raplCode
+    if nvml:
+      base = base + nvmlCode
 
-<Plugin csv>
-  DataDir "{target}"
-  StoreRates false
-</Plugin>
-""")
+    with open(self.conf_file, "w") as f:
+      f.write(base)
     self.process = subprocess.Popen(["/usr/sbin/collectd", "-fC", self.conf_file])
     self.target = target
 
diff --git a/stuff/docker/simulation.py b/stuff/docker-example/simulation.py
similarity index 85%
rename from stuff/docker/simulation.py
rename to stuff/docker-example/simulation.py
index 551d384..d55d470 100644
--- a/stuff/docker/simulation.py
+++ b/stuff/docker-example/simulation.py
@@ -7,12 +7,13 @@ import random
 import os
 from powergoblin import PowerGoblin, Collectd
 
-runs=4
-
 # - - -
 
+def milli_time():
+    return round(time.time() * 1000)
+
 def gen(n):
-    return [random.randint(1, 1000000) for _ in range(n)]
+    return [random.randint(1, 1000) for _ in range(n)]
 
 def sort(arr):
     if len(arr) <= 1:
@@ -39,15 +40,16 @@ def do_computation():
 
 # - - -
 
+runs = 4
 host = os.environ['HOST']
-pg = PowerGoblin("localhost:8080")
+pg = PowerGoblin(host)
 
 pg.get("cmd/startSession")
 pg.post_file("session/latest/import/template", "README.md")
 
-cd = Collectd(target = "/tmp/collectd/", rapl = False)
+cd = Collectd()
 
-pg.get("session/latest/measurement/start/Scenario1")
+pg.get("session/latest/measurement/start/RandomNumbers")
 
 for run in range(runs):
     pg.get("session/latest/run/start")
diff --git a/stuff/report-example/README.md b/stuff/report-example/README.md
index 811d2ee..fb6e998 100644
--- a/stuff/report-example/README.md
+++ b/stuff/report-example/README.md
@@ -3,18 +3,33 @@ author: Captain Planet
 name: Dummy Example
 ---
 
-This example demonstrates the use of report templates.
+This example demonstrates the use of report templates by creating a dummy
+PowerGoblin measurement session. This document will be used as the
+document template for the project 
 
-Nothing really special here.
+The front matter of the markdown file contains special fields for session 
+metadata. The `name` is the name of the session and `author` is the author
+of the session. This text here is the `description`. It's first parsed
+as markdown, then rendered as HTML. HTML code can also be passed through 
+to the final report. There are some limitations, e.g. linked images will
+not be automatically embedded like the built-in ones.
 
-The front matter of the markdown file contains special
-fields for session metadata. The 'name' is the name of
-the session and 'author' is the author of the session.
-This text here is the 'description'. It's first parsed
-as markdown, then rendered as HTML. HTML code can also
-be passed through to the final report. There are some
-limitations, e.g. linked images will not be automatically
-embedded like the built-in ones.
+The script depends on the `powergoblin.sh` defined in
+`../client-library/`.
+
+Preparations (background shell):
+
+```shell
+$ wget https://tech.utugit.fi/soft/tools/power/powergoblin/powergoblin.jar
+$ java -jar powergoblin.jar
+```
+
+Usage:
+
+```shell
+$ cp ../client-library/powergoblin.sh .
+$ ./test-report.sh
+```
 
 ## Tests
 
@@ -41,10 +56,3 @@ Example list
 
 **This is bold**, *this is written in italics*.
 ~~This has strike through~~.
-
-How to run:
-
-```
-$ java -jar powergoblin.jar
-$ curl --data-binary @report.md http://localhost:8080/api/v2/session/latest/import/template
-```
diff --git a/stuff/report-example/test-report.sh b/stuff/report-example/test-report.sh
new file mode 100755
index 0000000..657b77f
--- /dev/null
+++ b/stuff/report-example/test-report.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# The script should be run on the same system.
+# Adjust the HOST parameter if necessary
+
+source powergoblin.sh
+
+export HOST=localhost:8080
+
+pg_get cmd/startSession
+
+pg_post_file session/latest/import/template README.md
+
+pg_get session/latest/measurement/start
+pg_get session/latest/measurement/rename/Sleep
+
+for i in $(seq 10); do
+  pg_get session/latest/run/start
+  sleep 0.1
+  pg_get session/latest/run/stop
+done
+
+sleep 0.1
+pg_get session/latest/measurement/stop
+
+pg_get session/latest/close
diff --git a/stuff/report-example/test-sut.sh b/stuff/report-example/test-sut.sh
deleted file mode 100755
index 89b12bc..0000000
--- a/stuff/report-example/test-sut.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-# simple script for testing the functionality of the built-in HTTP server
-# API v2
-#
-# The script should be run on the same system.
-# Adjust the HOST parameter if necessary
-
-HOST=localhost:8080
-
-msg_get() {
-  curl "http://$HOST/api/v2/$*"
-  echo
-}
-
-msg_post_file() {
-  curl --data-binary "@$1" "http://$HOST/api/v2/$2"
-  echo
-}
-
-msg_get cmd/startSession
-
-msg_post_file README.md session/latest/import/template
-
-msg_get session/latest/measurement/start
-msg_get session/latest/measurement/rename/Sleep
-
-for i in $(seq 10); do
-  msg_get session/latest/run/start
-  sleep 0.1
-  msg_get session/latest/run/stop
-done
-
-sleep 0.1
-msg_get session/latest/measurement/stop
-
-msg_get session/latest/close
diff --git a/stuff/rpi-dietpi/README.md b/stuff/rpi-dietpi/README.md
new file mode 100644
index 0000000..dbbd0a8
--- /dev/null
+++ b/stuff/rpi-dietpi/README.md
@@ -0,0 +1,2 @@
+The process of using this script is described in
+https://tech.utugit.fi/soft/tools/power/doc/manual/installation/download/#raspberry-pi
\ No newline at end of file
diff --git a/stuff/rpi-dietpi/rpi.sh b/stuff/rpi-dietpi/rpi.sh
index 97640f5..9e6741a 100755
--- a/stuff/rpi-dietpi/rpi.sh
+++ b/stuff/rpi-dietpi/rpi.sh
@@ -27,7 +27,7 @@ Type=simple
 Restart=always
 RestartSec=1
 User=root
-ExecStart=/usr/bin/java -jar /usr/local/bin/powergoblin.jar --headless
+ExecStart=/usr/bin/java -jar /root/powergoblin.jar --headless
 
 [Install]
 WantedBy=multi-user.target
-- 
GitLab