diff --git a/enervent-ctrl-python/.gitignore b/enervent-ctrl-python/.gitignore
deleted file mode 100644
index 9e4c91c..0000000
--- a/enervent-ctrl-python/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-*/__pycache__/
-bin/
-include/
-lib/
-lib64
-share/
diff --git a/enervent-ctrl-python/html/coils/index.html b/enervent-ctrl-python/html/coils/index.html
deleted file mode 120000
index 79c5d6f..0000000
--- a/enervent-ctrl-python/html/coils/index.html
+++ /dev/null
@@ -1 +0,0 @@
-../index.html
\ No newline at end of file
diff --git a/enervent-ctrl-python/html/index.html b/enervent-ctrl-python/html/index.html
deleted file mode 100644
index eeb0a81..0000000
--- a/enervent-ctrl-python/html/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
- Enervent Pingvin Kotilämpö
-
-
-
- Coil values at
- Address | Value | Symbol | Description |
-
-
-
-
\ No newline at end of file
diff --git a/enervent-ctrl-python/html/registers/index.html b/enervent-ctrl-python/html/registers/index.html
deleted file mode 120000
index 79c5d6f..0000000
--- a/enervent-ctrl-python/html/registers/index.html
+++ /dev/null
@@ -1 +0,0 @@
-../index.html
\ No newline at end of file
diff --git a/enervent-ctrl-python/html/static/tabledata.css b/enervent-ctrl-python/html/static/tabledata.css
deleted file mode 100644
index 3f7a99f..0000000
--- a/enervent-ctrl-python/html/static/tabledata.css
+++ /dev/null
@@ -1,17 +0,0 @@
-.addr {
- text-align: center;
-}
-.val {
- text-align: center;
-}
-#data {
- padding: 2pt;
- border-collapse: collapse;
-}
-thead {
- border-bottom: 1px solid;
- text-align: left;
-}
-td {
- padding: 2pt;
-}
\ No newline at end of file
diff --git a/enervent-ctrl-python/html/static/tabledata.js b/enervent-ctrl-python/html/static/tabledata.js
deleted file mode 100644
index 769fcf8..0000000
--- a/enervent-ctrl-python/html/static/tabledata.js
+++ /dev/null
@@ -1,52 +0,0 @@
-function zeroPad(number) {
- return ("0" + number).slice(-2)
-}
-function getData() {
- now = new Date()
- Y = now.getFullYear()
- m = now.getMonth()
- d = now.getDate()
- H = zeroPad(now.getHours())
- M = zeroPad(now.getMinutes())
- S = zeroPad(now.getSeconds())
- document.getElementById('time').innerHTML = `${Y}-${m}-${d} ${H}:${M}:${S}`
-
- error = false
- // The same index.html is used for both coil and register data,
- // change api url based on which we're looking at
- if (document.location.pathname == "/coils/") {
- url = "/api/v1/coils"
- }
- else if (document.location.pathname == "/registers/") {
- url = "/api/v1/registers"
- }
- else {
- document.getElementById("data").innerHTML = 'Page not found'
- error = true
- }
- if (!error) {
- // Fetch data from API
- fetch(url)
- .then((response) => {
- if (!response.ok) {
- throw new Error(`Error fetching data: ${response.status}`)
- }
- return response.json()
- })
- .then((data) => {
- // Populate table
- document.getElementById('coildata').innerHTML = "";
- for (n=0; n${data[n].address} | \
- ${Number(data[n].value)} | \
- ${data[n].symbol} | \
- ${data[n].description} | `
- document.getElementById('coildata').innerHTML += tablerow
- }
- });
- }
-
- // Using setTimeout instead of setInterval to avoid possible connection issues
- // There's no need to update exactly every 5 seconds, the skew is fine
- setTimeout(getData, 1*1000);
-}
\ No newline at end of file
diff --git a/enervent-ctrl-python/nginx-server-block.conf b/enervent-ctrl-python/nginx-server-block.conf
deleted file mode 100644
index 20a41c3..0000000
--- a/enervent-ctrl-python/nginx-server-block.conf
+++ /dev/null
@@ -1,59 +0,0 @@
-upstream enervent-ctrl {
- server localhost:8888;
-}
-
-server {
- listen 80 default_server;
- listen [::]:80 default_server;
-
- # SSL configuration
- #
- # listen 443 ssl default_server;
- # listen [::]:443 ssl default_server;
- #
- # Note: You should disable gzip for SSL traffic.
- # See: https://bugs.debian.org/773332
- #
- # Read up on ssl_ciphers to ensure a secure configuration.
- # See: https://bugs.debian.org/765782
- #
- # Self signed certs generated by the ssl-cert package
- # Don't use them in a production server!
- #
- # include snippets/snakeoil.conf;
-
- root /home/jarno/enervent-ctrl/enervent-ctrl-python/html;
- index index.html;
-
- server_name _;
-
- location / {
- # First attempt to serve request as file, then
- # as directory, then fall back to displaying a 404.
- if ($http_user_agent ~* "^curl") {
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Host $host:$server_port;
- proxy_set_header X-Forwarded-Port $server_port;
- proxy_pass http://enervent-ctrl;
- }
- try_files $uri $uri/ =404;
- }
-
- #location ~ /static|/coils|/registers {
- # root /home/jarno/enervent-ctrl/enervent-ctrl-python/html;
- #}
-
- location ~ /api {
- proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Host $host:$server_port;
- proxy_set_header X-Forwarded-Port $server_port;
- proxy_pass http://enervent-ctrl;
- }
-
-
-
-
-
-}
diff --git a/enervent-ctrl-python/pyvenv.cfg b/enervent-ctrl-python/pyvenv.cfg
deleted file mode 100644
index 5c102c1..0000000
--- a/enervent-ctrl-python/pyvenv.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-home = /usr/bin
-include-system-site-packages = false
-version = 3.9.2
diff --git a/enervent-ctrl-python/requirements.txt b/enervent-ctrl-python/requirements.txt
deleted file mode 100644
index bff09ad..0000000
--- a/enervent-ctrl-python/requirements.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-click==8.1.3
-Flask==2.2.2
-importlib-metadata==6.0.0
-itsdangerous==2.1.2
-Jinja2==3.1.2
-MarkupSafe==2.1.1
-minimalmodbus==2.0.1
-pyserial==3.5
-waitress==2.1.2
-Werkzeug==2.2.3
-zipp==3.11.0
diff --git a/enervent-ctrl-python/src/PingvinKL.py b/enervent-ctrl-python/src/PingvinKL.py
deleted file mode 100644
index b67fe09..0000000
--- a/enervent-ctrl-python/src/PingvinKL.py
+++ /dev/null
@@ -1,188 +0,0 @@
-import minimalmodbus
-import logging
-from flask import jsonify
-from threading import Lock
-from time import sleep
-
-class PingvinCoil():
- """Single coil data structure"""
- def __init__(self, symbol="-", description="-"):
- self.symbol = symbol
- self.value = False
- self.description = description
- self.reserved = symbol == "-" and description == "-"
-
- def serialize(self):
- return {
- "value": self.value,
- "symbol": self.symbol,
- "description": self.description,
- "reserved": self.reserved
- }
-
- def get(self):
- return jsonify(self.serialize())
-
- def flip(self):
- self.value = not self.value
-
-class PingvinCoils():
- """Class for handling Modbus coils"""
- ## coil descriptions and symbols courtesy of Ensto Enervent
- ## https://doc.enervent.com/out/out.ViewDocument.php?documentid=59
- coils = [
- PingvinCoil("COIL_STOP", "Stop"),
- PingvinCoil("COIL_AWAY", "Away mode"),
- PingvinCoil("COIL_AWAY_L", "Away Long mode"),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil("COIL_MAX_H", "Max Heating"),
- PingvinCoil("COIL_MAX_C", "Max Cooling"),
- PingvinCoil("COIL_CO_BOOST_EN", "CO2 boost"),
- PingvinCoil("COIL_RH_BOOST_EN", "Relative humidity boost"),
- PingvinCoil("COIL_M_BOOST", "Manual boost 100%"),
- PingvinCoil("COIL_TEMP_BOOST_EN", "Temperature boost"),
- PingvinCoil("COIL_SNC", "Summer night cooling"),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil("COIL_AWAY_H", "Heating enabled/disabled in AWAY mode"),
- PingvinCoil("COIL_AWAY_C", "Cooling enabled/disabled in AWAY mode"),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil("COIL_LTO_ON", "Heat recycler state (running=1, stopped = 0)"),
- PingvinCoil(),
- PingvinCoil("COIL_HEAT_ON", "After heater element state (On = 1, Off = 0)"),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil("COIL_TEMP_DECREASE", "Temperature decrease function"),
- PingvinCoil("COIL_OVERTIME", "Programmatic equivalent of OVERTIME digital input"),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil("COIL_ECO_MODE", "Eco mode"),
- PingvinCoil("COIL_ALARM_A", "Alarm of class A active"),
- PingvinCoil("COIL_ALARM_B", "Alarm of class B active"),
- PingvinCoil("COIL_CLK_PROG", "Clock program is currently active"),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil("COIL_SILENT_MODE", "Silent mode"),
- PingvinCoil("COIL_STOP_SLP_COOLING", "Electrical heater cool-off function enabled when the machine has stopped"),
- PingvinCoil("COIL_SERVICE_EN", "Service reminder"),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil("COIL_COOLING_EN", "Active cooling function enabled"),
- PingvinCoil("COIL_LTO_EN", "N/A"),
- PingvinCoil("COIL_HEATING_EN", "Active heating function enabled"),
- PingvinCoil("COIL_LTO_DEFROST_EN", "HRC defrosting function enabled during winter season"),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil(),
- PingvinCoil()
- ]
-
- def __init__(self, device, semaphore, debug=False):
- self.pingvin = device
- self.semaphore = semaphore
-
- def __getitem__(self, item):
- return self.coils[item]
-
- def update(self, debug=False):
- """Fetch all coils values from device"""
- self.pingvin.serial.timeout = 0.2
- self.pingvin.debug = debug
- if debug: logging.info(f"{len(self.coils)} coils registered")
- self.semaphore.acquire()
- curvalues = self.pingvin.read_bits(0,len(self.coils),1)
- self.semaphore.release()
- for i, coil in enumerate(self.coils):
- self.coils[i].value = bool(curvalues[i])
- if debug: logging.info("Coil values read succesfully\n")
-
- def fetchValue(self, address, debug=False):
- """Update single coil value from device and return it"""
- self.pingvin.debug = debug
- if debug: logging.debug("Updating coil value from device to cache")
- self.semaphore.acquire()
- self.coils[address].value = bool(self.pingvin.read_bit(address, 1))
- self.semaphore.release()
- return self.value(address, debug)
-
- def value(self, address, debug=False):
- """Get single local coil value"""
- if debug: logging.debug("Reading coil value from cache")
- return self.coils[address].value
-
- def print(self, debug=False):
- """Human-readable print of all coil values"""
- coilvals = ""
- for i, coil in enumerate(self.coils):
- coilvals = coilvals + f"Coil {i : <{4}}{coil.value : <{2}} {coil.symbol : <{25}}{coil.description}\n"
- return coilvals
-
- def serialize(self, include_reserved=False):
- """Returns coil values as parseable Python object"""
- coilvals = []
- for i, coil in enumerate(self.coils):
- if not coil.reserved or include_reserved:
- coil = coil.serialize()
- coil['address'] = i
- coilvals.append(coil)
- return coilvals
-
- def get(self, include_reserved=False, live=False, debug=False):
- """Return all coil values in JSON format"""
- if live: self.update(debug)
- return jsonify(self.serialize(include_reserved))
-
- def write(self, address):
- self.semaphore.acquire()
- self.pingvin.write_bit(address, int(not self.coils[address].value))
- if self.pingvin.read_bit(address, 1) != self.coils[address].value:
- self.coils[address].flip()
- self.semaphore.release()
- return True
- self.semaphore.release()
- return False
-
-class PingvinKL():
- """Class for communicating with an Enervent Pinvin Kotilämpö ventilation/heating unit"""
- def __init__(self, serialdevice='/dev/ttyS0', modbusaddr=1, debug=False):
- self.semaphore = Lock()
- self.pingvin = minimalmodbus.Instrument(serialdevice, modbusaddr)
- self.coils = PingvinCoils(self.pingvin, self.semaphore, debug)
- self.run = False
-
- def monitor(self, interval=15, debug=False):
- if not self.run: # Prevent starting two monitor threads
- self.run = True
- logging.info("Starting data monitor loop")
- while self.run:
- if debug: logging.info("Data monitor updating coil data")
- self.coils.update(debug)
- sleep(interval)
\ No newline at end of file
diff --git a/enervent-ctrl-python/src/enervent-logger.py b/enervent-ctrl-python/src/enervent-logger.py
deleted file mode 100755
index 8cef774..0000000
--- a/enervent-ctrl-python/src/enervent-logger.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-import logging
-from PingvinKL import PingvinKL
-from flask import Flask, request
-import threading
-from waitress import serve
-
-VERSION = "0.0.1"
-DEBUG = False
-
-## Logging configuration
-log = logging.getLogger(__name__)
-if DEBUG:
- dbglevel = logging.DEBUG
-else:
- dbglevel = logging.INFO
-logging.basicConfig(
- level=dbglevel,
- format='%(asctime)s %(message)s',
- datefmt='%y/%m/%d %H:%M:%S'
- )
-
-pingvin = PingvinKL('/dev/ttyS0',1,debug=DEBUG)
-app = Flask(__name__)
-
-@app.route('/api/v1/coils')
-def get_all():
- return pingvin.coils.get(include_reserved=request.args.get('include_reserved'),live=request.args.get('live'),debug=DEBUG)
-
-@app.route('/api/v1/coils/', methods=["GET","PUT"])
-def coil(address):
- if request.method == 'GET':
- coil = pingvin.coils[address].get()
- return coil
- elif request.method == 'PUT':
- return {"success": pingvin.coils.write(address)}
-
-@app.route('/')
-def dump():
- return pingvin.coils.print(debug=DEBUG)
-
-if __name__ == "__main__":
- log.info(f"Starting enervent-logger {VERSION}")
- datathread = threading.Thread(target=pingvin.monitor, kwargs={"interval": 2, "debug": DEBUG})
- datathread.start()
- # app.run(host='0.0.0.0', port=8888)
- serve(app, listen='*:8888', trusted_proxy='127.0.0.1', trusted_proxy_headers="x-forwarded-for x-forwarded-host x-forwarded-proto x-forwarded-port")
\ No newline at end of file