Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec8d3ca94c | ||
|
|
88687124f2 | ||
|
|
97233f27c3 | ||
|
|
b35aacad3f | ||
|
|
2136406a28 | ||
|
|
ff13d8eeeb | ||
|
|
fece181c6f | ||
|
|
85d7be4117 | ||
|
|
56e8282a82 | ||
|
|
1c4949020b | ||
|
|
a71d8565c4 | ||
|
|
7e09a1e51f | ||
|
|
92fac02a9e | ||
|
|
320bcae78e | ||
|
|
d6a0efd69b | ||
|
|
40a79af9af | ||
|
|
229719cc5c | ||
|
|
ac6345c5b5 | ||
|
|
7773788e20 | ||
|
|
ac154e6770 | ||
|
|
a4ec93f412 | ||
|
|
16d7624154 | ||
|
|
54b93cb05c | ||
|
|
3d3254c4a7 | ||
|
|
cfe6e3c286 | ||
|
|
7a3877b34b | ||
|
|
f20dd30292 | ||
|
|
ef5c87d8d2 | ||
|
|
4878df9ca8 |
No files matched your search
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
parserOptions:
|
||||
ecmaVersion: 2019
|
||||
env:
|
||||
browser: true
|
||||
jquery: true
|
||||
+2
-2
@@ -128,5 +128,5 @@ dmypy.json
|
||||
# Pyre type checker
|
||||
.pyre/
|
||||
|
||||
# Include frontend libraries though
|
||||
!/frontend/lib
|
||||
# Include frontend ibraries though
|
||||
!terahz/templates/lib
|
||||
@@ -0,0 +1 @@
|
||||
language: python
|
||||
File renamed without changes.
@@ -0,0 +1,15 @@
|
||||
[[source]]
|
||||
name = "pypi"
|
||||
url = "https://pypi.org/simple"
|
||||
verify_ssl = true
|
||||
|
||||
[dev-packages]
|
||||
|
||||
[packages]
|
||||
flask = "*"
|
||||
smbus2 = "*"
|
||||
pyserial = "*"
|
||||
pandas = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.8"
|
||||
Generated
+184
@@ -0,0 +1,184 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "7fb3ae0afbe0d0c2af92f618aa1c54442566daeb561480eee2c2a299f1c2bee7"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
"python_version": "3.8"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
"url": "https://pypi.org/simple",
|
||||
"verify_ssl": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
|
||||
"sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
|
||||
],
|
||||
"version": "==7.1.2"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060",
|
||||
"sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.1.2"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
|
||||
"sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0",
|
||||
"sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"
|
||||
],
|
||||
"version": "==2.11.2"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
|
||||
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
|
||||
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
|
||||
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
|
||||
"sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42",
|
||||
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
|
||||
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
|
||||
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
|
||||
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
|
||||
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
|
||||
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
|
||||
"sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b",
|
||||
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
|
||||
"sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15",
|
||||
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
|
||||
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
|
||||
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
|
||||
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
|
||||
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
|
||||
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
|
||||
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
|
||||
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
|
||||
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
|
||||
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
|
||||
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
|
||||
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
|
||||
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
|
||||
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
|
||||
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
|
||||
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
|
||||
"sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2",
|
||||
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7",
|
||||
"sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"
|
||||
],
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"numpy": {
|
||||
"hashes": [
|
||||
"sha256:082f8d4dd69b6b688f64f509b91d482362124986d98dc7dc5f5e9f9b9c3bb983",
|
||||
"sha256:1bc0145999e8cb8aed9d4e65dd8b139adf1919e521177f198529687dbf613065",
|
||||
"sha256:309cbcfaa103fc9a33ec16d2d62569d541b79f828c382556ff072442226d1968",
|
||||
"sha256:3673c8b2b29077f1b7b3a848794f8e11f401ba0b71c49fbd26fb40b71788b132",
|
||||
"sha256:480fdd4dbda4dd6b638d3863da3be82873bba6d32d1fc12ea1b8486ac7b8d129",
|
||||
"sha256:56ef7f56470c24bb67fb43dae442e946a6ce172f97c69f8d067ff8550cf782ff",
|
||||
"sha256:5a936fd51049541d86ccdeef2833cc89a18e4d3808fe58a8abeb802665c5af93",
|
||||
"sha256:5b6885c12784a27e957294b60f97e8b5b4174c7504665333c5e94fbf41ae5d6a",
|
||||
"sha256:667c07063940e934287993366ad5f56766bc009017b4a0fe91dbd07960d0aba7",
|
||||
"sha256:7ed448ff4eaffeb01094959b19cbaf998ecdee9ef9932381420d514e446601cd",
|
||||
"sha256:8343bf67c72e09cfabfab55ad4a43ce3f6bf6e6ced7acf70f45ded9ebb425055",
|
||||
"sha256:92feb989b47f83ebef246adabc7ff3b9a59ac30601c3f6819f8913458610bdcc",
|
||||
"sha256:935c27ae2760c21cd7354402546f6be21d3d0c806fffe967f745d5f2de5005a7",
|
||||
"sha256:aaf42a04b472d12515debc621c31cf16c215e332242e7a9f56403d814c744624",
|
||||
"sha256:b12e639378c741add21fbffd16ba5ad25c0a1a17cf2b6fe4288feeb65144f35b",
|
||||
"sha256:b1cca51512299841bf69add3b75361779962f9cee7d9ee3bb446d5982e925b69",
|
||||
"sha256:b8456987b637232602ceb4d663cb34106f7eb780e247d51a260b84760fd8f491",
|
||||
"sha256:b9792b0ac0130b277536ab8944e7b754c69560dac0415dd4b2dbd16b902c8954",
|
||||
"sha256:c9591886fc9cbe5532d5df85cb8e0cc3b44ba8ce4367bd4cf1b93dc19713da72",
|
||||
"sha256:cf1347450c0b7644ea142712619533553f02ef23f92f781312f6a3553d031fc7",
|
||||
"sha256:de8b4a9b56255797cbddb93281ed92acbc510fb7b15df3f01bd28f46ebc4edae",
|
||||
"sha256:e1b1dc0372f530f26a03578ac75d5e51b3868b9b76cd2facba4c9ee0eb252ab1",
|
||||
"sha256:e45f8e981a0ab47103181773cc0a54e650b2aef8c7b6cd07405d0fa8d869444a",
|
||||
"sha256:e4f6d3c53911a9d103d8ec9518190e52a8b945bab021745af4939cfc7c0d4a9e",
|
||||
"sha256:ed8a311493cf5480a2ebc597d1e177231984c818a86875126cfd004241a73c3e",
|
||||
"sha256:ef71a1d4fd4858596ae80ad1ec76404ad29701f8ca7cdcebc50300178db14dfc"
|
||||
],
|
||||
"version": "==1.19.1"
|
||||
},
|
||||
"pandas": {
|
||||
"hashes": [
|
||||
"sha256:01b1e536eb960822c5e6b58357cad8c4b492a336f4a5630bf0b598566462a578",
|
||||
"sha256:0246c67cbaaaac8d25fed8d4cf2d8897bd858f0e540e8528a75281cee9ac516d",
|
||||
"sha256:0366150fe8ee37ef89a45d3093e05026b5f895e42bbce3902ce3b6427f1b8471",
|
||||
"sha256:16ae070c47474008769fc443ac765ffd88c3506b4a82966e7a605592978896f9",
|
||||
"sha256:1acc2bd7fc95e5408a4456897c2c2a1ae7c6acefe108d90479ab6d98d34fcc3d",
|
||||
"sha256:391db82ebeb886143b96b9c6c6166686c9a272d00020e4e39ad63b792542d9e2",
|
||||
"sha256:41675323d4fcdd15abde068607cad150dfe17f7d32290ee128e5fea98442bd09",
|
||||
"sha256:53328284a7bb046e2e885fd1b8c078bd896d7fc4575b915d4936f54984a2ba67",
|
||||
"sha256:57c5f6be49259cde8e6f71c2bf240a26b071569cabc04c751358495d09419e56",
|
||||
"sha256:84c101d0f7bbf0d9f1be9a2f29f6fcc12415442558d067164e50a56edfb732b4",
|
||||
"sha256:88930c74f69e97b17703600233c0eaf1f4f4dd10c14633d522724c5c1b963ec4",
|
||||
"sha256:8c9ec12c480c4d915e23ee9c8a2d8eba8509986f35f307771045c1294a2e5b73",
|
||||
"sha256:a81c4bf9c59010aa3efddbb6b9fc84a9b76dc0b4da2c2c2d50f06a9ef6ac0004",
|
||||
"sha256:d9644ac996149b2a51325d48d77e25c911e01aa6d39dc1b64be679cd71f683ec",
|
||||
"sha256:e4b6c98f45695799990da328e6fd7d6187be32752ed64c2f22326ad66762d179",
|
||||
"sha256:fe6f1623376b616e03d51f0dd95afd862cf9a33c18cf55ce0ed4bbe1c4444391"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"pyserial": {
|
||||
"hashes": [
|
||||
"sha256:6e2d401fdee0eab996cf734e67773a0143b932772ca8b42451440cfed942c627",
|
||||
"sha256:e0770fadba80c31013896c7e6ef703f72e7834965954a78e71a3049488d4d7d8"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==3.4"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
|
||||
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
|
||||
],
|
||||
"version": "==2.8.1"
|
||||
},
|
||||
"pytz": {
|
||||
"hashes": [
|
||||
"sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed",
|
||||
"sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"
|
||||
],
|
||||
"version": "==2020.1"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
|
||||
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
|
||||
],
|
||||
"version": "==1.15.0"
|
||||
},
|
||||
"smbus2": {
|
||||
"hashes": [
|
||||
"sha256:210e66eebe4d0b1fe836b3ec2751841942e1c4918c0b429b20a0e20a222228b4"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.3.0"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43",
|
||||
"sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"
|
||||
],
|
||||
"version": "==1.0.1"
|
||||
}
|
||||
},
|
||||
"develop": {}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
[](https://terahz.readthedocs.io/en/latest/?badge=latest)
|
||||
[](https://github.com/standard/semistandard)
|
||||
# <img alt="TeraHz logo" src="docs/imgs/logo-sq.png" width="200px"> TeraHz
|
||||
|
||||
*Za slovensko različico se odpravite na <http://git.sckr-lab.tk/kristjank/TeraHz>*
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# app.py - main backend program
|
||||
'''Main TeraHz backend program'''
|
||||
# All code in this file is licensed under the ISC license, provided in LICENSE.txt
|
||||
from flask import Flask, jsonify
|
||||
import sensors
|
||||
|
||||
app = Flask(__name__)
|
||||
@app.route('/data')
|
||||
def sendData():
|
||||
'''Responder function for /data route'''
|
||||
s = sensors.Spectrometer(path='/dev/serial0', baudrate=115200, tout=1)
|
||||
u = sensors.UVSensor()
|
||||
l = sensors.LxMeter()
|
||||
response = jsonify([s.getData(), l.getData(), u.getABI()])
|
||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||
return response
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
# run.sh - run the backend server
|
||||
cd `dirname $0`
|
||||
sudo gunicorn app:app -b 0.0.0.0:5000 &
|
||||
Binary file not shown.
@@ -1,37 +0,0 @@
|
||||
# storage.py - storage backend for TeraHz
|
||||
'''TeraHz storage backend'''
|
||||
# Copyright Kristjan Komloši 2019
|
||||
# All code in this file is licensed under the ISC license,
|
||||
# provided in LICENSE.txt
|
||||
|
||||
|
||||
import sqlite3
|
||||
class jsonStorage:
|
||||
'''Class for simple sqlite3 database of JSON entries'''
|
||||
def __init__(self, dbFile):
|
||||
'''Storage object constructor. Argument is filename'''
|
||||
self.db = sqlite3.connect(dbFile)
|
||||
|
||||
def listJSONs(self):
|
||||
'''Returns a list of all existing entries.'''
|
||||
c = self.db.cursor()
|
||||
c.execute('SELECT * FROM storage')
|
||||
result = c.fetchall()
|
||||
c.close()
|
||||
return result
|
||||
|
||||
def storeJSON(self, jsonString, comment):
|
||||
'''Stores a JSON entry along with a timestamp and a comment.'''
|
||||
c = self.db.cursor()
|
||||
c.execute(('INSERT INTO storage VALUES (datetime'
|
||||
'(\'now\', \'localtime\'), ?, ?)'), (comment, jsonString))
|
||||
c.close()
|
||||
self.db.commit()
|
||||
|
||||
def retrieveJSON(self, timestamp):
|
||||
'''Retrieves a JSON entry. Takes a timestamp string'''
|
||||
c = self.db.cursor()
|
||||
c.execute('SELECT * FROM storage WHERE timestamp = ?', (timestamp,))
|
||||
result = c.fetchall()
|
||||
c.close()
|
||||
return result
|
||||
Whitespace-only changes.
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/python3
|
||||
# Minimal flup configuration for Flask
|
||||
from flup.server.fcgi import WSGIServer
|
||||
from app import app
|
||||
|
||||
if __name__ == '__main__':
|
||||
WSGIServer(app, bindAddress='/var/www/api/terahz.sock').run()
|
||||
@@ -1,3 +0,0 @@
|
||||
interface=wlan0
|
||||
dhcp-range=192.168.1.10,192.168.1.100,255.255.255.0,24h
|
||||
address=/terahz.site/192.168.1.1
|
||||
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
# edit_ssid.sh - edits hostapd.conf and sets a MAC address-based SSID
|
||||
cd `dirname $0`
|
||||
ssid=`ip link | awk '/wlan0/ {getline; print $2}' | awk -v FS=':' '{printf("TeraHz_%s%s%s\n", $4, $5, $6)}'`
|
||||
sed "/ssid=.*/s/ssid=.*/ssid=$ssid/" hostapd.conf > newconf
|
||||
mv newconf hostapd.conf
|
||||
@@ -1,9 +0,0 @@
|
||||
interface=wlan0
|
||||
hw_mode=g
|
||||
channel=8
|
||||
wpa=2
|
||||
wpa_key_mgmt=WPA-PSK
|
||||
wpa_pairwise=TKIP
|
||||
rsn_pairwise=CCMP
|
||||
ssid=TeraHz
|
||||
wpa_passphrase=terahertz
|
||||
@@ -1,22 +0,0 @@
|
||||
# install.sh - install TeraHz onto a Raspbian or DietPi installation
|
||||
cd `dirname $0`
|
||||
|
||||
apt -y update
|
||||
apt -y full-upgrade
|
||||
apt install -y python3 python3-pip lighttpd dnsmasq hostapd libatlas-base-dev
|
||||
pip3 install numpy pandas flask smbus2 pyserial gunicorn
|
||||
|
||||
cp -R hostapd/ /etc
|
||||
chmod +rx /etc/hostapd/edit_ssid.sh
|
||||
cp dnsmasq.conf /etc
|
||||
|
||||
cp rc.local /etc
|
||||
chmod +rx /etc/rc.local
|
||||
cp interfaces-terahz /etc/network/interfaces.d/
|
||||
|
||||
cp -R ../frontend/* /var/www/html/
|
||||
mkdir -p /usr/local/lib/terahz
|
||||
cp -R ../backend/* /usr/local/lib/terahz
|
||||
|
||||
systemctl unmask dnsmasq hostapd lighttpd
|
||||
systemctl enable dnsmasq hostapd lighttpd
|
||||
@@ -1,3 +0,0 @@
|
||||
iface wlan0 inet static
|
||||
address 192.168.1.1
|
||||
netmask 255.255.255.0
|
||||
@@ -1,16 +0,0 @@
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# rc.local
|
||||
#
|
||||
# This script is executed at the end of each multiuser runlevel.
|
||||
# Make sure that the script will "exit 0" on success or any other
|
||||
# value on error.
|
||||
#
|
||||
# In order to enable or disable this script just change the execution
|
||||
# bits.
|
||||
#
|
||||
# By default this script does nothing.
|
||||
/etc/hostapd/edit_ssid.sh &
|
||||
/usr/local/lib/terahz/run.sh &
|
||||
sleep 3
|
||||
service hostapd restart # restart hostapd to prevent a weird startup race condition
|
||||
@@ -1,173 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<link rel="stylesheet" href="lib/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="stylesheet.css">
|
||||
<title>TeraHz</title>
|
||||
<script src="lib/bootstrap.bundle.min.js"></script>
|
||||
<script src="lib/jquery-3.4.1.min.js"></script>
|
||||
<script src="lib/flot/jquery.flot.js"></script>
|
||||
<script src="frontend.js"></script>
|
||||
<script src="lib/flot/jquery.canvaswrapper.js"></script>
|
||||
<script src="lib/flot/jquery.colorhelpers.js"></script>
|
||||
<script src="lib/flot/jquery.flot.js"></script>
|
||||
<script src="lib/flot/jquery.flot.saturated.js"></script>
|
||||
<script src="lib/flot/jquery.flot.browser.js"></script>
|
||||
<script src="lib/flot/jquery.flot.drawSeries.js"></script>
|
||||
<script src="lib/flot/jquery.flot.uiConstants.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container text-center">
|
||||
<h1><img src="lib/logo-sq.png" height="64px">TeraHz</h1>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<button id="update" onclick="updateData()" class="btn btn-primary">Get data</button>
|
||||
<button id="download" class="btn btn-primary">Download</button>
|
||||
<button id="debug" class="btn btn-danger">DEBUG</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<h4>Spectrogram</h4>
|
||||
<div id="graph" style="height:480px;width:720px"></div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
<h4>Visible+IR spectrum</h4>
|
||||
<table class="table table-dark table-sm" id="specter">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Band</th>
|
||||
<th>Wavelength [nm]</th>
|
||||
<th>Irradiance [μW/cm²]</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td>A</td>
|
||||
<td>410 nm</td>
|
||||
<td id="A">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>B</td>
|
||||
<td>435 nm</td>
|
||||
<td id="B">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>C</td>
|
||||
<td>460 nm</td>
|
||||
<td id="C">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>D</td>
|
||||
<td>485 nm</td>
|
||||
<td id="D">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>E</td>
|
||||
<td>510 nm</td>
|
||||
<td id="E">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>F</td>
|
||||
<td>535 nm</td>
|
||||
<td id="F">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>G</td>
|
||||
<td>560 nm</td>
|
||||
<td id="G">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>H</td>
|
||||
<td>585 nm</td>
|
||||
<td id="H">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>R</td>
|
||||
<td>610 nm</td>
|
||||
<td id="R">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>I</td>
|
||||
<td>645 nm</td>
|
||||
<td id="I">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>S</td>
|
||||
<td>680 nm</td>
|
||||
<td id="S">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>J</td>
|
||||
<td>705 nm</td>
|
||||
<td id="J">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>T</td>
|
||||
<td>730 nm</td>
|
||||
<td id="T">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>U</td>
|
||||
<td>760 nm</td>
|
||||
<td id="U">---</td>
|
||||
</tr>
|
||||
<tr class="table-secondary">
|
||||
<td>V</td>
|
||||
<td>810 nm</td>
|
||||
<td id="V">---</td>
|
||||
</tr>
|
||||
<tr class="table-secondary">
|
||||
<td>W</td>
|
||||
<td>860 nm</td>
|
||||
<td id="W">---</td>
|
||||
</tr>
|
||||
<tr class="table-secondary">
|
||||
<td>K</td>
|
||||
<td>900 nm</td>
|
||||
<td id="K">---</td>
|
||||
</tr>
|
||||
<tr class="table-secondary">
|
||||
<td>L</td>
|
||||
<td>940 nm</td>
|
||||
<td id="L">---</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
<h4>UV+Illuminance</h4>
|
||||
<table class="table-dark table table-sm" id="luxuv">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td>Illuminance [lx]</td>
|
||||
<td id="lx">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UVA irradiance [μW/cm²]</td>
|
||||
<td id="uva">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UVB irradiance [μW/cm²]</td>
|
||||
<td id="uvb">---</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UVA/UVB average [μW/cm²]</td>
|
||||
<td id="uvi">---</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["../../js/src/util.js","../../js/src/alert.js","../../js/src/button.js","../../js/src/carousel.js","../../js/src/collapse.js","../../node_modules/popper.js/dist/esm/popper.js","../../js/src/dropdown.js","../../js/src/modal.js","../../js/src/tools/sanitizer.js","../../js/src/tooltip.js","../../js/src/popover.js","../../js/src/scrollspy.js","../../js/src/tab.js","../../js/src/toast.js","../../js/src/index.js"],"names":["TRANSITION_END","transitionEndEmulator","duration","_this","this","called","$","one","Util","setTimeout","triggerTransitionEnd","getUID","prefix","Math","random","document","getElementById","getSelectorFromElement","element","selector","getAttribute","hrefAttr","trim","querySelector","err","getTransitionDurationFromElement","transitionDuration","css","transitionDelay","floatTransitionDuration","parseFloat","floatTransitionDelay","split","reflow","offsetHeight","trigger","supportsTransitionEnd","Boolean","isElement","obj","nodeType","typeCheckConfig","componentName","config","configTypes","property","Object","prototype","hasOwnProperty","call","expectedTypes","value","valueType","toString","match","toLowerCase","RegExp","test","Error","toUpperCase","findShadowRoot","documentElement","attachShadow","getRootNode","ShadowRoot","parentNode","root","fn","emulateTransitionEnd","event","special","bindType","delegateType","handle","target","is","handleObj","handler","apply","arguments","NAME","DATA_KEY","EVENT_KEY","JQUERY_NO_CONFLICT","Event","CLOSE","CLOSED","CLICK_DATA_API","ClassName","Alert","_element","close","rootElement","_getRootElement","_triggerCloseEvent","isDefaultPrevented","_removeElement","dispose","removeData","parent","closest","closeEvent","removeClass","hasClass","_destroyElement","detach","remove","_jQueryInterface","each","$element","data","_handleDismiss","alertInstance","preventDefault","on","Constructor","noConflict","DATA_API_KEY","Selector","FOCUS_BLUR_DATA_API","Button","toggle","triggerChangeEvent","addAriaPressed","input","type","checked","classList","contains","activeElement","hasAttribute","focus","setAttribute","toggleClass","button","Default","interval","keyboard","slide","pause","wrap","touch","DefaultType","Direction","SLIDE","SLID","KEYDOWN","MOUSEENTER","MOUSELEAVE","TOUCHSTART","TOUCHMOVE","TOUCHEND","POINTERDOWN","POINTERUP","DRAG_START","LOAD_DATA_API","PointerType","TOUCH","PEN","Carousel","_items","_interval","_activeElement","_isPaused","_isSliding","touchTimeout","touchStartX","touchDeltaX","_config","_getConfig","_indicatorsElement","_touchSupported","navigator","maxTouchPoints","_pointerEvent","window","PointerEvent","MSPointerEvent","_addEventListeners","next","_slide","nextWhenVisible","hidden","prev","cycle","clearInterval","setInterval","visibilityState","bind","to","index","activeIndex","_getItemIndex","length","direction","off","_objectSpread","_handleSwipe","absDeltax","abs","_this2","_keydown","_addTouchEventListeners","_this3","start","originalEvent","pointerType","clientX","touches","end","clearTimeout","querySelectorAll","e","add","tagName","which","slice","indexOf","_getItemByDirection","isNextDirection","isPrevDirection","lastItemIndex","itemIndex","_triggerSlideEvent","relatedTarget","eventDirectionName","targetIndex","fromIndex","slideEvent","from","_setActiveIndicatorElement","indicators","nextIndicator","children","addClass","directionalClassName","orderClassName","_this4","activeElementIndex","nextElement","nextElementIndex","isCycling","slidEvent","nextElementInterval","parseInt","defaultInterval","action","TypeError","ride","_dataApiClickHandler","slideIndex","carousels","i","len","$carousel","SHOW","SHOWN","HIDE","HIDDEN","Dimension","Collapse","_isTransitioning","_triggerArray","id","toggleList","elem","filterElement","filter","foundElem","_selector","push","_parent","_getParent","_addAriaAndCollapsedClass","hide","show","actives","activesData","not","startEvent","dimension","_getDimension","style","attr","setTransitioning","scrollSize","getBoundingClientRect","triggerArrayLength","isTransitioning","jquery","_getTargetFromElement","triggerArray","isOpen","$this","currentTarget","$trigger","selectors","$target","isBrowser","longerTimeoutBrowsers","timeoutDuration","userAgent","debounce","Promise","resolve","then","scheduled","isFunction","functionToCheck","getStyleComputedProperty","ownerDocument","defaultView","getComputedStyle","getParentNode","nodeName","host","getScrollParent","body","_getStyleComputedProp","overflow","overflowX","overflowY","isIE11","MSInputMethodContext","documentMode","isIE10","isIE","version","getOffsetParent","noOffsetParent","offsetParent","nextElementSibling","getRoot","node","findCommonOffsetParent","element1","element2","order","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","range","createRange","setStart","setEnd","commonAncestorContainer","firstElementChild","element1root","getScroll","upperSide","undefined","html","scrollingElement","getBordersSize","styles","axiLine truncated
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"sources":["../../scss/bootstrap.scss","../../scss/_root.scss","../../scss/_reboot.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","bootstrap.css","../../scss/mixins/_hover.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/mixins/_border-radius.scss","../../scss/_code.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/mixins/_breakpoints.scss","../../scss/mixins/_grid-framework.scss","../../scss/_tables.scss","../../scss/mixins/_table-row.scss","../../scss/_forms.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_forms.scss","../../scss/mixins/_gradients.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/mixins/_nav-divider.scss","../../scss/_button-group.scss","../../scss/_input-group.scss","../../scss/_custom-forms.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/mixins/_badge.scss","../../scss/_jumbotron.scss","../../scss/_alert.scss","../../scss/mixins/_alert.scss","../../scss/_progress.scss","../../scss/_media.scss","../../scss/_list-group.scss","../../scss/mixins/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/utilities/_align.scss","../../scss/mixins/_background-variant.scss","../../scss/utilities/_background.scss","../../scss/utilities/_borders.scss","../../scss/utilities/_display.scss","../../scss/utilities/_embed.scss","../../scss/utilities/_flex.scss","../../scss/utilities/_float.scss","../../scss/utilities/_overflow.scss","../../scss/utilities/_position.scss","../../scss/utilities/_screenreaders.scss","../../scss/mixins/_screen-reader.scss","../../scss/utilities/_shadows.scss","../../scss/utilities/_sizing.scss","../../scss/utilities/_stretched-link.scss","../../scss/utilities/_spacing.scss","../../scss/utilities/_text.scss","../../scss/mixins/_text-truncate.scss","../../scss/mixins/_text-emphasis.scss","../../scss/mixins/_text-hide.scss","../../scss/utilities/_visibility.scss","../../scss/_print.scss"],"names":[],"mappings":"AAAA;;;;;ACAA,MAGI,OAAA,QAAA,SAAA,QAAA,SAAA,QAAA,OAAA,QAAA,MAAA,QAAA,SAAA,QAAA,SAAA,QAAA,QAAA,QAAA,OAAA,QAAA,OAAA,QAAA,QAAA,KAAA,OAAA,QAAA,YAAA,QAIA,UAAA,QAAA,YAAA,QAAA,UAAA,QAAA,OAAA,QAAA,UAAA,QAAA,SAAA,QAAA,QAAA,QAAA,OAAA,QAIA,gBAAA,EAAA,gBAAA,MAAA,gBAAA,MAAA,gBAAA,MAAA,gBAAA,OAKF,yBAAA,aAAA,CAAA,kBAAA,CAAA,UAAA,CAAA,MAAA,CAAA,gBAAA,CAAA,KAAA,CAAA,WAAA,CAAA,UAAA,CAAA,mBAAA,CAAA,gBAAA,CAAA,iBAAA,CAAA,mBACA,wBAAA,cAAA,CAAA,KAAA,CAAA,MAAA,CAAA,QAAA,CAAA,iBAAA,CAAA,aAAA,CAAA,UCCF,ECqBA,QADA,SDjBE,WAAA,WAGF,KACE,YAAA,WACA,YAAA,KACA,yBAAA,KACA,4BAAA,YAMF,QAAA,MAAA,WAAA,OAAA,OAAA,OAAA,OAAA,KAAA,IAAA,QACE,QAAA,MAUF,KACE,OAAA,EACA,YAAA,aAAA,CAAA,kBAAA,CAAA,UAAA,CAAA,MAAA,CAAA,gBAAA,CAAA,KAAA,CAAA,WAAA,CAAA,UAAA,CAAA,mBAAA,CAAA,gBAAA,CAAA,iBAAA,CAAA,mBEgFI,UAAA,KF9EJ,YAAA,IACA,YAAA,IACA,MAAA,QACA,WAAA,KACA,iBAAA,KGYF,sBHHE,QAAA,YASF,GACE,WAAA,YACA,OAAA,EACA,SAAA,QAaF,GAAA,GAAA,GAAA,GAAA,GAAA,GACE,WAAA,EACA,cAAA,MAOF,EACE,WAAA,EACA,cAAA,KCZF,0BDuBA,YAEE,gBAAA,UACA,wBAAA,UAAA,OAAA,gBAAA,UAAA,OACA,OAAA,KACA,cAAA,EACA,iCAAA,KAAA,yBAAA,KAGF,QACE,cAAA,KACA,WAAA,OACA,YAAA,QCjBF,GDoBA,GCrBA,GDwBE,WAAA,EACA,cAAA,KAGF,MCpBA,MACA,MAFA,MDyBE,cAAA,EAGF,GACE,YAAA,IAGF,GACE,cAAA,MACA,YAAA,EAGF,WACE,OAAA,EAAA,EAAA,KAGF,ECrBA,ODuBE,YAAA,OAGF,MEpFI,UAAA,IF6FJ,IC1BA,ID4BE,SAAA,SE/FE,UAAA,IFiGF,YAAA,EACA,eAAA,SAGF,IAAM,OAAA,OACN,IAAM,IAAA,MAON,EACE,MAAA,QACA,gBAAA,KACA,iBAAA,YI5KA,QJ+KE,MAAA,QACA,gBAAA,UAUJ,8BACE,MAAA,QACA,gBAAA,KIxLA,oCAAA,oCJ2LE,MAAA,QACA,gBAAA,KANJ,oCAUI,QAAA,EC5BJ,KACA,IDoCA,ICnCA,KDuCE,YAAA,cAAA,CAAA,KAAA,CAAA,MAAA,CAAA,QAAA,CAAA,iBAAA,CAAA,aAAA,CAAA,UErJE,UAAA,IFyJJ,IAEE,WAAA,EAEA,cAAA,KAEA,SAAA,KAQF,OAEE,OAAA,EAAA,EAAA,KAQF,IACE,eAAA,OACA,aAAA,KAGF,IAGE,SAAA,OACA,eAAA,OAQF,MACE,gBAAA,SAGF,QACE,YAAA,OACA,eAAA,OACA,MAAA,QACA,WAAA,KACA,aAAA,OAGF,GAGE,WAAA,QAQF,MAEE,QAAA,aACA,cAAA,MAMF,OAEE,cAAA,EAOF,aACE,QAAA,IAAA,OACA,QAAA,IAAA,KAAA,yBCvEF,OD0EA,MCxEA,SADA,OAEA,SD4EE,OAAA,EACA,YAAA,QEtPE,UAAA,QFwPF,YAAA,QAGF,OC1EA,MD4EE,SAAA,QAGF,OC1EA,OD4EE,eAAA,KAMF,OACE,UAAA,OC1EF,cACA,aACA,cD+EA,OAIE,mBAAA,OC9EF,6BACA,4BACA,6BDiFE,sBAKI,OAAA,QCjFN,gCACA,+BACA,gCDqFA,yBAIE,QAAA,EACA,aAAA,KCpFF,qBDuFA,kBAEE,WAAA,WACA,QAAA,EAIF,iBCvFA,2BACA,kBAFA,iBDiGE,mBAAA,QAGF,SACE,SAAA,KAEA,OAAA,SAGF,SAME,UAAA,EAEA,QAAA,EACA,OAAA,EACA,OAAA,EAKF,OACE,QAAA,MACA,MAAA,KACA,UAAA,KACA,QAAA,EACA,cAAA,MElSI,UAAA,OFoSJ,YAAA,QACA,MAAA,QACA,YAAA,OAGF,SACE,eAAA,SGtGF,yCFGA,yCDyGE,OAAA,KGvGF,cH+GE,eAAA,KACA,mBAAA,KG3GF,yCHmHE,mBAAA,KAQF,6BACE,KAAA,QACA,mBAAA,OAOF,OACLine truncated
|
||||
@@ -0,0 +1,22 @@
|
||||
import setuptools
|
||||
|
||||
with open("README.md", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
setuptools.setup(
|
||||
name="terahz", # Replace with your own username
|
||||
version="1.0.0",
|
||||
author="Kristjan Komloši",
|
||||
author_email="kristjan.komlosi@gmail.com",
|
||||
description="Low cost spectrometry webapp",
|
||||
long_description=long_description,
|
||||
long_description_content_type="text/markdown",
|
||||
url="https://github.com/cls-02/TeraHz",
|
||||
packages=setuptools.find_packages(),
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
],
|
||||
python_requires='>=3.6',
|
||||
)
|
||||
@@ -0,0 +1,46 @@
|
||||
# app.py - main backend program
|
||||
'''Main TeraHz backend program'''
|
||||
# All code in this file is licensed under the ISC license, provided in LICENSE.txt
|
||||
from flask import Flask, jsonify, render_template
|
||||
from . import terahz
|
||||
|
||||
def start_flaskapp():
|
||||
'''Initialize global variables'''
|
||||
global app, s, u, l
|
||||
app = Flask(__name__)
|
||||
s = terahz.Spectrometer(path='/dev/serial0')
|
||||
u = terahz.UVSensor()
|
||||
l = terahz.LxMeter()
|
||||
|
||||
@app.route('/data')
|
||||
def sendData():
|
||||
'''Responder function for /data route'''
|
||||
response = jsonify([s.getData(), l.getData(), u.getABI()])
|
||||
response.headers.add('Access-Control-Allow-Origin', '*')
|
||||
return response
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def renderTable():
|
||||
''''Main page renderer'''
|
||||
wavelengthDict = {
|
||||
'A': '410 nm',
|
||||
'B': '435 nm',
|
||||
'C': '460 nm',
|
||||
'D': '485 nm',
|
||||
'E': '510 nm',
|
||||
'F': '535 nm',
|
||||
'G': '560 nm',
|
||||
'H': '585 nm',
|
||||
'R': '610 nm',
|
||||
'I': '645 nm',
|
||||
'S': '680 nm',
|
||||
'J': '705 nm',
|
||||
'T': '730 nm',
|
||||
'U': '760 nm',
|
||||
'V': '810 nm',
|
||||
'W': '860 nm',
|
||||
'K': '900 nm',
|
||||
'L': '940 nm'}
|
||||
data = [s.getData(), l.getData(), u.getABI()]
|
||||
return render_template('index.html', data=data, wavelengths=wavelengthDict)
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -3,15 +3,12 @@ $('#update').click(updateData);
|
||||
// jQuery event binder
|
||||
|
||||
function updateData () {
|
||||
const url = 'http://' + window.location.hostname + ':5000/data';
|
||||
$.ajax({ // spawn an AJAX request
|
||||
url: url,
|
||||
success: function (data, status) {
|
||||
console.log(data);
|
||||
const url = '/data';
|
||||
$.get(url, (data, status) => {
|
||||
if (status === '200') {
|
||||
graphSpectralData(data[0], 0);
|
||||
fillTableData(data);
|
||||
},
|
||||
timeout: 2500 // this should be a pretty sane timeout
|
||||
} else alert('Data request failed, please refresh page.');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -19,12 +16,13 @@ function graphSpectralData (obj, dom) {
|
||||
// graph spectral data in obj into dom
|
||||
var graphPoints = [];
|
||||
var graphXTicks = [];
|
||||
const spectrum = 'ABCDEFGHRISJTUVWKL';
|
||||
|
||||
const specter = 'ABCDEFGHRISJTUVWKL';
|
||||
for (var i = 0; i < specter.length; i++) {
|
||||
graphPoints.push([i, obj[specter[i]]]);
|
||||
graphXTicks.push([i, specter[i]]);
|
||||
for (var i = 0; i < spectrum.length; i++) {
|
||||
graphPoints.push([i, obj[spectrum[i]]]);
|
||||
graphXTicks.push([i, spectrum[i]]);
|
||||
}
|
||||
|
||||
const options = {
|
||||
grid: { color: 'white' },
|
||||
xaxis: { ticks: graphXTicks }
|
||||
@@ -35,8 +33,8 @@ function graphSpectralData (obj, dom) {
|
||||
|
||||
function fillTableData (obj) {
|
||||
// fill the obj data into HTML tables
|
||||
Object.keys(obj[0])
|
||||
.forEach((element) => { $('#' + element).text(obj[0][element]); });
|
||||
Object.keys(obj[0]).forEach((element) =>
|
||||
{ $('#' + element + '_value').text(obj[0][element]); });
|
||||
$('#lx').text(obj[1]);
|
||||
$('#uva').text(obj[2][0]);
|
||||
$('#uvb').text(obj[2][1]);
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,98 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
<link rel="stylesheet" href="static/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="static/stylesheet.css">
|
||||
<title>TeraHz</title>
|
||||
<!-- script imports -->
|
||||
<script src="static/bootstrap.bundle.min.js"></script>
|
||||
<script src="static/jquery-3.4.1.min.js"></script>
|
||||
<script src="static/flot/jquery.flot.js"></script>
|
||||
<script src="static/frontend.js"></script>
|
||||
<script src="static/flot/jquery.canvaswrapper.js"></script>
|
||||
<script src="static/flot/jquery.colorhelpers.js"></script>
|
||||
<script src="static/flot/jquery.flot.js"></script>
|
||||
<script src="static/flot/jquery.flot.saturated.js"></script>
|
||||
<script src="static/flot/jquery.flot.browser.js"></script>
|
||||
<script src="static/flot/jquery.flot.drawSeries.js"></script>
|
||||
<script src="static/flot/jquery.flot.uiConstants.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container text-center">
|
||||
<h1><img src="static/logo-sq.png" height="64px">TeraHz</h1>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<button id="update" onclick="updateData()" class="btn btn-primary">Get data</button>
|
||||
<button id="download" class="btn btn-primary">Download</button>
|
||||
<button id="debug" class="btn btn-danger">DEBUG</button>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<h4>Spectrogram</h4>
|
||||
<div id="graph" style="height:480px;width:720px"></div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
<h4>Visible+IR spectrum</h4>
|
||||
<table class="table table-dark table-sm" id="specter">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Band</th>
|
||||
<th>Wavelength [nm]</th>
|
||||
<th>Irradiance [μW/cm²]</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for band, irr in data[0] %}
|
||||
<tr id="{{band}}">
|
||||
<td>
|
||||
{{band}}
|
||||
</td>
|
||||
<td>
|
||||
{{wld[band]}}
|
||||
</td>
|
||||
<td id="{{band}}_value">
|
||||
{{irr}}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="col-sm">
|
||||
<h4>UV+Illuminance</h4>
|
||||
<table class="table-dark table table-sm" id="luxuv">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td>Illuminance [lx]</td>
|
||||
<td id="lx">{{data[1]}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UVA irradiance [μW/cm²]</td>
|
||||
<td id="uva">{{data[2][0]}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UVB irradiance [μW/cm²]</td>
|
||||
<td id="uvb">{{data[2][1]}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>UVA/UVB average [μW/cm²]</td>
|
||||
<td id="uvi">{{data[2][2]}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,6 +1,6 @@
|
||||
# sensors.py - a module for interfacing to the sensors
|
||||
# terahz.py - a module for interfacing to the sensors
|
||||
'''Module for interfacing with TeraHz sensors'''
|
||||
# Copyright 2019 Kristjan Komloši
|
||||
# Copyright 2019, 2020 Kristjan Komloši
|
||||
# All code in this file is licensed under the ISC license, provided in LICENSE.txt
|
||||
import serial as ser
|
||||
import pandas as pd
|
||||
@@ -8,6 +8,7 @@ import smbus2
|
||||
|
||||
class Spectrometer:
|
||||
'''Class representing the AS7265X specrometer'''
|
||||
|
||||
def initializeSensor(self):
|
||||
'''confirm the sensor is responding and proceed\
|
||||
with spectrometer initialization'''
|
||||
@@ -23,8 +24,7 @@ class Spectrometer:
|
||||
if rstring == 'ERROR':
|
||||
raise Exception # sensor is in error state
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception ocurred when performing spectrometer handshake')
|
||||
raise Exception('No AT command response')
|
||||
|
||||
def setParameters(self, parameters):
|
||||
'''applies the parameters like LED light and gain to the spectrometer'''
|
||||
@@ -53,8 +53,7 @@ class Spectrometer:
|
||||
self.serialObject.write('ATLED3={}\n'.format(led).encode())
|
||||
self.serialObject.readline()
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occured during spectrometer initialization')
|
||||
raise Exception('Error setting spectrometer parameters')
|
||||
|
||||
def getData(self):
|
||||
'''Returns spectral data in a pandas DataFrame.'''
|
||||
@@ -62,8 +61,7 @@ class Spectrometer:
|
||||
self.serialObject.write(b'ATCDATA\n')
|
||||
rawresp = self.serialObject.readline().decode()
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occurred when polling for spectrometer data')
|
||||
raise Exception('Error polling spectrometer data')
|
||||
else:
|
||||
responseorder = list('RSTUVWGHIJKLABCDEF')
|
||||
realorder = list('ABCDEFGHRISJTUVWKL')
|
||||
@@ -78,14 +76,14 @@ class Spectrometer:
|
||||
try:
|
||||
self.serialObject = ser.Serial(path, baudrate, timeout=tout)
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occured when opening the serial port at {}'.format(path))
|
||||
raise Exception('Error opening serial port: {}'.format(path))
|
||||
else:
|
||||
self.initializeSensor()
|
||||
|
||||
|
||||
class LxMeter:
|
||||
'''Class representing the APDS-9301 digital photometer.'''
|
||||
|
||||
def __init__(self, busNumber=1, addr=0x39):
|
||||
self.addr = addr
|
||||
try:
|
||||
@@ -93,14 +91,14 @@ class LxMeter:
|
||||
self.bus = smbus2.SMBus(busNumber)
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occured opening the SMBus {}'.format(self.bus))
|
||||
'Error opening SMBus {}'.format(self.bus))
|
||||
|
||||
try:
|
||||
self.bus.write_byte_data(
|
||||
self.addr, 0xa0, 0x03) # enable the sensor
|
||||
self.setGain(16)
|
||||
except:
|
||||
raise Exception('An exception occured when enabling lux meter')
|
||||
raise Exception('Error enabling lux meter')
|
||||
|
||||
def setGain(self, gain):
|
||||
'''Set the sensor gain. Either 1 or 16.'''
|
||||
@@ -109,15 +107,13 @@ class LxMeter:
|
||||
temp = self.bus.read_byte_data(self.addr, 0xa1)
|
||||
self.bus.write_byte_data(self.addr, 0xa1, 0xef & temp)
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occured when setting lux meter gain')
|
||||
raise Exception('Error setting lux meter gain')
|
||||
if gain == 16:
|
||||
try:
|
||||
temp = self.bus.read_byte_data(self.addr, 0xa1)
|
||||
self.bus.write_byte_data(self.addr, 0xa1, 0x10 | temp)
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occured when setting lux meter gain')
|
||||
raise Exception('Error setting lux meter gain')
|
||||
else:
|
||||
raise Exception('Invalid gain')
|
||||
|
||||
@@ -176,6 +172,7 @@ class LxMeter:
|
||||
|
||||
class UVSensor:
|
||||
'''Class representing VEML6075 UVA/B meter'''
|
||||
|
||||
def __init__(self, bus=1, addr=0x10):
|
||||
self.addr = addr
|
||||
try:
|
||||
@@ -191,11 +188,12 @@ class UVSensor:
|
||||
# trigger a measurement to prevent bus errors at first read
|
||||
self.bus.write_byte_data(self.addr, 0x00, 0b00010010) # UV_AF=1
|
||||
self.bus.write_byte_data(self.addr, 0x00, 0b00010110) # UV_TRIG=1
|
||||
self.bus.write_byte_data(self.addr, 0x00, 0b00010000) # normal mode
|
||||
self.bus.write_byte_data(
|
||||
self.addr, 0x00, 0b00010000) # normal mode
|
||||
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occured when initalizing the UV Sensor')
|
||||
'Error initalizing the UV Sensor')
|
||||
|
||||
def getABI(self):
|
||||
'''Calculates the UVA and UVB irradiances,
|
||||
@@ -208,7 +206,7 @@ class UVSensor:
|
||||
c1 = self.bus.read_word_data(self.addr, 0x0a)
|
||||
c2 = self.bus.read_word_data(self.addr, 0x0b)
|
||||
except:
|
||||
raise Exception('An exception occured when fetching raw UV data')
|
||||
raise Exception('Error fetching raw UV data')
|
||||
# Refer to Vishay app note 84339 and Sparkfun VEML6075 documentation.
|
||||
# The computed values may be negative if UV is vastly weaker than
|
||||
# visible and IR light. This is not a bug!
|
||||
@@ -226,7 +224,7 @@ class UVSensor:
|
||||
self.bus.write_byte_data(self.addr, 0x00, 0x10)
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occured when turning the UV sensor on')
|
||||
'Error turning the UV sensor on')
|
||||
|
||||
def off(self):
|
||||
'''Shuts the UV sensor down.'''
|
||||
@@ -236,4 +234,4 @@ class UVSensor:
|
||||
self.bus.write_byte_data(self.addr, 0x00, 0x11)
|
||||
except:
|
||||
raise Exception(
|
||||
'An exception occured when shutting the UV sensor down')
|
||||
'Error shutting the UV sensor down')
|
||||
@@ -1,45 +0,0 @@
|
||||
# getcdata.py - fetch the calibrated data from the AS7265x module
|
||||
# All code in this file is licensed under the ISC license, provided in LICENSE.txt
|
||||
|
||||
import serial as ser
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
import time
|
||||
#global variables
|
||||
uartpath = '/dev/ttyUSB0'
|
||||
uartbaud = 115200
|
||||
uarttout = 5
|
||||
|
||||
wl = [410, 435, 460, 485, 510, 535, 560, 585, 610, 645, 680, 705, 730, 760, 810, 860, 900, 940]
|
||||
responseorder = [i for i in 'RSTUVWGHIJKLABCDEF'] # works, do NOT touch!
|
||||
realorder = [i for i in 'ABCDEFGHRISJTUVWKL']
|
||||
|
||||
|
||||
print('getcdata')
|
||||
print('This utility is part of the TeraHz project')
|
||||
|
||||
wavelens = pd.Series(realorder)
|
||||
|
||||
|
||||
plt.ion()
|
||||
win = plt.figure()
|
||||
spectrum=win.add_subplot(111)
|
||||
|
||||
|
||||
with ser.Serial(uartpath, uartbaud, timeout=uarttout) as sensor:
|
||||
while True:
|
||||
sensor.write(b'ATCDATA\n')
|
||||
rawresp = sensor.readline().decode()
|
||||
# parses, calculates and saves the data
|
||||
response = pd.Series([float(i)/35.0 for i in rawresp[:-3].split(',')], index=responseorder)
|
||||
data = pd.DataFrame(response, index=realorder, columns = ['uW/cm^2']) # puts data into a DataFrame
|
||||
data.insert(0, 'wavelenght', wl) #inserts a legend
|
||||
print(data)
|
||||
spectrum.cla()
|
||||
spectrum.plot(data['wavelenght'], data['uW/cm^2'])
|
||||
spectrum.set_xlabel('Valovna dolžina')
|
||||
spectrum.set_ylabel('uW/cm2')
|
||||
win.canvas.draw()
|
||||
|
||||
time.sleep(0.1)
|
||||
@@ -1,12 +0,0 @@
|
||||
import smbus2
|
||||
|
||||
bus = smbus2.SMBus(1)
|
||||
|
||||
result = bus.read_byte_data(0x39, 0x8a)
|
||||
print('LUX Meter ID = {}'.format(result))
|
||||
|
||||
result = bus.read_word_data(0x10, 0x0c)
|
||||
print('UV sensor ID = {}'.format(result))
|
||||
|
||||
result = bus.read_word_data(0x39, 0xec)
|
||||
print('LUX chan 0 = {}'.format(result))
|
||||
@@ -1,22 +0,0 @@
|
||||
from serial import Serial
|
||||
import tkinter as tk
|
||||
import pandas as pd
|
||||
|
||||
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
|
||||
from matplotlib.backend_bases import key_press_handler
|
||||
from matplotlib.figure import Figure
|
||||
|
||||
uartpath = '/dev/ttyUSB0'
|
||||
uartbaud = 115200
|
||||
uarttout = 5
|
||||
|
||||
wl = [410, 435, 460, 485, 510, 535, 560, 585, 610, 645, 680, 705, 730, 760, 810, 860, 900, 940]
|
||||
responseorder = [i for i in 'RSTUVWGHIJKLABCDEF'] # works, do NOT touch!
|
||||
realorder = [i for i in 'ABCDEFGHRISJTUVWKL']
|
||||
|
||||
root = tk.Tk()
|
||||
root.wm_title('TeraHz Demo')
|
||||
|
||||
fig = Figure(figsize=(5, 4), dpi=100)
|
||||
plot = fig.add_subplot(111)
|
||||
canvas = FigureCanvasTkAgg(fig, master=root)
|
||||
Reference in new issue
Block a user