From: Bdale Garbee Date: Sat, 5 Apr 2025 05:08:54 +0000 (-0600) Subject: add an initial cherrypy + plotly application fragment X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=25b576703302aa1917032f6f540bab10a07ced5e;p=fw%2Fquantimotor add an initial cherrypy + plotly application fragment --- diff --git a/application.py b/application.py new file mode 100755 index 0000000..270ae11 --- /dev/null +++ b/application.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +# Copyright (C) 2025 Bdale Garbee . 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 = '

QuantiMotor

' + \ + plotly_data + \ + "

Thats all folks!

" + + # give the complete html to the client + return html_data + + cherrypy.quickstart(Root(), '/') + + + except OSError as ex: + print(ex, "\nD'oh!") + diff --git a/debian/control b/debian/control index 51ba1b9..555f21a 100644 --- a/debian/control +++ b/debian/control @@ -16,8 +16,10 @@ Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, + python3-cherrypy3, python3-libgpiod, python3-libiio, + python3-plotly, Description: Software for Altus Metrum QuantiMotor Operational software for the QuantiMotor rocket motor performance testing product family from Altus Metrum. diff --git a/debian/quantimotor.install b/debian/quantimotor.install index cc50a74..3836ff4 100644 --- a/debian/quantimotor.install +++ b/debian/quantimotor.install @@ -1,3 +1,4 @@ +application.py usr/share/quantimotor bcm2837-rpi-zero-2-w.dtb usr/share/quantimotor enable_ads.py usr/share/quantimotor quantimotor.conf etc/modules-load.d diff --git a/startup b/startup index 9d783b5..d9b6b17 100755 --- a/startup +++ b/startup @@ -18,3 +18,5 @@ echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage7_en echo 1 > /sys/bus/iio/devices/iio\:device0/buffer/enable echo "quantimotor startup script ran" > /tmp/status + +/usr/share/quantimotor/application.py