diff --git a/.gitignore b/.gitignore index e8877de..97fd1f5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ node_modules/ *.db* *.log .eslintrc.* +.env requirements-dev.txt tilix.json diff --git a/NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino b/NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino index 9187321..0a39c25 100644 --- a/NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino +++ b/NodeMCU/AdvancedWS_Node/AdvancedWS_Node.ino @@ -23,10 +23,14 @@ DHT dht(DHTPin, DHTTYPE); WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL); -const char *host = "192.168.0.106"; -const int led = D7; +const char *host = "192.168.0.106"; +const int httpPort = 5000; +const int led = D7; + +int estacao = 1; +String versao = "1.2"; +String token = ""; -int estacao = 1; int ldrPin = A0; int tmp = 80; int ldrValor = 0; @@ -110,12 +114,14 @@ void EncontraValor(String str1, String str2, String str3, int inicio, int fim, i if (str2 == "Pressao") { pos = str1.indexOf("Pressao", 0); Serial.println(pos); - if (pos > 0) + if (pos > 0) { str1 = str1.substring(pos); + Serial.println(str1); + } else if (pos == 0) { temp = str1.substring(1); pos = temp.indexOf("Pressao", 0); - if (pos >= 0) { + if (pos > 0) { Serial.println(pos); str1 = temp.substring(pos); } @@ -140,7 +146,6 @@ void EncontraValor(String str1, String str2, String str3, int inicio, int fim, i void EnviaDados(float valor, String tipo, int estacao) { WiFiClient client; - const int httpPort = 5000; timeClient.update(); if (!client.connect(host, httpPort)) { @@ -151,17 +156,32 @@ void EnviaDados(float valor, String tipo, int estacao) { String formattedTime = timeClient.getFormattedTime(); unsigned long epcohTime = timeClient.getEpochTime(); - data = "{\"valor\": " + String(valor) + ", \"datahora\": " + String(epcohTime) + "}"; - - client.println("POST /api/v1.1/sensor/" + String(estacao) + "/" + tipo + " HTTP/1.1"); + data = "{\"valor\": " + String(valor) + ", \"datahora\": " + String(epcohTime) + "}"; +/* + json= + { + "valor": 304.00, + "datahora": 1607109786 + }, + headers= + { + "Authorization": "jwt eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MDcxOTI0NzUsImlhdCI6MTYwNzEwNjA3NSwibmJmIjoxNjA3MTA2MDc1LCJpZGVudGl0eSI6MX0.gpFQ_KaX0DFd3ps8VHK7E5ly5L0doueUSbaYptgQVHI" + } +*/ + client.println("POST /api/v" + versao + "/sensor/" + String(estacao) + "/" + tipo + " HTTP/1.1"); client.print("Host: "); client.println(host); client.println("Accept: */*"); client.println("Content-Type: application/json"); + client.print("Authorization: "); + client.println(token); client.print("Content-Length: "); client.println(data.length()); + client.println(); client.print(data); + + Serial.println(token); Serial.println(data); delay(20); // Can be changed @@ -171,6 +191,43 @@ void EnviaDados(float valor, String tipo, int estacao) { delay(20); } +String RecebeToken() { + WiFiClient client; + String line, token2; + + if (!client.connect(host, httpPort)) { + Serial.println("connection failed"); + return "Erro ao conectar"; + } + + data = "{\"email\": \"admin@gmail.com\", \"password\": \"12345678\"}"; + + client.println("POST /token HTTP/1.1"); + client.print("Host: "); + client.println(host); + client.println("Accept: */*"); + client.println("Content-Type: application/json"); + client.print("Content-Length: "); + client.println(data.length()); + client.println(); + client.print(data); + + delay(20); // Can be changed + while (client.connected()) { + if (client.available()) { + line = client.readStringUntil('\n'); + if (line.indexOf("HTTP", 0) > 0) { + Serial.print("[Response:]"); + Serial.println(line.substring(0, 15)); + } + if (line.indexOf("access_token", 0) > 0) + token2 = "\"jwt " + line.substring(line.indexOf("access_token", 0)+16); + } + } + delay(20); + return token2; +} + void setup() { Serial.begin(115200); @@ -188,6 +245,10 @@ void setup() { dht.begin(); + token = RecebeToken(); + Serial.print("Token: "); + Serial.println(token); + digitalWrite(led, HIGH); delay(100); digitalWrite(led, LOW); diff --git a/prototipo/Vagrant-setup/bootstrap.sh b/Vagrant-setup/bootstrap.sh similarity index 100% rename from prototipo/Vagrant-setup/bootstrap.sh rename to Vagrant-setup/bootstrap.sh diff --git a/prototipo/Vagrantfile b/Vagrantfile similarity index 89% rename from prototipo/Vagrantfile rename to Vagrantfile index 57d16cd..ea20441 100644 --- a/prototipo/Vagrantfile +++ b/Vagrantfile @@ -13,12 +13,12 @@ Vagrant.configure("2") do |config| # config.vm.network "private_network", ip: "192.168.33.10" config.vm.network "public_network" - config.vm.synced_folder "./", "/vagrant_data" + config.vm.synced_folder "./prototipo", "/vagrant_data" config.vm.provider "virtualbox" do |vb| vb.name = "focal64_flaskAPI" vb.gui = false - vb.memory = "2048" + vb.memory = "1024" end config.vm.provision :shell, :path => "Vagrant-setup/bootstrap.sh" diff --git a/prototipo/package-lock.json b/package-lock.json similarity index 100% rename from prototipo/package-lock.json rename to package-lock.json diff --git a/prototipo/package.json b/package.json similarity index 100% rename from prototipo/package.json rename to package.json diff --git a/prototipo/migrations/env.py b/prototipo/migrations/env.py index 9452179..f01d2e8 100644 --- a/prototipo/migrations/env.py +++ b/prototipo/migrations/env.py @@ -3,10 +3,8 @@ import logging from logging.config import fileConfig -from sqlalchemy import engine_from_config -from sqlalchemy import pool - from alembic import context +from sqlalchemy import engine_from_config, pool # this is the Alembic Config object, which provides # access to the values within the .ini file in use. @@ -22,6 +20,7 @@ # from myapp import mymodel # target_metadata = mymodel.Base.metadata from flask import current_app + config.set_main_option( 'sqlalchemy.url', str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%')) diff --git a/prototipo/migrations/versions/175235720f56_.py b/prototipo/migrations/versions/175235720f56_.py new file mode 100644 index 0000000..d2f090d --- /dev/null +++ b/prototipo/migrations/versions/175235720f56_.py @@ -0,0 +1,29 @@ +"""empty message + +Revision ID: 175235720f56 +Revises: 61fd7b1a6054 +Create Date: 2020-12-14 13:59:25.369944 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = '175235720f56' +down_revision = '61fd7b1a6054' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('estacao', sa.Column('created_on', sa.DateTime(), nullable=True)) + op.add_column('estacao', sa.Column('updated_on', sa.DateTime(), nullable=True)) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column('estacao', 'updated_on') + op.drop_column('estacao', 'created_on') + # ### end Alembic commands ### diff --git a/prototipo/migrations/versions/3eeb4ae85a13_.py b/prototipo/migrations/versions/3eeb4ae85a13_.py index b74260f..e35deb1 100644 --- a/prototipo/migrations/versions/3eeb4ae85a13_.py +++ b/prototipo/migrations/versions/3eeb4ae85a13_.py @@ -5,9 +5,8 @@ Create Date: 2020-11-16 16:11:48.278616 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '3eeb4ae85a13' diff --git a/prototipo/migrations/versions/61fd7b1a6054_.py b/prototipo/migrations/versions/61fd7b1a6054_.py index b2ea39c..139d2fd 100644 --- a/prototipo/migrations/versions/61fd7b1a6054_.py +++ b/prototipo/migrations/versions/61fd7b1a6054_.py @@ -5,9 +5,8 @@ Create Date: 2020-11-30 14:31:27.250926 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '61fd7b1a6054' diff --git a/prototipo/migrations/versions/8384895bb7ff_initial_migration.py b/prototipo/migrations/versions/8384895bb7ff_initial_migration.py index 705374e..a319e85 100644 --- a/prototipo/migrations/versions/8384895bb7ff_initial_migration.py +++ b/prototipo/migrations/versions/8384895bb7ff_initial_migration.py @@ -5,9 +5,8 @@ Create Date: 2020-11-16 16:05:42.270171 """ -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision = '8384895bb7ff' diff --git a/prototipo/migrations/versions/bb88fe255549_.py b/prototipo/migrations/versions/bb88fe255549_.py new file mode 100644 index 0000000..0511b75 --- /dev/null +++ b/prototipo/migrations/versions/bb88fe255549_.py @@ -0,0 +1,44 @@ +"""empty message + +Revision ID: bb88fe255549 +Revises: 175235720f56 +Create Date: 2020-12-15 20:37:21.871157 + +""" +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision = 'bb88fe255549' +down_revision = '175235720f56' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('sensor_tipo', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('codigo', sa.String(length=255), nullable=False), + sa.Column('descricao', sa.String(length=255), nullable=False), + sa.Column('params', sa.String(length=255), nullable=False), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('codigo') + ) + op.add_column('sensor', sa.Column('tipo_id', sa.Integer(), nullable=False)) + op.create_foreign_key(None, 'sensor', 'sensor_tipo', ['tipo_id'], ['id']) + op.drop_column('sensor', 'tipo') + op.drop_column('sensor', 'params') + op.drop_column('sensor', 'descricao') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('sensor', sa.Column('descricao', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.add_column('sensor', sa.Column('params', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.add_column('sensor', sa.Column('tipo', sa.VARCHAR(length=255), autoincrement=False, nullable=False)) + op.drop_constraint(None, 'sensor', type_='foreignkey') + op.drop_column('sensor', 'tipo_id') + op.drop_table('sensor_tipo') + # ### end Alembic commands ### diff --git a/prototipo/projeto/app.py b/prototipo/projeto/app.py index be77085..40d490e 100644 --- a/prototipo/projeto/app.py +++ b/prototipo/projeto/app.py @@ -1,22 +1,12 @@ from datetime import timedelta from flask import Flask - from projeto.ext import admin, api, auth, db, jwt, site def create_app(): app = Flask(__name__) - - app.config[ - "SQLALCHEMY_DATABASE_URI"] = "postgresql://" + \ - "flaskapi:flaskapi@localhost:5432/flaskapi" - app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False - app.config["SECRET_KEY"] = "super-secret-key" - app.config["JWT_AUTH_USERNAME_KEY"] = "email" - app.config["JWT_AUTH_URL_RULE"] = "/token" - app.config["JWT_EXPIRATION_DELTA"] = timedelta(seconds=86400) # one day - app.config["FLASK_ADMIN_SWATCH"] = "sandstone" + app.config.from_object("projeto.config.DevConfig") db.init_app(app) api.init_app(app) diff --git a/prototipo/projeto/config.py b/prototipo/projeto/config.py new file mode 100644 index 0000000..bf91a46 --- /dev/null +++ b/prototipo/projeto/config.py @@ -0,0 +1,37 @@ +import os +from datetime import timedelta +from dotenv import load_dotenv + +basedir = os.path.abspath(os.path.dirname(__file__)) +load_dotenv(os.path.join(basedir, ".env"), verbose=True) + + +class BaseConfig: + """Base configs""" + + DEBUG = False + TESTING = False + SECRET_KEY = os.getenv("SECRET_KEY") + STATIC_FOLDER = "static" + TEMPLATE_FOLDER = "templates" + SQLALCHEMY_TRACK_MODIFICATIONS = False + JWT_AUTH_USERNAME_KEY = "email" + JWT_AUTH_URL_RULE = "/token" + JWT_EXPIRATION_DELTA = timedelta(seconds=86400) # one day + FLASK_ADMIN_SWATCH = "sandstone" + + +class ProdConfig(BaseConfig): + """Production configs""" + + FLASK_ENV = "production" + SQLALCHEMY_DATABASE_URI = os.getenv("PROD_DATABASE_URI") + + +class DevConfig(BaseConfig): + """Development configs""" + + FLASK_ENV = "development" + DEBUG = True + TESTING = True + SQLALCHEMY_DATABASE_URI = os.getenv("DEV_DATABASE_URI") diff --git a/prototipo/projeto/ext/admin/__init__.py b/prototipo/projeto/ext/admin/__init__.py index b9c38e3..02e68d0 100644 --- a/prototipo/projeto/ext/admin/__init__.py +++ b/prototipo/projeto/ext/admin/__init__.py @@ -1,6 +1,6 @@ from flask_admin import Admin -from projeto.ext.admin.views import EstacaoView, SensorView, UserView -from projeto.ext.api.models import Estacao, Sensor +from projeto.ext.admin.views import EstacaoView, SensorView, SensorTipoView, UserView +from projeto.ext.api.models import Estacao, Sensor, SensorTipo from projeto.ext.auth.models import UserAuth from projeto.ext.db import db @@ -12,6 +12,7 @@ def init_app(app): views = [ UserView(UserAuth, db.session), EstacaoView(Estacao, db.session), + SensorTipoView(SensorTipo, db.session), SensorView(Sensor, db.session), ] admin.add_views(*views) diff --git a/prototipo/projeto/ext/admin/views.py b/prototipo/projeto/ext/admin/views.py index 325d94d..1437a82 100644 --- a/prototipo/projeto/ext/admin/views.py +++ b/prototipo/projeto/ext/admin/views.py @@ -19,14 +19,25 @@ class UserView(AdminView): column_list = ("id", "email", "is_admin") column_sortable_list = () + can_create = True + can_delete = True + can_edit = False + class EstacaoView(AdminView): - column_list = ("id", "local", "latitude", "longitude") + column_list = ("id", "local", "latitude", "longitude", "created_on", + "updated_on") + form_excluded_columns = ("created_on", "updated_on") + column_sortable_list = () + + +class SensorTipoView(AdminView): + # column_list = ("id", "codigo", "descricao", "params") column_sortable_list = () class SensorView(AdminView): - column_list = ("id", "tipo", "descricao", "params", "estacao") + # column_list = ("id", "tipo", "estacao") column_sortable_list = () form_excluded_columns = [ diff --git a/prototipo/projeto/ext/api/__init__.py b/prototipo/projeto/ext/api/__init__.py index 583fe25..2282f3b 100644 --- a/prototipo/projeto/ext/api/__init__.py +++ b/prototipo/projeto/ext/api/__init__.py @@ -1,22 +1,21 @@ from flask_restful import Api - from projeto.ext.api.views import (ApiEstacao, ApiEstacaoId, ApiEstacaoIdSensor, ApiSensorId, ApiSensorIdParam, ApiSensorIdParamLast) api = Api() -versao = "v1.2" +VERSAO = "v1.2" -api.add_resource(ApiEstacao, f"/api/{versao}/estacao") -api.add_resource(ApiEstacaoId, f"/api/{versao}/estacao/") +api.add_resource(ApiEstacao, f"/api/{VERSAO}/estacao") +api.add_resource(ApiEstacaoId, f"/api/{VERSAO}/estacao/") api.add_resource(ApiEstacaoIdSensor, - f"/api/{versao}/estacao//sensor") -api.add_resource(ApiSensorId, f"/api/{versao}/sensor/") + f"/api/{VERSAO}/estacao//sensor") +api.add_resource(ApiSensorId, f"/api/{VERSAO}/sensor/") api.add_resource(ApiSensorIdParam, - f"/api/{versao}/sensor//") + f"/api/{VERSAO}/sensor//") api.add_resource( ApiSensorIdParamLast, - f"/api/{versao}/sensor///") + f"/api/{VERSAO}/sensor///") def init_app(app): diff --git a/prototipo/projeto/ext/api/models.py b/prototipo/projeto/ext/api/models.py index cca948c..328dddf 100644 --- a/prototipo/projeto/ext/api/models.py +++ b/prototipo/projeto/ext/api/models.py @@ -10,8 +10,13 @@ class Estacao(db.Model): local = db.Column("local", db.String(255), nullable=False) latitude = db.Column("latitude", db.String(255), nullable=False) longitude = db.Column("longitude", db.String(255), nullable=False) + created_on = db.Column("created_on", db.DateTime, default=datetime.now) + updated_on = db.Column("updated_on", + db.DateTime, + default=datetime.now, + onupdate=datetime.now) - def get_sensor(self, sensor_id): + def get_sensor(self, sensor_id: int): for sensor in self.sensores: if sensor.id == sensor_id: return sensor @@ -33,9 +38,15 @@ class Sensor(db.Model): __tablename__ = "sensor" id = db.Column("id", db.Integer, primary_key=True) - tipo = db.Column("tipo", db.String(255), nullable=False) - descricao = db.Column("descricao", db.String(255), nullable=False) - params = db.Column("params", db.String(255), nullable=False) + + tipo_id = db.Column("tipo_id", + db.Integer, + db.ForeignKey("sensor_tipo.id"), + nullable=False) + tipo = db.relationship("SensorTipo", + backref=db.backref("sensores", + cascade="all, delete-orphan", + lazy=True)) estacao_id = db.Column("estacao_id", db.Integer, @@ -49,14 +60,26 @@ class Sensor(db.Model): def json(self): return { "id": self.id, - "tipo": self.tipo, - "descricao": self.descricao, - "params": self.params, + "tipo": self.tipo.codigo, + "descricao": self.tipo.descricao, + "params": self.tipo.params, "estacao_id": self.estacao_id, } def __repr__(self): - return f"{self.tipo}" + return f"{self.tipo.codigo}" + + +class SensorTipo(db.Model): + __tablename__ = "sensor_tipo" + + id = db.Column("id", db.Integer, primary_key=True) + codigo = db.Column("codigo", db.String(255), nullable=False, unique=True) + descricao = db.Column("descricao", db.String(255), nullable=False) + params = db.Column("params", db.String(255), nullable=False) + + def __repr__(self): + return f"{self.codigo}" class Leitura(db.Model): diff --git a/prototipo/projeto/ext/api/views.py b/prototipo/projeto/ext/api/views.py index 2d2ee33..61420fe 100644 --- a/prototipo/projeto/ext/api/views.py +++ b/prototipo/projeto/ext/api/views.py @@ -1,13 +1,14 @@ +# from pprint import pprint from datetime import datetime +# from flask import request from flask_jwt import jwt_required from flask_restful import Resource, reqparse +from projeto.ext.api.models import Estacao, Leitura, Sensor from projeto.ext.db import db from sqlalchemy.exc import IntegrityError from sqlalchemy.orm.exc import UnmappedInstanceError -from projeto.ext.api.models import Estacao, Leitura, Sensor - HTTP_RESPONSE_CREATED = 201 HTTP_RESPONSE_NOT_FOUND = 404 @@ -199,6 +200,7 @@ def get(self, sensor_id, param): @jwt_required() def post(self, sensor_id, param): + # pprint(request.__dict__) parser = reqparse.RequestParser() parser.add_argument("valor", type=str, diff --git a/prototipo/projeto/ext/auth/__init__.py b/prototipo/projeto/ext/auth/__init__.py index 84f16ee..a4c7438 100644 --- a/prototipo/projeto/ext/auth/__init__.py +++ b/prototipo/projeto/ext/auth/__init__.py @@ -1,5 +1,4 @@ from flask_login import LoginManager - from projeto.ext.auth.models import UserAuth from projeto.ext.auth.views import bp diff --git a/prototipo/projeto/ext/auth/views.py b/prototipo/projeto/ext/auth/views.py index 5ae6f98..d224f8a 100644 --- a/prototipo/projeto/ext/auth/views.py +++ b/prototipo/projeto/ext/auth/views.py @@ -2,13 +2,12 @@ from flask_login import login_required, login_user, logout_user from flask_wtf import FlaskForm from passlib.hash import sha256_crypt +from projeto.ext.auth.models import UserAuth +from projeto.ext.db import db from wtforms import PasswordField from wtforms.fields.html5 import EmailField from wtforms.validators import DataRequired, Email, Length -from projeto.ext.auth.models import UserAuth -from projeto.ext.db import db - bp = Blueprint("auth", __name__) diff --git a/prototipo/projeto/ext/jwt.py b/prototipo/projeto/ext/jwt.py index b646ff1..94554b0 100644 --- a/prototipo/projeto/ext/jwt.py +++ b/prototipo/projeto/ext/jwt.py @@ -1,6 +1,5 @@ from flask_jwt import JWT from passlib.hash import sha256_crypt - from projeto.ext.auth.models import UserAuth diff --git a/prototipo/projeto/ext/site.py b/prototipo/projeto/ext/site.py index 9ec33f5..ad9f46c 100644 --- a/prototipo/projeto/ext/site.py +++ b/prototipo/projeto/ext/site.py @@ -1,6 +1,5 @@ from flask import Blueprint, render_template from flask_login import login_required - from projeto.ext.api.models import Estacao from projeto.ext.auth.models import UserAuth diff --git a/prototipo/projeto/static/visualizacoes.js b/prototipo/projeto/static/visualizacoes.js index 517568b..d61e08a 100644 --- a/prototipo/projeto/static/visualizacoes.js +++ b/prototipo/projeto/static/visualizacoes.js @@ -20,8 +20,8 @@ $(function () { const result = await fetch(`${URL_BASE}/estacao`); if (result.ok) { - const data = await result.json(); - return data.resources; + let data = await result.json(); + return data.resources.sort((a, b) => {return a.id > b.id}); } } @@ -34,7 +34,7 @@ $(function () { if (result.ok) { const data = await result.json(); - return data.resources; + return data.resources.sort((a, b) => {return a.id > b.id}); } } @@ -47,7 +47,7 @@ $(function () { if (result.ok) { const data = await result.json(); - return data.resource.params.split(","); + return data.resource.params.split(",").sort(); } } @@ -82,12 +82,12 @@ $(function () { function updateChart(serie, sensor_id, param) { fetch(`${URL_BASE}/sensor/${sensor_id}/${param}/1`) - .then(function(response) { + .then((response) => { let contentType = response.headers.get('content-type'); if (contentType && contentType.indexOf("application/json") !== -1) { return response.json() - .then(function(json) { + .then((json) => { // seconds (python) to milliseconds (js) let x = json.resources[0].datahora * 1000; let y = parseFloat(json.resources[0].valor); @@ -107,7 +107,7 @@ $(function () { if (estacoes) { $('#local-sel').empty(); - estacoes.forEach(function(estacao) { + estacoes.forEach((estacao) => { $('#local-sel') .append($('') .val(estacao.id) @@ -118,7 +118,7 @@ $(function () { if (sensores) { $('#sensor-sel').empty(); - sensores.forEach(function(sensor) { + sensores.forEach((sensor) => { $('#sensor-sel') .append($('') .val(sensor.id) @@ -129,7 +129,7 @@ $(function () { if (params) { $('#param-sel').empty(); - params.forEach(function(param) { + params.forEach((param) => { $('#param-sel') .append($('') .val(param) @@ -145,7 +145,7 @@ $(function () { * Inicializa o objeto Highcharts com os dados assícronos fornecidos * por requestData. */ - .then(function(data) { + .then((data) => { let chart = new Highcharts.chart('container', { chart: { @@ -153,7 +153,7 @@ $(function () { animation: Highcharts.svg, // don't animate in old IE marginRight: 10, events: { - load: function () { + load: function() { const selected = { estacao_id: data.estacoes[0].id, @@ -181,7 +181,7 @@ $(function () { selected.sensor_id = this.value; requestParams(selected.estacao_id, selected.sensor_id) - .then(function(params_new) { + .then((params_new) => { data.params = params_new; selected.param = data.params[0]; @@ -198,7 +198,7 @@ $(function () { selected.estacao_id = this.value; requestSensores(selected.estacao_id) - .then(function(sensores_new) { + .then((sensores_new) => { data.sensores = sensores_new; selected.sensor_id = data.sensores[0].id; @@ -214,7 +214,7 @@ $(function () { }); // set up the updating of the chart each second - setInterval(function () { + setInterval(() => { if (serie && selected.sensor_id && selected.param) { updateChart(serie, selected.sensor_id, selected.param); } @@ -236,7 +236,7 @@ $(function () { announceNewData: { enabled: true, minAnnounceInterval: 15000, - announcementFormatter: function (allSeries, newSeries, newPoint) { + announcementFormatter: (allSeries, newSeries, newPoint) => { if (newPoint) { return 'New point added. Value: ' + newPoint.y; } diff --git a/prototipo/requirements.txt b/prototipo/requirements.txt index a675aaf..7c581f2 100644 --- a/prototipo/requirements.txt +++ b/prototipo/requirements.txt @@ -12,4 +12,5 @@ passlib numpy requests psycopg2-binary +python-dotenv diff --git a/prototipo/sensor_sim.py b/prototipo/sensor_sim.py index e2fcd3d..3c4b687 100644 --- a/prototipo/sensor_sim.py +++ b/prototipo/sensor_sim.py @@ -4,8 +4,7 @@ import numpy as np import requests - -from projeto.ext.api.models import Estacao, Leitura, Sensor +from projeto.ext.api.models import Estacao, Leitura, Sensor, SensorTipo from projeto.ext.db import db MIN_VAR = -1 @@ -29,54 +28,64 @@ def create_all(): - estacoes = [ + estacoes = { + "ubatuba": Estacao(local="Ubatuba", latitude="-23.43389", longitude="-45.07111"), + "caragua": Estacao(local="Caraguatatuba", latitude="-23.62028", longitude="-45.41306"), + "cunha": Estacao(local="Cunha", latitude="-23.07444", longitude="-44.95972") - ] + } + + tipos = { + "dht11": + SensorTipo(codigo="DHT11", + descricao="Sensor temperatura e umidade", + params="temp_ambiente,umid_relativa"), + "ldr": + SensorTipo(codigo="LDR", + descricao="Sensor de luminosidade", + params="luminosidade"), + "ds18b20": + SensorTipo(codigo="DS18B20", + descricao="Sensor de temperatura digital", + params="temp_agua"), + "solo": + SensorTipo(codigo="LM393_solo", + descricao="Sensor de umidade do solo", + params="umid_solo"), + "chuva": + SensorTipo(codigo="LM393_chuva", + descricao="Sensor de chuva", + params="chuva"), + "som": + SensorTipo(codigo="LM393_som", descricao="Sensor de som", + params="som"), + "bmp180": + SensorTipo(codigo="BMP180", + descricao="Sensor de altitude e pressão", + params="altitude,pressao"), + "dht22": + SensorTipo(codigo="DHT22", + descricao="Sensor temperatura e umidade", + params="temp_ambiente,umid_relativa") + } sensores = [ - Sensor(tipo="DHT11", - descricao="Sensor temperatura e umidade", - params="temp_ambiente,umid_relativa", - estacao_id=1), - Sensor(tipo="LDR", - descricao="Sensor de luminosidade", - params="luminosidade", - estacao_id=1), - Sensor(tipo="DS18B20", - descricao="Sensor de temperatura digital", - params="temp_agua", - estacao_id=1), - Sensor(tipo="LM393_solo", - descricao="Sensor de umidade do solo", - params="umid_solo", - estacao_id=1), - Sensor(tipo="LM393_chuva", - descricao="Sensor de chuva", - params="chuva", - estacao_id=1), - Sensor(tipo="LM393_som", - descricao="Sensor de som", - params="som", - estacao_id=1), - Sensor(tipo="BMP180", - descricao="Sensor de altitude e pressão", - params="altitude,pressao", - estacao_id=1), - Sensor(tipo="DHT22", - descricao="Sensor temperatura e umidade", - params="temp_ambiente,umid_relativa", - estacao_id=2), - Sensor(tipo="BMP180", - descricao="Sensor de altitude e pressão", - params="altitude,pressao", - estacao_id=3) + Sensor(tipo=tipos["dht11"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["ldr"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["ds18b20"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["solo"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["chuva"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["som"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["bmp180"], estacao=estacoes["ubatuba"]), + Sensor(tipo=tipos["dht22"], estacao=estacoes["caragua"]), + Sensor(tipo=tipos["bmp180"], estacao=estacoes["cunha"]), ] - for estacao in estacoes: + for estacao in estacoes.values(): db.session.add(estacao) db.session.commit() @@ -84,11 +93,9 @@ def create_all(): db.session.add(sensor) db.session.commit() - def get_datahora(): return int(datetime.timestamp(datetime.now())) - def post(url, leitura, token): response = requests.post(url, json={ @@ -98,7 +105,6 @@ def post(url, leitura, token): headers={"Authorization": f"jwt {token}"}) print(response.json()) - def simular(): auth = {"email": "admin@gmail.com", "password": "12345678"} url = "http://localhost:5000/token" @@ -112,7 +118,7 @@ def simular(): # Determina os valores iniciais para cada parámetro for sensor in sensores: valores_sensor = {} - for param in sensor.params.split(","): + for param in sensor.tipo.params.split(","): if param.startswith("temp"): pmin = MIN_TEMP pmax = MAX_TEMP @@ -143,7 +149,7 @@ def simular(): sleep(1) for sensor, valores in zip_sensores: - params = sensor.params.split(",") + params = sensor.tipo.params.split(",") for param in params: url = f"http://localhost:5000/api/{VERSAO}/sensor/{sensor.id}/{param}" inicial = float(valores[param]) @@ -151,7 +157,6 @@ def simular(): leitura = Leitura(valor=valor, datahora=get_datahora()) post(url, leitura, token) - if __name__ == "__main__": print(""" Esse script não deve ser executado. @@ -161,4 +166,4 @@ def simular(): - chame a função com: `sensor_sim.create_all()` `sensor_sim.simular()` - """) +""") diff --git a/prototipo/setup.py b/prototipo/setup.py index 69ee722..50eba3c 100644 --- a/prototipo/setup.py +++ b/prototipo/setup.py @@ -8,7 +8,7 @@ def read(filename): setup( name="FlaskAPI", version="0.1.0", - description="Online Chess Game", + description="Flask REST API", packages=find_packages(), include_package_data=True, install_requires=read("requirements.txt"),