Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migration esp #60

Merged
merged 22 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
41b7de1
feat: create migration to add api.esp table
Jun 26, 2024
f8c4cc2
feat: create esp interface
Jun 26, 2024
af90318
feat: create function to get all esp in database
Jun 26, 2024
d807aa8
refactor: move host name in .env file
Jun 26, 2024
1194b12
Merge branch 'Dev' into migration-esp
Jun 26, 2024
870bcbb
Merge branch 'Dev' into migration-esp
Jun 26, 2024
ae05115
refactor: changed link to get data in api
Jun 26, 2024
bfeb7d4
refactor: changes the permissions of the web_user in the esp table
Jun 26, 2024
67e6e5b
fix: display data in esp page
Jun 26, 2024
e1c6252
feat: implementation of adding esp to the database
Jun 26, 2024
9a30148
refactor: useFindipByName retrieves the correct ip address from the d…
Jun 27, 2024
fcd56e8
refactor: lists the different esp from the database
Jun 27, 2024
ca4fa91
Merge branch 'museebolo:main' into migration-esp
jordyBSK Jun 27, 2024
8fbb835
Merge branch 'migration-esp' of github.com:jordyBSK/climat_guardian i…
Jun 27, 2024
d2b08dc
refactor: get esp from database in dashboard
Jun 27, 2024
4869894
feat: update data table to use a foreign key instead of a string (#1)
Rignchen Jun 27, 2024
41f7dc2
Merge branch 'migration-esp' of github.com:jordyBSK/climat_guardian i…
Jun 27, 2024
9436af9
refactor: removed function add an esp on page plan
Jun 27, 2024
88e33dc
fix: allow webuser to get data from data_view
Jun 27, 2024
f2e8453
refactor: change link fetch to get data in database
Jun 27, 2024
99e21e9
fix: fix deleteEsp function
Jun 27, 2024
04e059e
refactor: removed unused samplecontext
Jun 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 75 additions & 5 deletions database/migration/deploy/esp.sql
Original file line number Diff line number Diff line change
@@ -1,9 +1,79 @@
-- Deploy climat-guardian:esp to pg

BEGIN;

create table esp
(
name character varying(20) not null,
ip character varying(15) NOT NULL
);
create table api.esp (
id serial primary key,
name character varying(20) not null,
ip character varying(15) NOT NULL unique,
x integer default 0,
y integer default 0
);
grant all on api.esp to web_user;
grant usage, select on sequence api.esp_id_seq to web_user;

-- Change api.data to use a foreign key instead of a string
alter table api.data add column esp_id integer;
insert into api.esp (name, ip) select distinct 'unnamed', ip from api.data;
update api.data set esp_id = esp.id from api.esp esp where api.data.ip = esp.ip;
alter table api.data drop column ip;
alter table api.data add constraint data_esp_fk foreign key (esp_id) references api.esp(id);

-- Create a view to get the data with the esp name and ip
create view api.data_view as
select temperature, humidity, timestamp, ip, name
from api.data
join api.esp as e on e.id = data.esp_id;
grant select on api.data_view to web_user;

-- Replace the function to insert data to match the new data structure
drop function api.insert_data;
create function api.insert_data(
temperature real,
humidity real,
ip varchar(15),
unix_timestamp bigint
)
returns void as $$
declare
ip_address varchar(15):= ip;
begin
-- if the ip said in the token is not the same as the one in the request, then this means that the user is not who he pretends to be and we should throw an error
if (current_setting('request.jwt.claims', true)::json->>'ip' != ip_address) then
raise exception insufficient_privilege
using hint = 'You are not who you pretend to be';
end if;
-- insert the data
insert into api.data("temperature", "humidity", "timestamp", "esp_id") values (temperature, humidity, to_timestamp(unix_timestamp), (select id from api.esp where ip_address = esp.ip));
end $$ language plpgsql;
grant insert on api.data to esp32;

-- Replace the function to get the averaged data to match the new data structure
drop function api.avg_date;
create function api.avg_date(
delta varchar
)
returns table(
avg_temperature double precision,
avg_humidity double precision,
date timestamp,
ip character varying(15),
name character varying(20),
count bigint
) as $$
begin
return query select
avg(temperature) as avg_temperature,
avg(humidity) as avg_humidity,
date_trunc(delta, timestamp) as date,
esp.ip,
esp.name,
count(*) as count
from api.data
join api.esp on data.esp_id = esp.id
group by date, esp.id
order by date;
end;
$$ language plpgsql;

COMMIT;
59 changes: 57 additions & 2 deletions database/migration/revert/esp.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,60 @@
-- Revert climat-guardian:esp from pg

BEGIN;

drop table esp;
-- drop the view
drop view api.data_view;

-- set the data table back to the old state
alter table api.data add column ip varchar(15);
update api.data data set ip = esp.ip from api.esp esp where data.esp_id = esp.id;
alter table api.data drop column esp_id;

-- drop the esp table
drop table api.esp;

-- use the old functions bback
drop function api.insert_data;
create function api.insert_data(
temperature real,
humidity real,
ip varchar(15),
unix_timestamp bigint
)
returns void as $$
begin
-- if the ip said in the token is not the same as the one in the request, then this means that the user is not who he pretends to be and we should throw an error
if (current_setting('request.jwt.claims', true)::json->>'ip' != ip) then
raise exception insufficient_privilege
using hint = 'You are not who you pretend to be';
end if;
-- insert the data
insert into api.data("temperature", "humidity", "ip", "timestamp") values (temperature, humidity, ip, to_timestamp(unix_timestamp));
end $$ language plpgsql;
grant insert on api.data to esp32;

drop function api.avg_date;
create function api.avg_date(
delta varchar
)
returns table(
avg_temperature double precision,
avg_humidity double precision,
date timestamp,
ip character varying(15),
count bigint
) as $$
begin
return query select
avg(temperature) as avg_temperature,
avg(humidity) as avg_humidity,
date_trunc(delta, timestamp) as date,
data.ip,
count(*) as count
from api.data
group by date, data.ip
order by date;
end;
$$ language plpgsql;

COMMIT;
COMMIT;
1 change: 1 addition & 0 deletions database/migration/sqitch.plan
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ postgrest 2024-06-07T14:50:40Z Nils <nils@fedora> # create schema and roles for
roles 2024-06-07T18:32:02Z Nils <nils@fedora> # create the role used by the user to distinguish users and esp
data 2024-06-07T20:09:18Z Nils <nils@fedora> # Add table to store data
user 2024-06-07T20:47:39Z Nils <nils@fedora> # create a user table to store every user and password
esp 2024-06-26T08:20:01Z dylan <dylanbossoku@dylan> # create a esp table to stove every esp data
24 changes: 20 additions & 4 deletions database/migration/verify/esp.sql
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
-- Verify climat-guardian:esp on pg

BEGIN;

select * from esp
INSERT INTO esp (name, ip) VALUES ('ESP1', '192.168.1.10');
SELECT ip FROM esp WHERE name = 'ESP1';
-- test esp table
select * from api.esp;
INSERT INTO api.esp (name, ip) VALUES ('ESP1', '192.168.1.10');
UPDATE api.esp SET (x,y) = (4,5) WHERE name = 'ESP1';
SELECT ip FROM api.esp WHERE name = 'ESP1';

-- test data table
select * from api.data;
INSERT INTO api.data (temperature, humidity, timestamp, esp_id) VALUES (25.5, 50.5, '2021-01-01 00:00:00', (SELECT id FROM api.esp WHERE name = 'ESP1'));

-- test data_view and avg_date
select * from api.data_view where name = 'ESP1';
select * from api.avg_date('day') where name = 'ESP1';

-- test insert_data
delete from api.data where esp_id = (SELECT id FROM api.esp WHERE name = 'ESP1');
select api.insert_data(25.5, 50.5, '192.168.1.10', 1609459200);
select * from api.data where esp_id = (SELECT id FROM api.esp WHERE name = 'ESP1');

COMMIT;
ROLLBACK;
17 changes: 6 additions & 11 deletions nextjs-interface/src/app/dashboard/esp/[espName]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
// import components
"use client";

// import charts
import { PieChartHumidity } from "@/app/ui/dashboard/PieChartHumidity";
import { ChartElement } from "@/app/ui/dashboard/ChartElement";
import { PieChartTemperature } from "@/app/ui/dashboard/PieChartTemperature";
import { DateRangeElement } from "@/app/ui/dashboard/DateRangeElement";

import findIpByName, { useFetchData, useLastData } from "@/lib/data";
import { endOfMonth, format, startOfMonth } from "date-fns";
import { DateRange } from "react-day-picker";
import findIpByName, { useFetchData, useLastData } from "@/lib/data";

import React from "react";
import { useParams } from "react-router";

export default function Page() {
const params = useParams<{ espName: string }>();

export default function Page({ params }: { params: any }) {
const [date, setDate] = React.useState<DateRange | undefined>(() => {
const now = new Date();
return {
from: startOfMonth(now),
to: endOfMonth(now),
};
});

const from = date?.from ? format(date.from, "yyyy-MM-dd") : "";
const to = date?.to ? format(date.to, "yyyy-MM-dd") : "";
const precision = "day";
const precision = "minute";

const ip = findIpByName(params.espName || "Loading");
const ip = findIpByName(params.espName);
const allData = useFetchData(precision, ip, from, to);
const temperature = useLastData("temperature", ip);
const humidity = useLastData("humidity", ip);
Expand All @@ -37,7 +33,6 @@ export default function Page() {
<p className="text-2xl font-bold uppercase text-black">
{params.espName}
</p>

<DateRangeElement date={date} setDate={setDate} />
<div className="flex flex-col sm:flex-row">
<PieChartTemperature data={temperature} />
Expand Down
11 changes: 2 additions & 9 deletions nextjs-interface/src/app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,10 @@
"use client";
// import components
import DataCircle from "@/app/ui/dashboard/DataCircle";

const ESPList = [
{ name: "ESP N°1", ip: "172.16.5.178" },
{ name: "ESP N°2", ip: "172.16.4.100" },
{ name: "ESP N°3", ip: "172.16.5.178" },
{ name: "ESP N°4", ip: "172.16.4.100" },
{ name: "ESP N°5", ip: "172.16.5.178" },
{ name: "ESP N°6", ip: "172.16.4.100" },
];
import { useAllEsp } from "@/lib/data";

export default function Page() {
const ESPList = useAllEsp();
return (
<>
<div className="px-auto grid h-fit w-full min-w-[500px] grid-cols-1 gap-10 xl:grid-cols-2 2xl:grid-cols-3">
Expand Down
34 changes: 25 additions & 9 deletions nextjs-interface/src/app/ui/dashboard/EspLinksElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,41 @@ import {
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "recharts";
import { getToken } from "@/lib/context";
import { useAllEsp } from "@/lib/data";

export default function EspLinksElement() {
const pathname = usePathname();

const [links, setLinks] = useState([
{ name: "chasseron", ip: "172.16.4.100" },
{ name: "pleiades", ip: "172.16.5.178" },
]);

const [newLink, setNewLink] = useState({ name: "", ip: "" });
const links = useAllEsp();
const [newLink, setNewLink] = useState({ name: "", ip: ""});

const handleInputChange = (e: any) => {
setNewLink({ ...newLink, [e.target.id]: e.target.value });
};

const handleSubmit = (e: any) => {
const handleSubmit = async (e: { preventDefault: () => void }) => {
e.preventDefault();
setLinks([...links, newLink]);
setNewLink({ name: "", ip: "" });
const url = `/postgrest/esp`;

try {
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${getToken()}`,
},
body: JSON.stringify(newLink),
});

if (!response.ok) {
Error("Erreur lors de l'envoi des données à l'API");
}

setNewLink({ name: "", ip: "" });
} catch (e) {
console.error("Une erreur s'est produite :", e);
}
};

return (
Expand Down
4 changes: 0 additions & 4 deletions nextjs-interface/src/app/ui/dashboard/espLinks.tsx

This file was deleted.

5 changes: 2 additions & 3 deletions nextjs-interface/src/app/ui/login/LoginElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { SampleContext } from "@/lib/context";

export function LoginElement() {
const [username, setUsername] = useState("");
Expand All @@ -23,7 +22,7 @@ export function LoginElement() {
e.preventDefault();

await fetch(
`${SampleContext.urlLogin}/login.php?username=${username}&password=${password}`,
`/php/login.php?username=${username}&password=${password}`,
{
headers: {
Accept: "application/json",
Expand All @@ -39,7 +38,7 @@ export function LoginElement() {
if (reponse.token) {
localStorage.setItem("token", reponse.token);
localStorage.setItem("username", username);
window.location.replace(`${SampleContext.urlCurrent}/dashboard`);
window.location.replace(`/dashboard`);
}
})
.catch((e) => {
Expand Down
Loading