--- /dev/null
+#!/usr/bin/env python3
+# Copyright (C) 2025 Bdale Garbee <bdale@gag.com>. GPLv3+
+
+import gpiod
+import iio
+import signal
+import sys
+import time
+import os
+import cherrypy
+import plotly.express as px
+
+ctx = iio.LocalContext()
+ctrl = ctx.find_device('ads8688')
+
+# configuration for each channel on ADS8688
+OFFSET = "0"
+SCALE = "0.078127104"
+VOLTAGES = ['voltage0', 'voltage1', 'voltage2', 'voltage3', 'voltage4', 'voltage5', 'voltage6', 'voltage7']
+
+from gpiod.line import Direction, Value
+
+def set_line_values(chip_path, line_values):
+ value_str = {Value.ACTIVE: "Active", Value.INACTIVE: "Inactive"}
+
+ request = gpiod.request_lines(
+ chip_path,
+ consumer=sys.argv[0],
+ config={
+ tuple(line_values.keys()): gpiod.LineSettings(direction=Direction.OUTPUT)
+ },
+ )
+ request.set_values(line_values)
+
+if __name__ == "__main__":
+ try:
+ # initialize hardware
+ set_line_values(
+ "/dev/gpiochip0",
+ {25: Value.ACTIVE, # take ADS8688 out of reset
+ 4: Value.ACTIVE, # indicate 'ready' to LPC
+ 16: Value.INACTIVE, # pyro off
+ 17: Value.INACTIVE, # alarm b off
+ 20: Value.INACTIVE, # turn continuity LED off
+ 21: Value.INACTIVE, # turn armed LED off
+ 27: Value.INACTIVE # alarm a off
+ }
+ )
+
+ # configure ADC channels
+ for id in VOLTAGES:
+ chan = ctrl.find_channel(id)
+ # must set scale before offset, so offset 0 is valid!
+ chan.attrs['scale'].value = SCALE
+ chan.attrs['offset'].value = OFFSET
+
+ file_path = os.getcwd()
+
+ class Root(object):
+ @cherrypy.expose
+
+ # define what happens on default (index) page
+ def index(self):
+ cherrypy.log("index")
+
+ # some sort of demo data
+ df = px.data.gapminder().query("country=='Canada'")
+
+ # constrain height to 600 to avoid having to scroll for other info?
+ fig = px.line(df, x="year", y="lifeExp", \
+ title='Life expectancy in Canada', height=600)
+
+ # fig.to_html gives us the entire interactive graph as a python string!
+ plotly_data = fig.to_html(full_html=False)
+
+ # for now, just concatenate a header and a footer
+ html_data = '<html> <body> <h1>QuantiMotor</h1>' + \
+ plotly_data + \
+ "<h2>Thats all folks!</h2></body> </html>"
+
+ # give the complete html to the client
+ return html_data
+
+ cherrypy.quickstart(Root(), '/')
+
+
+ except OSError as ex:
+ print(ex, "\nD'oh!")
+