Set new Base version
commit
4e95570fbc
|
@ -0,0 +1,79 @@
|
||||||
|
# Created by .ignore support plugin (hsz.mobi)
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
share/python-wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
MANIFEST
|
||||||
|
*.manifest
|
||||||
|
*.spec
|
||||||
|
pip-log.txt
|
||||||
|
pip-delete-this-directory.txt
|
||||||
|
htmlcov/
|
||||||
|
.tox/
|
||||||
|
.nox/
|
||||||
|
.coverage
|
||||||
|
.coverage.*
|
||||||
|
.cache
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
*.cover
|
||||||
|
*.py,cover
|
||||||
|
.hypothesis/
|
||||||
|
.pytest_cache/
|
||||||
|
cover/
|
||||||
|
*.mo
|
||||||
|
*.pot
|
||||||
|
*.log
|
||||||
|
local_settings.py
|
||||||
|
db.sqlite3
|
||||||
|
db.sqlite3-journal
|
||||||
|
instance/
|
||||||
|
.webassets-cache
|
||||||
|
.scrapy
|
||||||
|
docs/_build/
|
||||||
|
.pybuilder/
|
||||||
|
target/
|
||||||
|
.ipynb_checkpoints
|
||||||
|
profile_default/
|
||||||
|
ipython_config.py
|
||||||
|
__pypackages__/
|
||||||
|
celerybeat-schedule
|
||||||
|
celerybeat.pid
|
||||||
|
*.sage.py
|
||||||
|
.env
|
||||||
|
.venv
|
||||||
|
env/
|
||||||
|
venv/
|
||||||
|
ENV/
|
||||||
|
env.bak/
|
||||||
|
venv.bak/
|
||||||
|
.spyderproject
|
||||||
|
.spyproject
|
||||||
|
.ropeproject
|
||||||
|
/site
|
||||||
|
.mypy_cache/
|
||||||
|
.dmypy.json
|
||||||
|
dmypy.json
|
||||||
|
.pyre/
|
||||||
|
.pytype/
|
||||||
|
cython_debug/
|
||||||
|
/src/config.ini
|
||||||
|
/.idea/
|
||||||
|
/venv/
|
|
@ -0,0 +1,9 @@
|
||||||
|
FROM python:3-alpine
|
||||||
|
|
||||||
|
COPY . /code/
|
||||||
|
|
||||||
|
RUN pip install -r /code/requirements.txt
|
||||||
|
|
||||||
|
WORKDIR /code/src/
|
||||||
|
|
||||||
|
CMD ["python","app.py"]
|
|
@ -0,0 +1,62 @@
|
||||||
|
# PiSwitch_Reporting
|
||||||
|
reporting server/API for the [PiSwitch](https://git.dennisvandermeulen.nl/dennis/PiSwitch)
|
||||||
|
|
||||||
|
## Installation Process
|
||||||
|
|
||||||
|
Clone the repository
|
||||||
|
```shell
|
||||||
|
git clone https://git.dennisvandermeulen.nl/dennis/PiSwitch_reporting.git
|
||||||
|
cd PiSwitch_reporting/
|
||||||
|
```
|
||||||
|
Setup virtual environment & install requirements (skip if you use Docker)
|
||||||
|
```shell
|
||||||
|
python3 -m venv venv
|
||||||
|
source venv/bin/activate
|
||||||
|
pip3 install -r requirements.txt
|
||||||
|
```
|
||||||
|
Setup config.ini
|
||||||
|
```shell
|
||||||
|
nano src/config.ini
|
||||||
|
```
|
||||||
|
setup database config
|
||||||
|
```ini
|
||||||
|
[database]
|
||||||
|
host =
|
||||||
|
user =
|
||||||
|
password =
|
||||||
|
db =
|
||||||
|
```
|
||||||
|
setup apikey for this server
|
||||||
|
```ini
|
||||||
|
[setup]
|
||||||
|
apikey = string
|
||||||
|
````
|
||||||
|
##Docker
|
||||||
|
use the included Dockerfile
|
||||||
|
```shell
|
||||||
|
docker run . -t piswitch/reporting -d -p 5000:5000
|
||||||
|
```
|
||||||
|
or build the dockerfile for use with [PiSwitch_frontend](https://git.dennisvandermeulen.nl/dennis/PiSwitch_frontend)
|
||||||
|
```shell
|
||||||
|
docker build . -t piswitch/reporting
|
||||||
|
```
|
||||||
|
|
||||||
|
## Systemd
|
||||||
|
Use the following script to automatically start the scripts at boot
|
||||||
|
|
||||||
|
````ini
|
||||||
|
[Unit]
|
||||||
|
Description=PiSwitch Reporting server
|
||||||
|
After=multi-user.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=
|
||||||
|
Group=
|
||||||
|
WorkingDirectory=/path/to/PiSwitch_reporting/src
|
||||||
|
ExecStart=/path/to/venv/bin/python3 path/to/PiSwitch_reporting/src/server.py
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
````
|
||||||
|
save as PiSwitch_reporting.service
|
|
@ -0,0 +1,13 @@
|
||||||
|
astral==2.2
|
||||||
|
click==7.1.2
|
||||||
|
configparser==5.0.0
|
||||||
|
Flask==1.1.2
|
||||||
|
Flask-Cors==3.0.9
|
||||||
|
itsdangerous==1.1.0
|
||||||
|
Jinja2==2.11.2
|
||||||
|
MarkupSafe==1.1.1
|
||||||
|
mysql-connector-python==8.0.23
|
||||||
|
protobuf==3.15.6
|
||||||
|
pytz==2020.1
|
||||||
|
six==1.15.0
|
||||||
|
Werkzeug==1.0.1
|
|
@ -0,0 +1,98 @@
|
||||||
|
from flask import Flask, request, jsonify
|
||||||
|
from flask_cors import CORS
|
||||||
|
import configparser
|
||||||
|
from helper import storecmd, getcmd, updatestatus, getstatus, getalldata, updatelocation, getdbtime, datelookup
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
|
|
||||||
|
def verifyapikey(requestapikey):
|
||||||
|
if requestapikey == apiKey:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/cmd', methods=['POST', 'GET'])
|
||||||
|
def command():
|
||||||
|
if verifyapikey(request.values.get('apikey')):
|
||||||
|
if request.method == 'POST':
|
||||||
|
storecmd(request.values.get('id'), datetime.datetime.now(), request.values.get('response'))
|
||||||
|
return jsonify(response='success'), 200
|
||||||
|
else:
|
||||||
|
results = getcmd(request.values.get('id'))
|
||||||
|
x = 0
|
||||||
|
response = {}
|
||||||
|
for i in results:
|
||||||
|
response[x] = {'date': i[0], 'command': i[1]}
|
||||||
|
x = x + 1
|
||||||
|
return response, 200
|
||||||
|
return jsonify(response='invalid api key'), 401
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/status', methods=['POST', 'GET'])
|
||||||
|
def status():
|
||||||
|
if verifyapikey(request.values.get('apikey')):
|
||||||
|
if request.method == 'POST':
|
||||||
|
updatestatus(request.values.get('id'), datetime.datetime.now(), request.values.get('key'),
|
||||||
|
request.values.get('value'))
|
||||||
|
return jsonify(response='success'), 200
|
||||||
|
else:
|
||||||
|
result = getstatus(request.values.get('id'), request.values.get('key'))
|
||||||
|
return jsonify(response=result[0]), 200
|
||||||
|
return jsonify(response='invalid api key'), 401
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/gettime', methods=['POST'])
|
||||||
|
def gettime():
|
||||||
|
if verifyapikey(request.values.get('apikey')):
|
||||||
|
result = getdbtime(request.values.get('id'), request.values.get('key'))
|
||||||
|
return jsonify(response=str(result[0])), 200
|
||||||
|
return jsonify(response='invalid api key'), 401
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/fullstatus', methods=['POST'])
|
||||||
|
def fullstatus():
|
||||||
|
if verifyapikey(request.values.get('apikey')):
|
||||||
|
result = getalldata(request.values.get('id'))
|
||||||
|
return {'switch_name': result[1],
|
||||||
|
'switch_status': result[3],
|
||||||
|
'astral_status': result[4],
|
||||||
|
'conn_status': result[5],
|
||||||
|
'last_updated': result[2],
|
||||||
|
'on_time': str(result[6]),
|
||||||
|
'off_time': str(result[7]),
|
||||||
|
'loc_name': result[8],
|
||||||
|
'loc_region': result[9],
|
||||||
|
'loc_lat': result[10],
|
||||||
|
'loc_lon': result[11],
|
||||||
|
'loc_timezone': result[12],
|
||||||
|
'apikey': result[13]
|
||||||
|
}, 200
|
||||||
|
return jsonify(response='invalid api key'), 401
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/updatelocation', methods=['POST'])
|
||||||
|
def updateloc():
|
||||||
|
if verifyapikey(request.values.get('apikey')):
|
||||||
|
updatelocation(request.values.get('id'), datetime.datetime.now(), request.values.get('loc_name'),
|
||||||
|
request.values.get('loc_region'), request.values.get('loc_lat'), request.values.get('loc_lon'))
|
||||||
|
return jsonify(response='success'), 200
|
||||||
|
return jsonify(response='invalid api key'), 401
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/datelookup', methods=['POST'])
|
||||||
|
def lookupdate():
|
||||||
|
if verifyapikey(request.values.get('apikey')):
|
||||||
|
result = datelookup(request.values.get('id'),
|
||||||
|
request.values.get('day'), request.values.get('month'), request.values.get('year'))
|
||||||
|
return jsonify(response=result), 200
|
||||||
|
return jsonify(response='invalid api key'), 401
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read('config.ini')
|
||||||
|
apiKey = config['setup']['apikey']
|
||||||
|
app.run(host='0.0.0.0')
|
|
@ -0,0 +1,93 @@
|
||||||
|
import mysql.connector
|
||||||
|
import configparser
|
||||||
|
import astral
|
||||||
|
import astral.sun
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
config = configparser.ConfigParser()
|
||||||
|
config.read('config.ini')
|
||||||
|
host = config['database']['host']
|
||||||
|
user = config['database']['user']
|
||||||
|
password = config['database']['password']
|
||||||
|
db = config['database']['db']
|
||||||
|
|
||||||
|
|
||||||
|
def storecmd(device_id, date_time, command):
|
||||||
|
dwh = mysql.connector.connect(host=host,user=user,password=password,database=db)
|
||||||
|
c = dwh.cursor()
|
||||||
|
c.execute("""INSERT INTO commands(device_id,date_time,command) VALUES(%s,%s,%s)""", (device_id, date_time, command))
|
||||||
|
dwh.commit()
|
||||||
|
c.close()
|
||||||
|
|
||||||
|
|
||||||
|
def getcmd(device_id):
|
||||||
|
dwh = mysql.connector.connect(host=host,user=user,password=password,database=db)
|
||||||
|
c = dwh.cursor()
|
||||||
|
c.execute("""SELECT date_time, command FROM commands WHERE device_id = %s ORDER BY date_time DESC LIMIT 10 """,
|
||||||
|
(device_id,))
|
||||||
|
result = c.fetchmany(10)
|
||||||
|
c.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def updatestatus(device_id, date_time, key, value):
|
||||||
|
if key in ['device_id', 'name', 'last_updated', 'switch_status', 'astral_status', 'conn_status', 'on_time',
|
||||||
|
'off_time', 'loc_name', 'loc_region', 'loc_lat', 'loc_lon', 'loc_timezone', 'apikey']:
|
||||||
|
dwh = mysql.connector.connect(host=host,user=user,password=password,database=db)
|
||||||
|
c = dwh.cursor()
|
||||||
|
c.execute("""UPDATE status SET last_updated = %s, {} = %s WHERE device_id = %s""".format(key),
|
||||||
|
(date_time, value, device_id))
|
||||||
|
dwh.commit()
|
||||||
|
c.close()
|
||||||
|
|
||||||
|
|
||||||
|
def getstatus(device_id, key):
|
||||||
|
dwh = mysql.connector.connect(host=host,user=user,password=password,database=db)
|
||||||
|
c = dwh.cursor()
|
||||||
|
c.execute("""SELECT {} FROM status WHERE device_id = %s""".format(key), ([device_id]))
|
||||||
|
result = c.fetchone()
|
||||||
|
c.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def getalldata(device_id):
|
||||||
|
dwh = mysql.connector.connect(host=host,user=user,password=password,database=db)
|
||||||
|
c = dwh.cursor()
|
||||||
|
c.execute("""SELECT * FROM status WHERE device_id = %s""", ([device_id]))
|
||||||
|
result = c.fetchone()
|
||||||
|
c.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def updatelocation(device_id, date_time, loc_name, loc_region, loc_lat, loc_lon):
|
||||||
|
dwh = mysql.connector.connect(host=host,user=user,password=password,database=db)
|
||||||
|
c = dwh.cursor()
|
||||||
|
c.execute(
|
||||||
|
"""UPDATE status SET last_updated = %s, loc_name = %s, loc_region = %s, loc_lat = %s, loc_lon = %s WHERE device_id = %s""",
|
||||||
|
(date_time, loc_name, loc_region, loc_lat, loc_lon, device_id))
|
||||||
|
dwh.commit()
|
||||||
|
c.close()
|
||||||
|
|
||||||
|
|
||||||
|
def getdbtime(device_id, key):
|
||||||
|
if key in ['device_id', 'name', 'last_updated', 'switch_status', 'astral_status', 'conn_status', 'on_time',
|
||||||
|
'off_time', 'loc_name', 'loc_region', 'loc_lat', 'loc_lon', 'loc_timezone', 'apikey']:
|
||||||
|
dwh = mysql.connector.connect(host=host,user=user,password=password,database=db)
|
||||||
|
c = dwh.cursor()
|
||||||
|
c.execute("""SELECT {} FROM status WHERE device_id = %s""".format(key), ([device_id]))
|
||||||
|
result = c.fetchone()
|
||||||
|
c.close()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def datelookup(device_id, day, month, year):
|
||||||
|
dwh = mysql.connector.connect(host=host,user=user,password=password,database=db)
|
||||||
|
c = dwh.cursor()
|
||||||
|
c.execute("""SELECT loc_name, loc_region, loc_lat, loc_lon, loc_timezone FROM status WHERE device_id = %s""",
|
||||||
|
(device_id,))
|
||||||
|
result = c.fetchone()
|
||||||
|
c.close()
|
||||||
|
l = astral.LocationInfo(name=result[0], region=result[1], latitude=result[2], longitude=result[3],
|
||||||
|
timezone=result[4])
|
||||||
|
triggerontime = astral.sun.sunset(observer=l.observer, date=datetime.date(day, month, year))
|
||||||
|
return triggerontime
|
Loading…
Reference in New Issue