This commit is contained in:
Sage The DM 2024-11-25 22:25:35 +01:00
parent db6b2a2a6e
commit 58a45463d4
38 changed files with 512 additions and 173 deletions

View file

@ -0,0 +1,87 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ThingSpeakURLGenerator {
// Constants for Room channel numbers
private static final int ROOM_39_NUMBER = 1521262;
private static final int ROOM_38_NUMBER = 1364580;
private static final int ROOM_37_NUMBER = 1521263;
// Example Dates for fetching data, dynamically generated
private static final LocalDateTime START_DATE = LocalDateTime.of(2024, 11, 1, 0, 0);
private static final LocalDateTime END_DATE = LocalDateTime.of(2024, 11, 1, 23, 59);
// Room URLs
private static final Map<Integer, String> ROOM_URLS = new HashMap<>();
static {
ROOM_URLS.put(39, createUrl(ROOM_39_NUMBER));
ROOM_URLS.put(38, createUrl(ROOM_38_NUMBER));
ROOM_URLS.put(37, createUrl(ROOM_37_NUMBER));
}
// Method to create the ThingSpeak API URL dynamically
public static String createUrl(int channelNumber) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String startDate = encodeUrlParam(START_DATE.format(formatter));
String endDate = encodeUrlParam(END_DATE.format(formatter));
return String.format("https://api.thingspeak.com/channels/%d/feeds.csv?start=%s&end=%s",
channelNumber, startDate, endDate);
}
// Helper method to URL encode the date strings
private static String encodeUrlParam(String value) {
try {
return URLEncoder.encode(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
System.err.println("Error encoding URL parameter: " + e.getMessage());
return value;
}
}
// Method to calculate the average of a specific number of data points (e.g.,
// CO2 levels)
public static double calculateAverage(List<Co2Data> dataList) {
if (dataList == null || dataList.isEmpty()) {
return 0.0;
}
double sum = 0.0;
for (Co2Data data : dataList) {
sum += data.getCo2Level(); // Assuming Co2Data has a method getCo2Level() that returns the CO2 level
}
return sum / dataList.size();
}
public static void main(String[] args) {
try {
// Print out the generated URLs for each room
for (Map.Entry<Integer, String> entry : ROOM_URLS.entrySet()) {
System.out.println("Room " + entry.getKey() + " URL: " + entry.getValue());
}
// Example: Calculate and print the average CO2 level for each room (assuming
// Co2Data.getData() method exists)
List<Co2Data> room39Data = Co2Data.getData(ROOM_URLS.get(39));
List<Co2Data> room38Data = Co2Data.getData(ROOM_URLS.get(38));
List<Co2Data> room37Data = Co2Data.getData(ROOM_URLS.get(37));
double avgRoom39 = calculateAverage(room39Data);
double avgRoom38 = calculateAverage(room38Data);
double avgRoom37 = calculateAverage(room37Data);
System.out.println("Average CO2 Level in Room 39: " + avgRoom39);
System.out.println("Average CO2 Level in Room 38: " + avgRoom38);
System.out.println("Average CO2 Level in Room 37: " + avgRoom37);
} catch (Exception e) {
e.printStackTrace();
}
}
}

Binary file not shown.

Binary file not shown.

View file

@ -1,78 +1,71 @@
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.HashMap;
public class App { public class App {
// #region app constants // #region app constants
private static final Scanner scanner = new Scanner(System.in);
private static final Teacher[] teachers = new Teacher[Teacher.nameMap.size()]; private static final Teacher[] teachers = new Teacher[Teacher.nameMap.size()];
private static final String[] START_SMALL_BREAK = {
"8:30", "10:25", "11:15", "12:05", "13:30", "14:20", "16:10", "17:00", "17:50"
};
private static final String[] END_SMALL_BREAK = {
"8:35", "10:30", "11:20", "12:10", "13:35", "14:25", "16:15", "17:05", "17:55"
};
private static final String[] START_LONG_BREAK = {
"9:20", "15:10"
};
private static final String[] END_LONG_BREAK = {
"9:40", "15:25"
};
// Room channel numbers // Room channel numbers
private static final int ROOM_39_NUMBER = 1521262; private static final int ROOM_39_NUMBER = 1521262;
private static final int ROOM_38_NUMBER = 1364580; private static final int ROOM_38_NUMBER = 1364580;
private static final int ROOM_37_NUMBER = 1521263; private static final int ROOM_37_NUMBER = 1521263;
// Date and time constants // Date and time constants for Start and End Dates
private static final int START_YEAR = 2024; private static final String START_DATE = "2024-11-04";
private static final int START_MONTH = 11; // November private static final String END_DATE = "2024-11-08";
private static final int START_DAY = 4;
private static final int START_HOUR = 0;
private static final int START_MINUTE = 0;
private static final int END_YEAR = 2024;
private static final int END_MONTH = 11; // November
private static final int END_DAY = 8;
private static final int END_HOUR = 23;
private static final int END_MINUTE = 59;
// Formatting the start and end date with time
private static final String START_DATE = String.format("%d-%02d-%02d%%20%02d:%02d:00",
START_YEAR, START_MONTH, START_DAY, START_HOUR, START_MINUTE);
private static final String END_DATE = String.format("%d-%02d-%02d%%20%02d:%02d:00",
END_YEAR, END_MONTH, END_DAY, END_HOUR, END_MINUTE);
// #region Initialization // #region Initialization
private static String createUrl(int ROOM_X_NUMBER) {
return String.format("https://api.thingspeak.com/channels/%d/feeds.csv?start=%s&end=%s", public static String generateLink(int channelNumber, String date, String startTime, String endTime) {
ROOM_X_NUMBER, START_DATE, END_DATE); String baseUrl = "https://api.thingspeak.com/channels/";
String formattedStartDateTime = date + " " + startTime;
String formattedEndDateTime = date + " " + endTime;
return baseUrl + channelNumber + "/feeds.csv?start=" + formattedStartDateTime.replace(" ", "%20")
+ "&end=" + formattedEndDateTime.replace(" ", "%20"); // %20 --> " "
} }
// #endregion
private static void getDataForBreak() { private static double getDataAverageForMinute(int minute, int hour, int number, String date) {
// Co2Data[Wochentag][Room 37, 38 or 39] // get the url
Co2Data[][][] data = new Co2Data[5][3][11]; String startTime = "";
if (hour < 10) {
startTime += "0";
}
startTime += String.valueOf(hour);
startTime += ":";
if (minute < 10) {
startTime += "0";
}
startTime += String.valueOf(minute);
String calcStarttime = startTime + ":00";
String calcEndTime = startTime + "59";
// Placeholder logic: Retrieve data for CO2 during breaks String url = generateLink(number, date, calcStarttime, calcEndTime);
// This should be replaced with the actual logic to get the data from ThingSpeak
for (int i = 0; i < 5; i++) { double averageCO2 = 0.0;
for (int j = 0; j < 3; j++) { List<Co2Data> co2DataList = Co2Data.getData(url);
for (int k = 0; k < 11; k++) { for (Co2Data co2Data : co2DataList) {
data[i][j][k] = new Co2Data(null, k); // Placeholder CO2 data averageCO2 += co2Data.getCo2Level();
}
return averageCO2 / co2DataList.size(); // Example CO2 average level
}
private static void calculateBreakPoints(double[] minuteData, Break calcBreak) {
int duration = calcBreak.getEnd().getMinute() - calcBreak.getStart().getMinute();
int breakPoints = minuteData.length;
if (duration == minuteData.length) {
for (int i = 0; i < duration; i++) {
if (minuteData[i] < minuteData[i + 1]) {
breakPoints--;
} }
} }
}
}
private static double getDataAverageForMinute(String time) { } else
// Placeholder logic to calculate average CO2 levels System.out.println("Unexpected error");
return 400.0; // Example CO2 average level
} }
private static void initializeTeachers() { private static void initializeTeachers() {
@ -85,7 +78,6 @@ public class App {
} }
} }
private static final Scanner scanner = new Scanner(System.in);
// #region User Interaction // #region User Interaction
private static int getUserInput(String textOutput) { private static int getUserInput(String textOutput) {
@ -104,7 +96,6 @@ public class App {
System.out.println("1. Up to 5 points for keeping the window open during a small pause."); System.out.println("1. Up to 5 points for keeping the window open during a small pause.");
System.out.println("2. Up to 10 points for long pauses, depending on window usage."); System.out.println("2. Up to 10 points for long pauses, depending on window usage.");
System.out.println("3. 5 bonus points for teacher switches in classrooms."); System.out.println("3. 5 bonus points for teacher switches in classrooms.");
System.out.println("4. Deduct points if CO2 levels are too high.");
} }
// #region shutdown // #region shutdown
@ -168,15 +159,22 @@ public class App {
public static void main(String[] args) { public static void main(String[] args) {
System.out.println("Calculations in process please do not shut off..."); System.out.println("Calculations in process please do not shut off...");
initializeTeachers(); initializeTeachers();
sortTeachers(); sortTeachers();
printTeachers(); printTeachers();
// Loop threw each day with a specific classroom and after the weekdays are over
// go to the next of the 3 classroms
// go threw every break calculate the point and give them to the teacher
// directly
// remember the point class
// breakShedule needed
while (true) { while (true) {
int userInput = getUserInput( int userInput = getUserInput(
"Do you want to see how the points were calculated? (Yes 1, No 0; anything is an error)"); "Do you want to see how the points were calculated? (Yes 1, No 0; anything is an error)");
if (userInput == 1) { if (userInput == 1) {
printExplanation(); printExplanation();
// add a more detailed listing of the teacher since points can be broken down
// further
printShutDown(); printShutDown();
break; break;
} else if (userInput == 0) { } else if (userInput == 0) {

View file

@ -1,14 +1,10 @@
public class Break { public class Break {
private Time start; private Time start;
private Time end; private Time end;
private Teacher teacher;
private int room;
public Break(Time start, Time end, Teacher teacher, int room) { public Break(Time start, Time end) {
this.start = start; this.start = start;
this.end = end; this.end = end;
this.teacher = teacher;
this.room = room;
} }
public Time getStart() { public Time getStart() {
@ -27,19 +23,34 @@ public class Break {
this.end = end; this.end = end;
} }
public Teacher getTeacher() { /**
return teacher; * Generates a Thingspeak API link based on channel number, date, and break
* period.
*
* @param channelNumber The Thingspeak channel number.
* @param date The date in format "YYYY-MM-DD".
* @param breakPeriod The Break object containing start and end times.
* @return A formatted URL for fetching data from the Thingspeak API.
*/
public static String generateLink(int channelNumber, String date, Break breakPeriod) {
String baseUrl = "https://api.thingspeak.com/channels/";
String formattedStartDateTime = date + " " + breakPeriod.getStart().toString();
String formattedEndDateTime = date + " " + breakPeriod.getEnd().toString();
return baseUrl + channelNumber + "/feeds.csv?start=" + formattedStartDateTime.replace(" ", "%20")
+ "&end=" + formattedEndDateTime.replace(" ", "%20");
} }
public void setTeacher(Teacher teacher) { public static void main(String[] args) {
this.teacher = teacher; // Example usage
} Time start = Time.valueOf("00:00:00");
Time end = Time.valueOf("23:59:59");
Break breakPeriod = new Break(start, end);
public int getRoom() { String date = "2024-11-17";
return room; int channelNumber = 1364580;
}
public void setRoom(int room) { String link = Break.generateLink(channelNumber, date, breakPeriod);
this.room = room; System.out.println(link);
} }
} }

View file

@ -0,0 +1,47 @@
public class BreakSchedule {
private static final String[] START_SMALL_BREAK = {
"8:30", "10:25", "11:15", "12:05", "13:30", "14:20", "16:10", "17:00", "17:50"
};
private static final String[] END_SMALL_BREAK = {
"8:35", "10:30", "11:20", "12:10", "13:35", "14:25", "16:15", "17:05", "17:55"
};
private static final String[] START_LONG_BREAK = {
"9:20", "15:10"
};
private static final String[] END_LONG_BREAK = {
"9:40", "15:25"
};
private static final Break[] SMALL_BREAKS;
private static final Break[] LONG_BREAKS;
static {
SMALL_BREAKS = createBreaks(START_SMALL_BREAK, END_SMALL_BREAK);
LONG_BREAKS = createBreaks(START_LONG_BREAK, END_LONG_BREAK);
}
private static Break[] createBreaks(String[] startTimes, String[] endTimes) {
Break[] breaks = new Break[startTimes.length];
for (int i = 0; i < startTimes.length; i++) {
// Append ":00" to include seconds
String startTimeWithSeconds = startTimes[i];
String endTimeWithSeconds = endTimes[i];
Time start = Time.valueOf(startTimeWithSeconds);
Time end = Time.valueOf(endTimeWithSeconds);
breaks[i] = new Break(start, end);
}
return breaks;
}
public static Break[] getSmallBreaks() {
return SMALL_BREAKS;
}
public static Break[] getLongBreaks() {
return LONG_BREAKS;
}
}

Binary file not shown.

View file

@ -2,21 +2,22 @@ import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
public class Co2Data { public class Co2Data {
// #region Fields
private Date date; private Date date;
private int co2Level; private int co2Level;
// #region Constructor // Constructor
public Co2Data(Date date, int co2Level) { public Co2Data(Date date, int co2Level) {
this.date = date; this.date = date;
this.co2Level = co2Level; this.co2Level = co2Level;
} }
// #region Getters and Setters // Getters and Setters
public Date getDate() { public Date getDate() {
return date; return date;
} }
@ -33,17 +34,15 @@ public class Co2Data {
this.co2Level = co2Level; this.co2Level = co2Level;
} }
// #region Data Fetching // Fetch and parse data from a CSV URL
// Method to fetch and parse CO2 data from a URL public static List<Co2Data> getData(String csvURL) {
public static List<Co2Data> getData(String csvURL, int classRoomNumber) {
List<Co2Data> dataList = new ArrayList<>(); List<Co2Data> dataList = new ArrayList<>();
Date referenceDate = new Date(8, 11, 2024, 0, 0); // Reference date: November 8, 2024
try { try {
URL url = new URL(csvURL); URL url = new URL(csvURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET"); conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/csv"); conn.setRequestProperty("Accept", "text/csv");
if (conn.getResponseCode() != 200) { if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP Error code : " + conn.getResponseCode()); throw new RuntimeException("Failed : HTTP Error code : " + conn.getResponseCode());
@ -54,66 +53,36 @@ public class Co2Data {
String output; String output;
while ((output = br.readLine()) != null) { while ((output = br.readLine()) != null) {
Co2Data data = parseData(output, classRoomNumber); Co2Data data = parseData(output);
if (data != null && isNewerThanReferenceDate(data.getDate(), referenceDate)) { if (data != null) {
dataList.add(data); dataList.add(data);
} }
} }
conn.disconnect(); conn.disconnect();
} catch (Exception e) { } catch (Exception e) {
System.out.println("Exception in NetClientGet: " + e); System.out.println("Error in data fetching: " + e);
} }
return dataList; return dataList;
} }
// #region Date Comparison // Helper method to parse CSV data and create a Co2Data object
// Method to compare if the data date is newer than the reference date private static Co2Data parseData(String line) {
private static boolean isNewerThanReferenceDate(Date dataDate, Date referenceDate) {
if (dataDate.getYear() > referenceDate.getYear()) {
return true;
} else if (dataDate.getYear() == referenceDate.getYear()) {
if (dataDate.getMonth() > referenceDate.getMonth()) {
return true;
} else if (dataDate.getMonth() == referenceDate.getMonth()) {
return dataDate.getDay() > referenceDate.getDay();
}
}
return false;
}
// #region Data Parsing
// Method to parse CO2 data from a CSV line
private static Co2Data parseData(String csvLine, int classRoomNumber) {
String[] fields = csvLine.split(",");
if (fields.length < 5)
return null;
try { try {
String[] dateTime = fields[0].split(" "); String[] parts = line.split(",");
String[] dateParts = dateTime[0].split("-"); String dateStr = parts[0].trim(); // assuming date is in the first column
String[] timeParts = dateTime[1].split(":"); int co2Level = Integer.parseInt(parts[1].trim()); // assuming CO2 level is in the second column
int year = Integer.parseInt(dateParts[0]); // Convert the date string into a Date object (assumes CSV date format is
int month = Integer.parseInt(dateParts[1]); // yyyy-MM-dd HH:mm:ss)
int day = Integer.parseInt(dateParts[2]); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
int hour = Integer.parseInt(timeParts[0]); Date date = sdf.parse(dateStr);
int minute = Integer.parseInt(timeParts[1]);
Date date = new Date(day, month, year, hour, minute);
int co2Level = Integer.parseInt(fields[2]);
return new Co2Data(date, co2Level); return new Co2Data(date, co2Level);
} catch (NumberFormatException e) { } catch (Exception e) {
System.out.println("Error parsing data line: " + e);
return null; return null;
} }
} }
// #region ToString Method
// Method to return a string representation of the CO2 data
@Override
public String toString() {
return "Date: " + date + ", CO2 Level: " + co2Level;
}
} }

Binary file not shown.

View file

@ -1,34 +1,62 @@
public class Date { public class Date {
// #region Fields
private int day;
private int month;
private int year; private int year;
private int month;
private int day;
private int hour; private int hour;
private int minute; private int minute;
// #region Constructor // Constructor to parse date string
public Date(int day, int month, int year, int hour, int minute) { public Date(String dateStr) {
this.day = day; String[] dateTime = dateStr.split(" ");
this.month = month; String[] dateParts = dateTime[0].split("-");
this.year = year; String[] timeParts = dateTime[1].split(":");
this.hour = hour;
this.minute = minute;
// Automatically adjust for Switzerland time after initialization this.year = Integer.parseInt(dateParts[0]);
this.month = Integer.parseInt(dateParts[1]);
this.day = Integer.parseInt(dateParts[2]);
this.hour = Integer.parseInt(timeParts[0]);
this.minute = Integer.parseInt(timeParts[1]);
// Adjust for Switzerland time
adjustForSwitzerlandTime(); adjustForSwitzerlandTime();
} }
// #region Getters // Constructor to create date with fixed numeric values
public int getDay() { public Date(int year, int month, int day, int hour, int minute) {
return day; this.year = year;
this.month = month;
this.day = day;
this.hour = hour;
this.minute = minute;
// Adjust for Switzerland time
adjustForSwitzerlandTime();
}
// Adjust time for Switzerland timezone (UTC+1 or UTC+2 during daylight saving
// time)
private void adjustForSwitzerlandTime() {
// Switzerland time adjustment logic (simplified version)
// For simplicity, this doesn't handle daylight saving time changes but adjusts
// based on UTC+1
this.hour += 1; // Assuming fixed UTC+1 offset for simplicity
if (this.hour >= 24) {
this.hour -= 24;
this.day += 1;
}
}
// Getter methods
public int getYear() {
return year;
} }
public int getMonth() { public int getMonth() {
return month; return month;
} }
public int getYear() { public int getDay() {
return year; return day;
} }
public int getHour() { public int getHour() {
@ -39,38 +67,7 @@ public class Date {
return minute; return minute;
} }
// #region Adjust UTC to Switzerland Time // Method to print date in a readable format
private void adjustForSwitzerlandTime() {
hour += 1;
// Adjust if the hour exceeds 24 or falls below 0
if (hour >= 24) {
hour -= 24;
day++;
if (day > 31) { // Simple month/day rollover, could be more sophisticated
day = 1;
month++;
if (month > 12) {
month = 1;
year++;
}
}
} else if (hour < 0) {
hour += 24;
day--;
if (day < 1) {
month--;
if (month < 1) {
month = 12;
year--;
}
day = 31; // Simple month/day rollover, could be more sophisticated
}
}
}
// #region toString Override
@Override
public String toString() { public String toString() {
return String.format("%04d-%02d-%02d %02d:%02d", year, month, day, hour, minute); return String.format("%04d-%02d-%02d %02d:%02d", year, month, day, hour, minute);
} }

Binary file not shown.

Binary file not shown.

View file

@ -26,4 +26,12 @@ public class Time {
public void setMinute(int minute) { public void setMinute(int minute) {
this.minute = minute; this.minute = minute;
} }
public static Time valueOf(String time) {
String[] parts = time.split(":");
int hour = Integer.parseInt(parts[0]);
int minute = Integer.parseInt(parts[1]);
Time returnValue = new Time(hour, minute);
return returnValue;
}
} }

View file

@ -0,0 +1,79 @@
public class TimeTable {
private String[][] shortTeacher;
public TimeTable(int roomIndex) {
shortTeacher = new String[11][5]; // 11 lessons, 5 weekdays
initializeTimeTable(roomIndex);
}
private void initializeTimeTable(int roomIndex) {
switch (roomIndex) {
case 0: // Room 37
fillRoom37();
break;
case 1: // Room 38
fillRoom38();
break;
case 2: // Room 39
fillRoom39();
break;
default:
throw new IllegalArgumentException("Invalid room index");
}
}
private void fillRoom37() {
shortTeacher = new String[][] {
{ "Hm", "Ts", "Lu", "Gi", "Kp" },
{ "Hm", "Ts", "Lu", "Gi", "KP" },
{ "Hi", "Ts", "Lu", "Ba", "Or" },
{ "Hm", "Ts", "Lu", "Ba", "Vt" },
{ "Hm", "Le", "Cg", "Ba", "Vt" },
{ "Lunch", "Lunch", "Lunch", "Lunch", "Lunch" },
{ "Bd", "Lunch", "Se", "Bd", "Lunch" },
{ "Gi", "Fh", "Se", "Du", "Du" },
{ "Gi", "Fh", "Se", "Lz", "Du" },
{ "Ts", "Fh", "Se", "Lz", "Du" },
{ "Ts", "Fh", "Se", "", "" }
};
}
private void fillRoom38() {
shortTeacher = new String[][] {
{ "Bz", "Kg", "Cg", "Do", "" },
{ "Bz", "Kg", "Cg", "Do", "Hu" },
{ "Bz", "Eh", "Cg", "Gr", "Ge" },
{ "Bz", "Re", "Cg", "Gr", "Eh" },
{ "Bz", "Re", "Es", "Or", "Eh" },
{ "Lunch", "Lunch", "Lunch", "Lunch", "Lunch" },
{ "Lunch", "Lunch", "Lunch", "Lunch", "Bu" },
{ "Hn", "Bt", "Cg", "Bu", "Eh" },
{ "Hn", "Kh", "Cg", "Bu", "Eh" },
{ "Bu", "Kh", "", "Zu", "" },
{ "Hn", "", "", "", "" }
};
}
private void fillRoom39() {
shortTeacher = new String[][] {
{ "Bd", "Do", "Cg", "Bd", "Gi" },
{ "Bd", "Do", "Cg", "Bd", "Gi" },
{ "Bd", "Zu", "Cg", "Bd", "Gr" },
{ "Bd", "Zu", "Cg", "Bd", "Gr" },
{ "Bd", "Zu", "Bu", "Or", "Gi" },
{ "Lunch", "Lunch", "Lunch", "Lunch", "Lunch" },
{ "Lunch", "Lunch", "Lunch", "Lunch", "Lunch" },
{ "Lu", "Se", "Gi", "Le", "Hi" },
{ "Lu", "Se", "Gi", "Le", "Hi" },
{ "Lu", "Se", "Gi", "Le", "Hi" },
{ "Lu", "Se", "Gi", "", "" }
};
}
public String getLesson(int lesson, int day) {
if (lesson < 0 || lesson >= 11 || day < 0 || day >= 5) {
throw new IllegalArgumentException("Invalid lesson or day");
}
return shortTeacher[lesson][day];
}
}

View file

@ -0,0 +1,7 @@
{
"java.project.sourcePaths": ["src"],
"java.project.outputPath": "bin",
"java.project.referencedLibraries": [
"lib/**/*.jar"
]
}

View file

@ -0,0 +1,18 @@
## Getting Started
Welcome to the VS Code Java world. Here is a guideline to help you get started to write Java code in Visual Studio Code.
## Folder Structure
The workspace contains two folders by default, where:
- `src`: the folder to maintain sources
- `lib`: the folder to maintain dependencies
Meanwhile, the compiled output files will be generated in the `bin` folder by default.
> If you want to customize the folder structure, open `.vscode/settings.json` and update the related settings there.
## Dependency Management
The `JAVA PROJECTS` view allows you to manage your dependencies. More details can be found [here](https://github.com/microsoft/vscode-java-dependency#manage-dependencies).

View file

@ -0,0 +1,22 @@
public static void main(String[] args) {
try {
// Example input for generating the URL
String channelId = "123456"; // Replace with your actual channel ID
String apiKey = "YOUR_READ_API_KEY"; // Replace with your actual API key
int results = 50; // Fetch 50 records
String start = "2024-11-01 00:00:00"; // Start date-time
String end = "2024-11-01 23:59:59"; // End date-time
String timezone = "Europe/Zurich"; // Timezone
// Generate the dynamic URL using the method
String url = createThingSpeakURL(channelId, apiKey, results, start, end, timezone);
// Output the generated URL
System.out.println("Generated ThingSpeak URL: ");
System.out.println(url);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,87 @@
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ThingSpeakURLGenerator {
// Constants for Room channel numbers
private static final int ROOM_39_NUMBER = 1521262;
private static final int ROOM_38_NUMBER = 1364580;
private static final int ROOM_37_NUMBER = 1521263;
// Example Dates for fetching data, dynamically generated
private static final LocalDateTime START_DATE = LocalDateTime.of(2024, 11, 1, 0, 0);
private static final LocalDateTime END_DATE = LocalDateTime.of(2024, 11, 1, 23, 59);
// Room URLs
private static final Map<Integer, String> ROOM_URLS = new HashMap<>();
static {
ROOM_URLS.put(39, createUrl(ROOM_39_NUMBER));
ROOM_URLS.put(38, createUrl(ROOM_38_NUMBER));
ROOM_URLS.put(37, createUrl(ROOM_37_NUMBER));
}
// Method to create the ThingSpeak API URL dynamically
public static String createUrl(int channelNumber) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String startDate = encodeUrlParam(START_DATE.format(formatter));
String endDate = encodeUrlParam(END_DATE.format(formatter));
return String.format("https://api.thingspeak.com/channels/%d/feeds.csv?start=%s&end=%s",
channelNumber, startDate, endDate);
}
// Helper method to URL encode the date strings
private static String encodeUrlParam(String value) {
try {
return URLEncoder.encode(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
System.err.println("Error encoding URL parameter: " + e.getMessage());
return value;
}
}
// Method to calculate the average of a specific number of data points (e.g.,
// CO2 levels)
public static double calculateAverage(List<Co2Data> dataList) {
if (dataList == null || dataList.isEmpty()) {
return 0.0;
}
double sum = 0.0;
for (Co2Data data : dataList) {
sum += data.getCo2Level(); // Assuming Co2Data has a method getCo2Level() that returns the CO2 level
}
return sum / dataList.size();
}
public static void main(String[] args) {
try {
// Print out the generated URLs for each room
for (Map.Entry<Integer, String> entry : ROOM_URLS.entrySet()) {
System.out.println("Room " + entry.getKey() + " URL: " + entry.getValue());
}
// Example: Calculate and print the average CO2 level for each room (assuming
// Co2Data.getData() method exists)
List<Co2Data> room39Data = Co2Data.getData(ROOM_URLS.get(39));
List<Co2Data> room38Data = Co2Data.getData(ROOM_URLS.get(38));
List<Co2Data> room37Data = Co2Data.getData(ROOM_URLS.get(37));
double avgRoom39 = calculateAverage(room39Data);
double avgRoom38 = calculateAverage(room38Data);
double avgRoom37 = calculateAverage(room37Data);
System.out.println("Average CO2 Level in Room 39: " + avgRoom39);
System.out.println("Average CO2 Level in Room 38: " + avgRoom38);
System.out.println("Average CO2 Level in Room 37: " + avgRoom37);
} catch (Exception e) {
e.printStackTrace();
}
}
}

Binary file not shown.

View file

@ -0,0 +1,9 @@
Notizen zum Auftrag:
Das Word-Dokument ist in der Webview etwa 1 1/4 Seiten lang, während es in der Desktop-App genau eine Seite umfasst, wie von mir geplant.
Die GUI-Elemente wurden bereits erklärt.
Die GUI weist noch einige Imperfektionen auf, die während der Entwicklung in JavaFX besser behoben werden können als in Adobe XD.
Das Wireframe wurde in Adobe XD erstellt, da ich es bevorzuge, ohne aktives Internet an solchen Projekten zu arbeiten. Das Internet wurde nur für die Suche nach Büchern, deren Beschreibung und Bildern verwendet.