From 4b7da2645370361dfdb175129a24369e0cc0f977 Mon Sep 17 00:00:00 2001 From: Abdellah El Morabit Date: Sun, 24 Nov 2024 01:31:48 +0100 Subject: worked on the GUI for the application, added a couple of new features, updated the readme, added a quotes file for making a daily quote feature thats going to reset at midnight, also did some small bug fixing --- bin/display.c | 30 --------------- bin/display_driver.c | 53 +++++++++++++++++++++++++ bin/gtk_app | Bin 0 -> 51400 bytes bin/hardware_driver.py | 68 +++++++++++++++++++++++++++++++++ bin/i2c.py | 68 --------------------------------- bin/main.py | 102 ++++++++++++++++++++++++++++++++++++++++++------- bin/quotes.txt | 30 +++++++++++++++ 7 files changed, 240 insertions(+), 111 deletions(-) delete mode 100644 bin/display.c create mode 100644 bin/display_driver.c create mode 100755 bin/gtk_app create mode 100644 bin/hardware_driver.py delete mode 100644 bin/i2c.py create mode 100644 bin/quotes.txt diff --git a/bin/display.c b/bin/display.c deleted file mode 100644 index b960ff1..0000000 --- a/bin/display.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - - -static void activate(GtkApplication *app, gpointer user_data) { - // Create a new application window - GtkWidget *window = gtk_application_window_new(app); - gtk_window_set_title(GTK_WINDOW(window), "I2C CONTROLLER"); - gtk_window_set_default_size(GTK_WINDOW(window), 400, 200); - - // Show the window - gtk_window_present(GTK_WINDOW(window)); -} - -int main(int argc, char *argv[]) { - // Create a new GtkApplication - GtkApplication *app = gtk_application_new("com.example.GTK4Test", G_APPLICATION_FLAGS_NONE); - - // Connect the activate signal - g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); - - // Run the application - int status = g_application_run(G_APPLICATION(app), argc, argv); - - // Clean up - g_object_unref(app); - - return status; -} diff --git a/bin/display_driver.c b/bin/display_driver.c new file mode 100644 index 0000000..04f2900 --- /dev/null +++ b/bin/display_driver.c @@ -0,0 +1,53 @@ +#include +#include +#include + +// Define the features array +char *features[] = {"recourses", "greeting", "pomodoro", "weather", "speech", "command center"}; + +// Function to create a button with a label +void create_button(const char *label) { + GtkWidget *button = gtk_button_new_with_label(label); + // You can set the button properties or add it to a container here + g_print("Button created: %s\n", label); // For debugging purposes +} + +static void activate(GtkApplication *app, gpointer user_data) { + // Create the window + GtkWidget *window = gtk_application_window_new(app); + gtk_window_set_title(GTK_WINDOW(window), "I2C CONTROLLER"); + gtk_window_set_default_size(GTK_WINDOW(window), 400, 400); + + // Create a container for buttons (e.g., vertical box) + GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5); + gtk_container_add(GTK_CONTAINER(window), vbox); + + // Calculate the number of features + int features_count = sizeof(features) / sizeof(features[0]); + + // Create a button for each feature + for (int i = 0; i < features_count; i++) { + GtkWidget *button = gtk_button_new_with_label(features[i]); + gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); + gtk_widget_set_size_request(button, 200, 100); + } + + // Show all widgets + gtk_widget_show_all(window); +} + +int main(int argc, char *argv[]) { + // Create the application + GtkApplication *app = gtk_application_new("com.example.GTK4Test", G_APPLICATION_FLAGS_NONE); + + // Connect the "activate" signal to the callback function + g_signal_connect(app, "activate", G_CALLBACK(activate), NULL); + + // Run the application + int status = g_application_run(G_APPLICATION(app), argc, argv); + + // Clean up + g_object_unref(app); + + return status; +} diff --git a/bin/gtk_app b/bin/gtk_app new file mode 100755 index 0000000..4d1dc8c Binary files /dev/null and b/bin/gtk_app differ diff --git a/bin/hardware_driver.py b/bin/hardware_driver.py new file mode 100644 index 0000000..1afb219 --- /dev/null +++ b/bin/hardware_driver.py @@ -0,0 +1,68 @@ +from smbus2 import SMBus +from time import sleep + +ALIGN_FUNC = {"left": "ljust", "right": "rjust", "center": "center"} +CLEAR_DISPLAY = 0x01 +ENABLE_BIT = 0b00000100 +LINES = {1: 0x80, 2: 0xC0, 3: 0x94, 4: 0xD4} + +LCD_BACKLIGHT = 0x08 +LCD_NOBACKLIGHT = 0x00 + + +class LCD(object): + + def __init__(self, address=0x27, bus=1, width=20, rows=4, backlight=True): + self.address = address + self.bus = SMBus(bus) + self.delay = 0.0005 + self.rows = rows + self.width = width + self.backlight_status = backlight + + self.write(0x33) + self.write(0x32) + self.write(0x06) + self.write(0x0C) + self.write(0x28) + self.write(CLEAR_DISPLAY) + sleep(self.delay) + + def _write_byte(self, byte): + self.bus.write_byte(self.address, byte) + self.bus.write_byte(self.address, (byte | ENABLE_BIT)) + sleep(self.delay) + self.bus.write_byte(self.address, (byte & ~ENABLE_BIT)) + sleep(self.delay) + + def write(self, byte, mode=0): + backlight_mode = LCD_BACKLIGHT if self.backlight_status else LCD_NOBACKLIGHT + self._write_byte(mode | (byte & 0xF0) | backlight_mode) + self._write_byte(mode | ((byte << 4) & 0xF0) | backlight_mode) + + def text(self, text, line, align="left"): + self.write(LINES.get(line, LINES[1])) + text, other_lines = self.get_text_line(text) + text = getattr(text, ALIGN_FUNC.get(align, "ljust"))(self.width) + for char in text: + self.write(ord(char), mode=1) + if other_lines and line <= self.rows - 1: + self.text(other_lines, line + 1, align=align) + + def backlight(self, turn_on=True): + self.backlight_status = turn_on + self.write(0) + + def get_text_line(self, text): + line_break = self.width + if len(text) > self.width: + line_break = text[: self.width + 1].rfind(" ") + if line_break < 0: + line_break = self.width + return text[:line_break], text[line_break:].strip() + + def clear(self): + self.write(CLEAR_DISPLAY) + + def read(self): + self._read_i2c_block_data diff --git a/bin/i2c.py b/bin/i2c.py deleted file mode 100644 index 1afb219..0000000 --- a/bin/i2c.py +++ /dev/null @@ -1,68 +0,0 @@ -from smbus2 import SMBus -from time import sleep - -ALIGN_FUNC = {"left": "ljust", "right": "rjust", "center": "center"} -CLEAR_DISPLAY = 0x01 -ENABLE_BIT = 0b00000100 -LINES = {1: 0x80, 2: 0xC0, 3: 0x94, 4: 0xD4} - -LCD_BACKLIGHT = 0x08 -LCD_NOBACKLIGHT = 0x00 - - -class LCD(object): - - def __init__(self, address=0x27, bus=1, width=20, rows=4, backlight=True): - self.address = address - self.bus = SMBus(bus) - self.delay = 0.0005 - self.rows = rows - self.width = width - self.backlight_status = backlight - - self.write(0x33) - self.write(0x32) - self.write(0x06) - self.write(0x0C) - self.write(0x28) - self.write(CLEAR_DISPLAY) - sleep(self.delay) - - def _write_byte(self, byte): - self.bus.write_byte(self.address, byte) - self.bus.write_byte(self.address, (byte | ENABLE_BIT)) - sleep(self.delay) - self.bus.write_byte(self.address, (byte & ~ENABLE_BIT)) - sleep(self.delay) - - def write(self, byte, mode=0): - backlight_mode = LCD_BACKLIGHT if self.backlight_status else LCD_NOBACKLIGHT - self._write_byte(mode | (byte & 0xF0) | backlight_mode) - self._write_byte(mode | ((byte << 4) & 0xF0) | backlight_mode) - - def text(self, text, line, align="left"): - self.write(LINES.get(line, LINES[1])) - text, other_lines = self.get_text_line(text) - text = getattr(text, ALIGN_FUNC.get(align, "ljust"))(self.width) - for char in text: - self.write(ord(char), mode=1) - if other_lines and line <= self.rows - 1: - self.text(other_lines, line + 1, align=align) - - def backlight(self, turn_on=True): - self.backlight_status = turn_on - self.write(0) - - def get_text_line(self, text): - line_break = self.width - if len(text) > self.width: - line_break = text[: self.width + 1].rfind(" ") - if line_break < 0: - line_break = self.width - return text[:line_break], text[line_break:].strip() - - def clear(self): - self.write(CLEAR_DISPLAY) - - def read(self): - self._read_i2c_block_data diff --git a/bin/main.py b/bin/main.py index 17b506d..bf556ca 100644 --- a/bin/main.py +++ b/bin/main.py @@ -2,12 +2,13 @@ import time import os import speech_recognition as speech import sounddevice -import i2c as lcd +import bin.hardware_driver as lcd from gpiozero import CPUTemperature ERROR_BAD_REQUEST = "400 Bad Request" ERROR_UNAUTHORIZED = "401 Unauthorized" ERROR_NOT_FOUND = "404 Not Found" +SPEECH_NOT_RECOGNIZED = "404-1 Speech is not recognized" ERROR_TIMEOUT = "408 Request Timeout" lcd_instance = lcd.LCD() @@ -16,7 +17,46 @@ recognizer = speech.Recognizer() microphone = speech.Microphone() -def display_cpu_info(): +# greeting that starts upon the boot of the device: +# shows a hello line; shorter than 16 chars +# and some small information on the second line +def custom_greeting(): + with open('quotes.txt', 'r') as file: + quotes = file.readlines() + + # Strip newline characters and use the quotes + quotes = [quote.strip() for quote in quotes] + + # Print the quotes + for quote in quotes: + print(quote) + first_line = "" + second_line = "" + count = 0 + for i in quote: + if count < 16: + first_line += i + count += 1 + else: + second_line += i + lcd.text(first_line,1) + lcd.text(secon_line,2) +def pomodoro(): + time = input("How long do you want to wait? : ") + print("Okay \nStarting Now...") + while time > 0: + time.sleep(1) + print(time + "Seconds") + lcd.text(time + " Seconds remaining...", 1) + time -= 1 + + +def weather(): + pass + + +# ram usage, internet speed, +def system_readings(): lcd_instance.clear() while True: load = os.getloadavg()[0] @@ -37,6 +77,7 @@ def display_uptime(): def recognize_speech(): + lcd_instance.clear() try: with microphone as source: @@ -46,6 +87,7 @@ def recognize_speech(): text = recognizer.recognize_google(audio) lcd_instance.clear() lcd_instance.text(text, 1) + print("Speech recognized:", text) except speech.UnknownValueError: lcd_instance.text(ERROR_BAD_REQUEST, 1) @@ -54,6 +96,8 @@ def recognize_speech(): lcd_instance.text(ERROR_UNAUTHORIZED, 1) print(ERROR_UNAUTHORIZED) + return text + def save_notes(): print("Type your notes (type 'stop' to exit):") @@ -61,32 +105,64 @@ def save_notes(): while True: line = 1 output = input(":") + output_length = len(output) if output.lower() in ["stop", "break", "quit", "exit"]: break if output == "line=1": line = 1 elif output == "line=2": line = 2 - lcd_instance.text(output, line) - time.sleep(2) + + if output_length < 16: + lcd_instance.text(output, line) + time.sleep(2) + else: + output_list = output.split("") + first_line = "" + second_line = "" + for i in output_list: + count = 0 + if count > 16: + first_line += output_list[i] + count += 1 + else: + second_line += output_list[i] + lcd.text(first_line,1) + lcd.text(secon_line,2) + +def command_center(commands): + # checking if we can reconize commands within the user speech + # requires -> + # converting the commands to human readable text + # no under scars + command = recognize_speech() + list = [] + try: + for i in commands: + if i == command: + print("I think i found what you ment...") + command() + except: + print("ERROR 404 - COMMAND NOT RECOGNIZED") -OPTIONS = { - "CPU_INFO": display_cpu_info, - "UPTIME": display_uptime, - "SPEECH_TRANSCRIBER": recognize_speech, - "NOTES": save_notes, -} +FEATURES = { + "READINGS": system_readings, + "UPTIME": display_uptime, + "SPEECH_TRANSCRIBER": recognize_speech, + "NOTES": save_notes, + "COMMAND CENTER": command_center, + } def main(): lcd_instance.clear() - print("WELCOME TO THE I2C COMMAND LINE CENTER") - print("Options:", ", ".join(OPTIONS.keys())) + os.system("cls" if os.name == "nt" else "clear") + print("FEATURES:", ", ".join(FEATURES.keys())) while True: user_input = input("Enter command: ").upper() - action = OPTIONS.get(user_input) + action = FEATURES.get(user_input) if action: action() diff --git a/bin/quotes.txt b/bin/quotes.txt new file mode 100644 index 0000000..a6c9d84 --- /dev/null +++ b/bin/quotes.txt @@ -0,0 +1,30 @@ +“Code is like humor, it’s better if it’s clean.” +“Software is a great combination.” +“Computers are like a bicycle for the mind.” +“Simplicity is the soul of efficiency.” +“Good code is its own best documentation.” +“In programming, clarity is key.” +“Programs must be written for people.” +“Computers are only tools.” +“The best way to predict the future is to invent it.” +“Talk is cheap. Show me the code.” +"It’s not a bug, it’s a feature.” +“The computer is mightier than the pen.” +"Code is the art of telling computers what to do.” +"Make it work, make it right, make it fast.” +“Every problem can be solved with code.” +“The only limit is your imagination.” +“Programming is thinking, not typing.” +"Design is the soul of programming.” +“There’s no place like 127.0.0.1.” +“Without algorithms, there’s no solution.” +“Compilers turn ideas into machine code.” +“A program is only as good as its design.” +"Code never lies, comments sometimes do.” +“Debugging is twice as hard as writing.” +"Computers don’t make mistakes, programmers do.” +“Code fast, debug slow, optimize last.” +“Keep it simple, stupid (KISS).” +“Without testing, code is poetry.” +“Good software comes from great design.” +“The harder you work, the luckier you get.” -- cgit v1.2.3-70-g09d2