commit 6b025aeacb505129cd9a9104077374ffc0144f53 Author: Safouane Bazzi Date: Mon Mar 9 14:11:28 2026 +0100 Initial commit - EcoCharge backend API + admin diff --git a/app.py b/app.py new file mode 100644 index 0000000..b601121 --- /dev/null +++ b/app.py @@ -0,0 +1,106 @@ +from flask import Flask, jsonify, render_template, request, redirect, url_for, session +from flask_cors import CORS +from config import Config +import psycopg2 + +app = Flask(__name__) +app.config.from_object(Config) +app.secret_key = app.config["SECRET_KEY"] + +CORS(app) + +conn = psycopg2.connect( + host="localhost", + port=5432, + database="ecocharge", + user="eco", + password="eco_pass" +) + +@app.route("/") +def home(): + return jsonify({ + "message": "API EcoCharge en ligne" + }) + +@app.route("/api/status") +def status(): + return jsonify({ + "project": "EcoCharge", + "api": "ok", + "database": "postgresql_connected" + }) + +@app.route("/admin/login", methods=["GET", "POST"]) +def admin_login(): + if request.method == "POST": + username = request.form.get("username") + password = request.form.get("password") + + if username == "admin" and password == "admin123": + session["admin_logged_in"] = True + return redirect(url_for("admin_dashboard")) + + return render_template("login.html", error="Identifiants incorrects") + + return render_template("login.html") + +@app.route("/admin/dashboard", methods=["GET", "POST"]) +def admin_dashboard(): + if not session.get("admin_logged_in"): + return redirect(url_for("admin_login")) + + cur = conn.cursor() + + if request.method == "POST": + min_battery = request.form.get("min_battery") + max_temp = request.form.get("max_temp") + min_power = request.form.get("min_power") + + cur.execute(""" + INSERT INTO settings (key, value) + VALUES ('min_battery_voltage', %s) + ON CONFLICT (key) + DO UPDATE SET value = EXCLUDED.value + """, (min_battery,)) + + cur.execute(""" + INSERT INTO settings (key, value) + VALUES ('max_battery_temperature', %s) + ON CONFLICT (key) + DO UPDATE SET value = EXCLUDED.value + """, (max_temp,)) + + cur.execute(""" + INSERT INTO settings (key, value) + VALUES ('min_solar_power', %s) + ON CONFLICT (key) + DO UPDATE SET value = EXCLUDED.value + """, (min_power,)) + + conn.commit() + + cur.execute("SELECT value FROM settings WHERE key = 'min_battery_voltage'") + row1 = cur.fetchone() + + cur.execute("SELECT value FROM settings WHERE key = 'max_battery_temperature'") + row2 = cur.fetchone() + + cur.execute("SELECT value FROM settings WHERE key = 'min_solar_power'") + row3 = cur.fetchone() + + settings = { + "min_battery": row1[0] if row1 else "10.5", + "max_temp": row2[0] if row2 else "45", + "min_power": row3[0] if row3 else "5" + } + + return render_template("admin_dashboard.html", settings=settings) + +@app.route("/admin/logout") +def admin_logout(): + session.pop("admin_logged_in", None) + return redirect(url_for("admin_login")) + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=True) diff --git a/config.py b/config.py new file mode 100644 index 0000000..b946876 --- /dev/null +++ b/config.py @@ -0,0 +1,13 @@ +import os +from dotenv import load_dotenv + +load_dotenv() + +class Config: + SECRET_KEY = os.getenv("SECRET_KEY", "ecocharge_secret_2026") + + DB_HOST = os.getenv("DB_HOST", "localhost") + DB_PORT = int(os.getenv("DB_PORT", 3306)) + DB_NAME = os.getenv("DB_NAME", "ecocharge") + DB_USER = os.getenv("DB_USER", "root") + DB_PASSWORD = os.getenv("DB_PASSWORD", "root") diff --git a/database.sql b/database.sql new file mode 100644 index 0000000..b67e9b7 --- /dev/null +++ b/database.sql @@ -0,0 +1,323 @@ +-- +-- PostgreSQL database dump +-- + +\restrict ijnV8LNUvXkT7zfNUtK8rYjTPMZ7E4a8Dp7BES0I4ggucAotiMgPl90yvhq0XQq + +-- Dumped from database version 18.3 (Debian 18.3-1.pgdg13+1) +-- Dumped by pg_dump version 18.3 (Debian 18.3-1.pgdg13+1) + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET transaction_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- Name: settings; Type: TABLE; Schema: public; Owner: eco +-- + +CREATE TABLE public.settings ( + id integer NOT NULL, + key character varying(50), + value character varying(100) +); + + +ALTER TABLE public.settings OWNER TO eco; + +-- +-- Name: settings_id_seq; Type: SEQUENCE; Schema: public; Owner: eco +-- + +CREATE SEQUENCE public.settings_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER SEQUENCE public.settings_id_seq OWNER TO eco; + +-- +-- Name: settings_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: eco +-- + +ALTER SEQUENCE public.settings_id_seq OWNED BY public.settings.id; + + +-- +-- Name: system_status; Type: TABLE; Schema: public; Owner: eco +-- + +CREATE TABLE public.system_status ( + id integer NOT NULL, + device_name character varying(50), + online boolean, + last_seen timestamp without time zone +); + + +ALTER TABLE public.system_status OWNER TO eco; + +-- +-- Name: system_status_id_seq; Type: SEQUENCE; Schema: public; Owner: eco +-- + +CREATE SEQUENCE public.system_status_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER SEQUENCE public.system_status_id_seq OWNER TO eco; + +-- +-- Name: system_status_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: eco +-- + +ALTER SEQUENCE public.system_status_id_seq OWNED BY public.system_status.id; + + +-- +-- Name: telemetry; Type: TABLE; Schema: public; Owner: eco +-- + +CREATE TABLE public.telemetry ( + id integer NOT NULL, + "timestamp" timestamp without time zone DEFAULT CURRENT_TIMESTAMP, + upv double precision, + ipv double precision, + ubat double precision, + ibat double precision, + power double precision, + temperature double precision, + luminosity double precision, + humidity double precision +); + + +ALTER TABLE public.telemetry OWNER TO eco; + +-- +-- Name: telemetry_id_seq; Type: SEQUENCE; Schema: public; Owner: eco +-- + +CREATE SEQUENCE public.telemetry_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER SEQUENCE public.telemetry_id_seq OWNER TO eco; + +-- +-- Name: telemetry_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: eco +-- + +ALTER SEQUENCE public.telemetry_id_seq OWNED BY public.telemetry.id; + + +-- +-- Name: users; Type: TABLE; Schema: public; Owner: eco +-- + +CREATE TABLE public.users ( + id integer NOT NULL, + username character varying(50), + password character varying(255), + is_admin boolean DEFAULT false +); + + +ALTER TABLE public.users OWNER TO eco; + +-- +-- Name: users_id_seq; Type: SEQUENCE; Schema: public; Owner: eco +-- + +CREATE SEQUENCE public.users_id_seq + AS integer + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + +ALTER SEQUENCE public.users_id_seq OWNER TO eco; + +-- +-- Name: users_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: eco +-- + +ALTER SEQUENCE public.users_id_seq OWNED BY public.users.id; + + +-- +-- Name: settings id; Type: DEFAULT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.settings ALTER COLUMN id SET DEFAULT nextval('public.settings_id_seq'::regclass); + + +-- +-- Name: system_status id; Type: DEFAULT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.system_status ALTER COLUMN id SET DEFAULT nextval('public.system_status_id_seq'::regclass); + + +-- +-- Name: telemetry id; Type: DEFAULT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.telemetry ALTER COLUMN id SET DEFAULT nextval('public.telemetry_id_seq'::regclass); + + +-- +-- Name: users id; Type: DEFAULT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.users ALTER COLUMN id SET DEFAULT nextval('public.users_id_seq'::regclass); + + +-- +-- Data for Name: settings; Type: TABLE DATA; Schema: public; Owner: eco +-- + +COPY public.settings (id, key, value) FROM stdin; +1 temp_max 60 +2 battery_min 11 +3 solar_max 22 +\. + + +-- +-- Data for Name: system_status; Type: TABLE DATA; Schema: public; Owner: eco +-- + +COPY public.system_status (id, device_name, online, last_seen) FROM stdin; +1 esp32 f 2026-03-05 15:07:28.827398 +\. + + +-- +-- Data for Name: telemetry; Type: TABLE DATA; Schema: public; Owner: eco +-- + +COPY public.telemetry (id, "timestamp", upv, ipv, ubat, ibat, power, temperature, luminosity, humidity) FROM stdin; +1 2026-03-05 14:51:17.119119 18.5 0.7 12.4 0.5 13 32 500 45 +2 2026-03-05 15:07:19.878569 19 0.8 12.5 0.5 14 31 600 40 +\. + + +-- +-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: eco +-- + +COPY public.users (id, username, password, is_admin) FROM stdin; +1 admin admin123 t +\. + + +-- +-- Name: settings_id_seq; Type: SEQUENCE SET; Schema: public; Owner: eco +-- + +SELECT pg_catalog.setval('public.settings_id_seq', 3, true); + + +-- +-- Name: system_status_id_seq; Type: SEQUENCE SET; Schema: public; Owner: eco +-- + +SELECT pg_catalog.setval('public.system_status_id_seq', 1, true); + + +-- +-- Name: telemetry_id_seq; Type: SEQUENCE SET; Schema: public; Owner: eco +-- + +SELECT pg_catalog.setval('public.telemetry_id_seq', 2, true); + + +-- +-- Name: users_id_seq; Type: SEQUENCE SET; Schema: public; Owner: eco +-- + +SELECT pg_catalog.setval('public.users_id_seq', 1, true); + + +-- +-- Name: settings settings_key_key; Type: CONSTRAINT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.settings + ADD CONSTRAINT settings_key_key UNIQUE (key); + + +-- +-- Name: settings settings_pkey; Type: CONSTRAINT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.settings + ADD CONSTRAINT settings_pkey PRIMARY KEY (id); + + +-- +-- Name: system_status system_status_pkey; Type: CONSTRAINT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.system_status + ADD CONSTRAINT system_status_pkey PRIMARY KEY (id); + + +-- +-- Name: telemetry telemetry_pkey; Type: CONSTRAINT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.telemetry + ADD CONSTRAINT telemetry_pkey PRIMARY KEY (id); + + +-- +-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_pkey PRIMARY KEY (id); + + +-- +-- Name: users users_username_key; Type: CONSTRAINT; Schema: public; Owner: eco +-- + +ALTER TABLE ONLY public.users + ADD CONSTRAINT users_username_key UNIQUE (username); + + +-- +-- PostgreSQL database dump complete +-- + +\unrestrict ijnV8LNUvXkT7zfNUtK8rYjTPMZ7E4a8Dp7BES0I4ggucAotiMgPl90yvhq0XQq + diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..e7bcb32 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +Flask==3.0.3 +flask-cors==4.0.1 +python-dotenv==1.0.1 +mysql-connector-python==9.0.0 +Werkzeug==3.0.3 diff --git a/templates/admin_dashboard.html b/templates/admin_dashboard.html new file mode 100644 index 0000000..475f557 --- /dev/null +++ b/templates/admin_dashboard.html @@ -0,0 +1,78 @@ + + + + Admin EcoCharge + + + + + +
+ +

Administration EcoCharge

+ +
+ + + + + + + + + + + + +
+ +Se déconnecter + +
+ + + diff --git a/templates/login.html b/templates/login.html new file mode 100644 index 0000000..4c21fa5 --- /dev/null +++ b/templates/login.html @@ -0,0 +1,87 @@ + + + + + + Connexion Admin - EcoCharge + + + +
+

Connexion Admin

+
+ + + + + + + +
+ + {% if error %} +

{{ error }}

+ {% endif %} +
+ +