Skip to content

Commit

Permalink
New Release (#27)
Browse files Browse the repository at this point in the history
* added new average calculation for the values

* add everage

* changed formular

* updaed

* fixed spelling and some other errors

* added todo

* Switched to poetry and venv

* some linting

* added pre-commit

* reformatted with black

* change code from index to new file

* added the config menue / modal

* added vscode

* mocked spidev in dev mode

* fixed some spelling ??

* Added blinking

* updated blinking to invisable

* added comment

* deleted unused png

* added legend bottom right

* run pre-commit on all files

* change to config instead of global variables

* changed the AFR calculation

* added error check

* added pyinstaller

* fixed exception if ENV not set

* fixed know issue in package eventlet/eventlet#702

* fixed exception if ENV not set

* changed config and can change correction from web interface

* added devcontainer

* some code fixes (#7)

* nachkomastellen default zu 2 (#8)

* Set blinking and removed error warning (#10)

* blinking is in settings

* removed error checking

* #9 save all setting (#13)

* all settings getting saved

* switched to dynamic attributes in config

* use of url_for

* setup the default values and the persistent saving in the backend

* updated black

* added example settings and use this if not prod

* removed unused settings

* update README für neue Settings

* removed unused import

* added jinja extension

* #12 exceptions anzeigen (#14)

* renamend .html to .jinja

* renamend THREAD to UPDATE_DATA_THREAD and initialize it with None

* Exceptions werden nun angezeigt

* #16 New temperaturanzeige (#23)

* Basisklasse für GPIO erstellt und LambdaSensor daraus abgeleitet

* Added typ_k_tempreatursensor and apply snake_case to lambda_sensor

* submit temperaturdata to webpage

* splittet lamda functions and placed channels to config file

* added new config in exaple file

create base template. Working

moved javascript around

switched back to index.jinja

* lambda und temp werden nun von anfang an auf 50% im index angezeigt

* Tempreaturanzeige wird nun syncronisiert vom Back to Frontend

* alphabetic order

* alle Anzeigen können nun individuell angezeigt werden und in conf eingestellt

* apply orange and red colors

* Temp min max verlauf (#24)

* tmp_commit added charts rev

* added diagramm with test data

* added sqlite db and tempdata routes

* implemented firs working chart for temperatur

* Create own page for history

* switched to date and time imstead of datetime-local

* add nav and hisotry generator tool

* added bg color for chart

* added second timestamp for temprature

* added lambda values for charts

* removed influxdb

* generate better example values

* added timezone to db timestamps

* fixed labes for data

* fixed some type errors

* swtiched to own CSS layout

* changed the main Layout to own CSS

* tracking the sensor lifetime and show warnings (#25)

* added overheating (#26)

* updated readme

* update python version to 3.7.*
  • Loading branch information
Floskinner committed Jan 3, 2024
1 parent 3bb6877 commit 1884de6
Show file tree
Hide file tree
Showing 39 changed files with 2,698 additions and 1,413 deletions.
59 changes: 35 additions & 24 deletions .devcontainer/devcontainer.json
@@ -1,30 +1,41 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/python
{
"image": "python:3.7.3",
"forwardPorts": [8080],
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"njpwerner.autodocstring",
"naumovs.color-highlight",
"GitHub.copilot",
"donjayamanne.githistory",
"mhutchie.git-graph",
"oderwat.indent-rainbow",
"ms-python.vscode-pylance",
"Gruntfuggly.todo-tree",
"yzhang.markdown-all-in-one"
]
}
},
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/python:3.7",
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers-contrib/features/poetry:1": {}
"ghcr.io/devcontainers-contrib/features/poetry:2.0.17": {}
},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [8080],

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "poetry config virtualenvs.in-project true && poetry install",

// Configure tool-specific properties.
"customizations": {
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"njpwerner.autodocstring",
"naumovs.color-highlight",
"GitHub.copilot",
"donjayamanne.githistory",
"mhutchie.git-graph",
"oderwat.indent-rainbow",
"ms-python.vscode-pylance",
"Gruntfuggly.todo-tree",
"yzhang.markdown-all-in-one",
"samuelcolvin.jinjahtml"
]
}
},

"remoteEnv": {
"FLASK_ENV": "development"
},
"postCreateCommand": "poetry config virtualenvs.in-project true && poetry install"
}
}
}
31 changes: 31 additions & 0 deletions .devcontainer/devcontainer.json.bak
@@ -0,0 +1,31 @@
{
"image": "python:3.7.3",
"forwardPorts": [8080],
"customizations": {
// Configure properties specific to VS Code.
"vscode": {
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"njpwerner.autodocstring",
"naumovs.color-highlight",
"GitHub.copilot",
"donjayamanne.githistory",
"mhutchie.git-graph",
"oderwat.indent-rainbow",
"ms-python.vscode-pylance",
"Gruntfuggly.todo-tree",
"yzhang.markdown-all-in-one",
"samuelcolvin.jinjahtml"
]
}
},
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers-contrib/features/poetry:1": {}
},
"remoteEnv": {
"FLASK_ENV": "development"
},
"postCreateCommand": "poetry config virtualenvs.in-project true && poetry install"
}
5 changes: 4 additions & 1 deletion .gitignore
Expand Up @@ -13,4 +13,7 @@ htmlcov/

dist/
build/
*.egg-info/
*.egg-info/

settings.json
MAMA.sqlite
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Expand Up @@ -10,7 +10,7 @@ repos:
types:
- "python"
- repo: https://github.com/psf/black
rev: 19.3b0
rev: 22.3.0
hooks:
- id: black
exclude: |
Expand Down
48 changes: 12 additions & 36 deletions GPIO.py
@@ -1,50 +1,26 @@
import os

from globale_variablen import config
from MCP3008 import MCP3008
from MCP3008 import TestMCP3008


class GPIO_Reader(object):
"""
Klasse womit der Aktuelle Lamdawert am GPIO Einglang ausgelesen werden kann
"""
class GPIO(object):
"""Basis Klasse für die GPIO Schnittstelle"""

def __init__(self):
def __init__(self, *args, **kwargs):
"""Handelt es sich um eine Testumgebung wird ein TestMCP3008 Objekt erstellt, ansonsten ein MCP3008 Objekt"""
if os.environ.get("FLASK_ENV") == "development":
self.adc = TestMCP3008()
print("Create TestMCP3008 Object")
self.adc = TestMCP3008(*args, **kwargs)
else:
self.adc = MCP3008()
self.adc = MCP3008(*args, **kwargs)

def get_voltage(self, channel: int) -> float:
"""Gibt den Spannungswert des angegebenen Kanals zurück
:param channel: Kanalnummer (0-7)
:return: Spannungswert (0-5V)
"""
value = self.adc.read(channel)
voltage = value / 1023.0 * 5.0
return voltage

def get_lamda(self, voltage: float, correction: float) -> float:
lamda = round(0.2 * voltage + correction, 3)
return lamda

def get_afr(self, lamda: float) -> float:
afr = lamda * config.AFR_STOCH
return afr

def getData(self):
voltage_1 = self.get_voltage(0)
voltage_2 = self.get_voltage(1)

lamda_1 = round(self.get_lamda(voltage_1, config.KORREKTURFAKTOR_BANK_1), 3)
lamda_2 = round(self.get_lamda(voltage_2, config.KORREKTURFAKTOR_BANK_2), 3)

afr_1 = self.get_afr(lamda_1)
afr_2 = self.get_afr(lamda_2)

data = {
"lamda1": lamda_1,
"lamda2": lamda_2,
"afr1": afr_1,
"afr2": afr_2,
"volt1": voltage_1,
"volt2": voltage_2,
}
return data
18 changes: 13 additions & 5 deletions MCP3008.py
@@ -1,3 +1,5 @@
import random

from spidev import SpiDev


Expand All @@ -22,15 +24,21 @@ def close(self):


class TestMCP3008:
def __init__(self):
pass
def __init__(self, test_summand: int = 1):
self.current_value = 0
self.summand = test_summand + random.randint(5, 10)

def open(self):
pass

def read(self, channel=0):
# Lamda 1 = 500
return 900
def read(self, _):
if self.current_value > 1023:
self.summand *= -1
elif self.current_value < 0:
self.summand *= -1

self.current_value += self.summand
return self.current_value

def close(self):
pass
55 changes: 24 additions & 31 deletions README.md
Expand Up @@ -15,41 +15,14 @@ Produkte:
Da der Pi W kein Ethernet anschluss besitzt, muss dem Pi zuvor die WLAN Konfiguration übergeben werden -> [Anleitung](https://www.dahlen.org/2017/10/raspberry-pi-zero-w-headless-setup/) <br>
<br>
Folgende Software muss installiert werden:
- Python 3 or newer
- Python 3.7
- pip
- influxDB
- Grafana
- dnsmasq
- hostapd

### WLAN
Damit der Pi sein eigenes WLAN erstellt, kann folgende [Anleitung](https://www.elektronik-kompendium.de/sites/raspberry-pi/2002171.htm) bis einschließlich "WLAN-Interface konfigurieren" befolgt werden.

### Grafana & InfluxDB
Mithilfe dieser [Anleitung](https://simonhearne.com/2020/pi-influx-grafana/) kann Grafana und InfluxDB installiert werden. Für Grafana muss anschließend ein Anonymus Zugang eingerichtet werden, damit man auch ohne Login auf den Grafen dann zugreifen kann [Anonymus Authentication](https://grafana.com/docs/grafana/latest/auth/overview/#anonymous-authentication), [Disable login form](https://grafana.com/docs/grafana/latest/auth/overview/#automatic-oauth-login). <br>
<hr>
Um InfluxDB richtig zu konfigurieren folgendes ausführen (influxdb.ini):

```bash
sudo influx

create database lamdawerte
use lamdawerte

create user grafana with password 'password' with all privileges
create user python with password 'password' with all privileges

grant all privileges on lamdawerte to grafana
grant all privileges on lamdawerte to python

show users

; user admin
; ---- -----
; grafana true
; python true
```

### Python
Python hat eine virtualenv ([Anleitung](https://bodo-schoenfeld.de/eine-virtuelle-umgebung-fuer-python-erstellen/)) in der alle benötigte Module installiert werden. Alle "requirements" stehen in `requirements.txt`. <br>
Diese können alle über folgendem Befehel installiert werden
Expand All @@ -58,15 +31,35 @@ pip install -r requirements.txt
```

### Service
Der Service muss unter `/etc/systemd/system/lamda.service` liegen -> [Anleitung](https://www.raspberrypi.org/documentation/linux/usage/systemd.md). Wichtig hier, dass `Environment="PATH=/home/pi/lamdaProjekt/venv/bin"` dem Pfad entspricht, wo auch die virtualenv ist, damit sichergestellt ist, das auch alle benötigte vorhaben ist.
Der Service muss unter `/etc/systemd/system/lamda.service` liegen -> [Anleitung](https://www.raspberrypi.org/documentation/linux/usage/systemd.md). Wichtig hier, dass `Environment="PATH=/home/pi/lamdaProjekt/venv/bin"` dem Pfad entspricht, wo auch die virtualenv ist, damit sichergestellt ist, das auch alle benötigte Packete vorhanden sind.

### Flask / Gunicorn
Der Webserver wird mithilfe von [Flask](https://flask.palletsprojects.com/en/1.1.x/) erstellt und mit [Gunicorn](https://docs.gunicorn.org/en/stable/run.html) gehosted (Anleitung auch bei Flask-soketIO). Mithilfe von [Flask-soketIO](https://flask.palletsprojects.com/en/1.1.x/api/#blueprint-objects) wird dann ein Socket erstellt, damit die Daten in Echtzeit im Browser erscheinen können. Gunicorn braucht eine `.py`-Datei mit entsprechenden Konfigurationen, die dann beim Service aufruf mit übergebenen werden müssen (`gunicorn.conf.py`)
Der Webserver wird mithilfe von [Flask](https://flask.palletsprojects.com/en/1.1.x/) erstellt und mit [Gunicorn](https://docs.gunicorn.org/en/stable/run.html) gehosted (Anleitung auch bei Flask-soketIO). Mithilfe von [Flask-soketIO](https://flask.palletsprojects.com/en/1.1.x/api/#blueprint-objects) wird dann ein Socket erstellt, damit die Daten in "Echtzeit" im Browser erscheinen können. Gunicorn braucht eine `.py`-Datei mit entsprechenden Konfigurationen, die dann beim Service aufruf mit übergebenen werden müssen (`gunicorn.conf.py`)

### MCP3008
Eine Verwendung für den MCP3008 findet man hier -> [Anleitung](https://tutorials-raspberrypi.de/raspberry-pi-mcp3008-analoge-signale-auslesen/)

## Konfigurationen
Es gibt eine Beispielkonfiguration [`settings_example.json`](settings_example.json). Diese kann als Vorlage verwendet werden und beinhaltet die Initialen ertesteten besten Werte. Wird das ganze Produtktiv verwendet (`FLASK_ENV = "prod"`), so muss eine Datei namens `settings.json` mit den entsprechenden Werten wie in der Beispieldatei vorhanden sein.

```json
{
"AFR_STOCH": 14.68, // Wert zum ausrechnen des AFR = lamda * AFR_STOCH
"KORREKTURFAKTOR_BANK_1": 0.511, // Korrekturfaktor des Lamdawertes Bank 1
"KORREKTURFAKTOR_BANK_2": 0.511, // Korrekturfaktor des Lamdawertes Bank 1
"MESSURE_INTERVAL": 0.01, // Messintervall in Sekunden
"UPDATE_INTERVAL": 1.5, // Updateintervall in Sekunden der Anzeige
"DB_DELETE_AELTER_ALS": 180, // Löschen in Tage der DB Einträge
"ANZEIGEN_BANK_1": true, // Bank 1 wird beim aufruf angezeigt
"ANZEIGEN_BANK_2": true, // Bank 2 wird beim aufruf angezeigt
"NACHKOMMASTELLEN": 2, // Initiale Anzeige der Nachkommastellen
"WARNUNG_BLINKEN": false // Blinken im roten Bereich aktivieren
}
```

---

## Randbemerkungen
- Der Pi wird intern der MAMA direkt mit 5V versorgt
- Die Uhrzeit vom Pi wird mithilfe vom Browser aktuallisiert, jedes mal wenn man die index.html aufruft
- Updates nur mit vorsicht durchführen (never change an running system)
- SQLite wird als Datenbank verwendet

0 comments on commit 1884de6

Please sign in to comment.