diff options
| author | Abdellah El Morabit <nsrddyn@gmail.com> | 2024-11-08 13:28:32 +0100 |
|---|---|---|
| committer | Abdellah El Morabit <nsrddyn@gmail.com> | 2024-11-08 13:28:32 +0100 |
| commit | 4176331a554565be402dcd588002176c0e8ec121 (patch) | |
| tree | d3c2871917f4e7f5700e6b7fee8b5d50cb7f6a94 | |
| parent | e458ed522f45a41cdcef32acc8aee5c340fba504 (diff) | |
i think im gonna keep the cod ehere for now until i can test it on my i2c display at home which owont be until next tuesday
| -rw-r--r-- | bin/kasper_source.py | 210 |
1 files changed, 90 insertions, 120 deletions
diff --git a/bin/kasper_source.py b/bin/kasper_source.py index 50fb48c..f4f7947 100644 --- a/bin/kasper_source.py +++ b/bin/kasper_source.py | |||
| @@ -1,168 +1,138 @@ | |||
| 1 | from smbus2 import SMBus | 1 | from smbus2 import SMBus |
| 2 | from time import sleep | ||
| 3 | from gpiozero import CPUTemperature | 2 | from gpiozero import CPUTemperature |
| 4 | import speech_recognition as sr | 3 | import speech_recognition as sr |
| 5 | import time | ||
| 6 | import os | 4 | import os |
| 5 | import time | ||
| 7 | 6 | ||
| 8 | ALIGN_FUNC = {"left": "ljust", "right": "rjust", "center": "center"} | 7 | # LCD Constants |
| 9 | CLEAR_DISPLAY = 0x01 | ||
| 10 | ENABLE_BIT = 0b00000100 | ||
| 11 | LINES = {1: 0x80, 2: 0xC0, 3: 0x94, 4: 0xD4} | ||
| 12 | |||
| 13 | LCD_BACKLIGHT = 0x08 | 8 | LCD_BACKLIGHT = 0x08 |
| 14 | LCD_NOBACKLIGHT = 0x00 | 9 | LCD_NOBACKLIGHT = 0x00 |
| 10 | ENABLE_BIT = 0b00000100 | ||
| 11 | LINES = {1: 0x80, 2: 0xC0, 3: 0x94, 4: 0xD4} | ||
| 12 | ALIGN_FUNC = {"left": "ljust", "right": "rjust", "center": "center"} | ||
| 15 | 13 | ||
| 16 | ERROR_BAD_REQUEST = "400" | 14 | # Error Messages |
| 17 | ERROR_UNAUTHORIZED = "401" | 15 | ERROR_BAD_REQUEST = "400 Bad Request" |
| 18 | ERROR_NOT_FOUND = "404" | 16 | ERROR_UNAUTHORIZED = "401 Unauthorized" |
| 19 | ERROR_TIMEOUT = "408" | 17 | ERROR_NOT_FOUND = "404 Not Found" |
| 20 | 18 | ERROR_TIMEOUT = "408 Request Timeout" | |
| 21 | 19 | ||
| 22 | class LCD(object): | ||
| 23 | 20 | ||
| 21 | # LCD Control Class | ||
| 22 | class LCD: | ||
| 24 | def __init__(self, address=0x27, bus=1, width=20, rows=4, backlight=True): | 23 | def __init__(self, address=0x27, bus=1, width=20, rows=4, backlight=True): |
| 25 | self.address = address | 24 | self.address = address |
| 26 | self.bus = SMBus(bus) | 25 | self.bus = SMBus(bus) |
| 27 | self.delay = 0.0005 | ||
| 28 | self.rows = rows | ||
| 29 | self.width = width | 26 | self.width = width |
| 27 | self.rows = rows | ||
| 30 | self.backlight_status = backlight | 28 | self.backlight_status = backlight |
| 29 | self.delay = 0.0005 | ||
| 31 | 30 | ||
| 32 | self.write(0x33) | 31 | # LCD Initialization |
| 33 | self.write(0x32) | 32 | for cmd in (0x33, 0x32, 0x06, 0x0C, 0x28, 0x01): |
| 34 | self.write(0x06) | 33 | self.write(cmd) |
| 35 | self.write(0x0C) | 34 | time.sleep(self.delay) |
| 36 | self.write(0x28) | 35 | |
| 37 | self.write(CLEAR_DISPLAY) | 36 | def write(self, byte, mode=0): |
| 38 | sleep(self.delay) | 37 | """Send a command or character to the LCD.""" |
| 38 | backlight = LCD_BACKLIGHT if self.backlight_status else LCD_NOBACKLIGHT | ||
| 39 | self._write_byte(mode | ((byte << 4) & 0xF0) | backlight) | ||
| 39 | 40 | ||
| 40 | def _write_byte(self, byte): | 41 | def _write_byte(self, byte): |
| 42 | """Write a byte to the I2C bus.""" | ||
| 41 | self.bus.write_byte(self.address, byte) | 43 | self.bus.write_byte(self.address, byte) |
| 42 | self.bus.write_byte(self.address, (byte | ENABLE_BIT)) | 44 | self.bus.write_byte(self.address, (byte | ENABLE_BIT)) |
| 43 | sleep(self.delay) | 45 | time.sleep(self.delay) |
| 44 | self.bus.write_byte(self.address, (byte & ~ENABLE_BIT)) | 46 | self.bus.write_byte(self.address, (byte & ~ENABLE_BIT)) |
| 45 | sleep(self.delay) | 47 | time.sleep(self.delay) |
| 46 | 48 | ||
| 47 | def write(self, byte, mode=0): | 49 | def display_text(self, text, line=1, align="left"): |
| 48 | backlight_mode = LCD_BACKLIGHT if self.backlight_status else LCD_NOBACKLIGHT | 50 | """Display text on a specified line with alignment.""" |
| 49 | self._write_byte(mode | ((byte << 4) & 0xF0) | backlight_mode) | ||
| 50 | |||
| 51 | def text(self, text, line, align="left"): | ||
| 52 | self.write(LINES.get(line, LINES[1])) | 51 | self.write(LINES.get(line, LINES[1])) |
| 53 | text, other_lines = self.get_text_line(text) | 52 | aligned_text = getattr(text, ALIGN_FUNC.get(align, "ljust"))(self.width) |
| 54 | text = getattr(text, ALIGN_FUNC.get(align, "ljust"))(self.width) | 53 | for char in aligned_text: |
| 55 | for char in text: | ||
| 56 | self.write(ord(char), mode=1) | 54 | self.write(ord(char), mode=1) |
| 57 | if other_lines and line <= self.rows - 1: | ||
| 58 | self.text(other_lines, line + 1, align=align) | ||
| 59 | 55 | ||
| 60 | def backlight(self, turn_on=True): | 56 | def clear(self): |
| 57 | """Clear the display.""" | ||
| 58 | self.write(0x01) | ||
| 59 | |||
| 60 | def set_backlight(self, turn_on=True): | ||
| 61 | """Toggle backlight on or off.""" | ||
| 61 | self.backlight_status = turn_on | 62 | self.backlight_status = turn_on |
| 62 | self.write(0) | 63 | self.write(0) |
| 63 | 64 | ||
| 64 | def get_text_line(self, text): | ||
| 65 | line_break = self.width | ||
| 66 | if len(text) > self.width: | ||
| 67 | line_break = text[: self.width + 1].rfind(" ") | ||
| 68 | if line_break < 0: | ||
| 69 | line_break = self.width | ||
| 70 | return text[:line_break], text[line_break:].strip() | ||
| 71 | |||
| 72 | def clear(self): | ||
| 73 | self.write(CLEAR_DISPLAY) | ||
| 74 | 65 | ||
| 66 | # Initialize components | ||
| 67 | lcd = LCD() | ||
| 68 | cpu_temp = CPUTemperature() | ||
| 69 | recognizer = sr.Recognizer() | ||
| 70 | microphone = sr.Microphone() | ||
| 75 | 71 | ||
| 76 | LCD_DISPLAY = LCD() | ||
| 77 | VOICE_REC = sr.Recognizer() | ||
| 78 | MIC = sr.Microphone() | ||
| 79 | PROCES_LOAD = os.getloadavg() | ||
| 80 | TIME = time.localtime() | ||
| 81 | CURRENT_TIME = time.strftime("%H:%M:%S", TIME) | ||
| 82 | UPTIME = time.CLOCK_UPTIME() | ||
| 83 | CPU_TEMP = CPUTemperature() | ||
| 84 | 72 | ||
| 85 | # clearing the lcd from any text that was on it before the program started to ensure smooth operations | 73 | # Display Functions |
| 86 | LCD_DISPLAY.clear() | 74 | def display_cpu_info(): |
| 75 | """Display CPU load and temperature on the LCD.""" | ||
| 76 | while True: | ||
| 77 | load = os.getloadavg()[0] # 1-minute load average | ||
| 78 | temperature = cpu_temp.temperature | ||
| 79 | lcd.clear() | ||
| 80 | lcd.display_text(f"CPU Load: {load:.2f}", line=1) | ||
| 81 | lcd.display_text(f"Temp: {temperature:.1f}C", line=2) | ||
| 82 | time.sleep(5) | ||
| 87 | 83 | ||
| 88 | 84 | ||
| 89 | # Listening to the user's voice and putting it into a variable | 85 | def display_uptime(): |
| 90 | def listen_voice(): | 86 | """Display system uptime on the LCD.""" |
| 91 | global audio | 87 | with open("/proc/uptime") as f: |
| 92 | with MIC as source: | 88 | uptime_seconds = float(f.readline().split()[0]) |
| 93 | VOICE_REC.adjust_for_ambient_noise(source) | 89 | uptime_str = time.strftime("%H:%M:%S", time.gmtime(uptime_seconds)) |
| 94 | audio = VOICE_REC.listen(source) | 90 | lcd.clear() |
| 95 | return audio | 91 | lcd.display_text(f"Uptime: {uptime_str}", line=1) |
| 96 | 92 | ||
| 97 | 93 | ||
| 98 | # Transcribing the audio to text and printing it out | 94 | def recognize_speech(): |
| 99 | # Using the Google Speech Recognizer | 95 | """Capture and transcribe speech input.""" |
| 100 | def recognize_speech(audio): | ||
| 101 | try: | 96 | try: |
| 102 | words = VOICE_REC.recognize_google(audio) | 97 | with microphone as source: |
| 103 | LCD_DISPLAY.text(words, 1) | 98 | recognizer.adjust_for_ambient_noise(source) |
| 104 | print(f"Printing on screen: {words}") | 99 | print("Listening...") |
| 100 | audio = recognizer.listen(source) | ||
| 101 | text = recognizer.recognize_google(audio) | ||
| 102 | lcd.clear() | ||
| 103 | lcd.display_text(text, line=1) | ||
| 104 | print("Speech recognized:", text) | ||
| 105 | except sr.UnknownValueError: | 105 | except sr.UnknownValueError: |
| 106 | LCD_DISPLAY.text(ERROR_BAD_REQUEST, 1) | 106 | lcd.display_text(ERROR_BAD_REQUEST, line=1) |
| 107 | print(ERROR_BAD_REQUEST) | 107 | print(ERROR_BAD_REQUEST) |
| 108 | except sr.RequestError: | 108 | except sr.RequestError: |
| 109 | LCD_DISPLAY.text(ERROR_UNAUTHORIZED, 1) | 109 | lcd.display_text(ERROR_UNAUTHORIZED, line=1) |
| 110 | print(ERROR_UNAUTHORIZED) | 110 | print(ERROR_UNAUTHORIZED) |
| 111 | 111 | ||
| 112 | 112 | ||
| 113 | def CPU_INFO(): | 113 | # Main Program Options |
| 114 | print("you chose to display the cpou") | 114 | OPTIONS = { |
| 115 | while True: | 115 | "CPU_INFO": display_cpu_info, |
| 116 | LCD.text( | 116 | "UPTIME": display_uptime, |
| 117 | PROCES_LOAD(), | 117 | "SPEECH_TRANSCRIBER": recognize_speech, |
| 118 | 1, | 118 | } |
| 119 | ) | ||
| 120 | 119 | ||
| 121 | 120 | ||
| 122 | def CPU_LOAD(): | 121 | def main(): |
| 123 | LCD.backlight_mode = True | 122 | # Main program loop to accept user commands. |
| 124 | LCD.text( | 123 | print("WELCOME TO THE I2C COMMAND LINE CENTER") |
| 125 | PROCES_LOAD, | 124 | print("Options:", ", ".join(OPTIONS.keys())) |
| 126 | 1, | ||
| 127 | ) | ||
| 128 | 125 | ||
| 126 | while True: | ||
| 127 | user_input = input("Enter command: ").upper() | ||
| 128 | action = OPTIONS.get(user_input) | ||
| 129 | 129 | ||
| 130 | def NOTES(): | 130 | if action: |
| 131 | count = 0 | 131 | action() |
| 132 | user_notes = input() | 132 | else: |
| 133 | for i in user_notes: | 133 | lcd.display_text(ERROR_NOT_FOUND, line=1) |
| 134 | while count < 20: | 134 | print(ERROR_NOT_FOUND) |
| 135 | LCD_DISPLAY.text( | ||
| 136 | i, | ||
| 137 | 1, | ||
| 138 | ) | ||
| 139 | count += 1 | ||
| 140 | |||
| 141 | |||
| 142 | OPTIONS = [ | ||
| 143 | "CPU_CLOCK", | ||
| 144 | "TIME", | ||
| 145 | "UPTIME", | ||
| 146 | "CPU_TEMP", | ||
| 147 | "CPU_LOAD", | ||
| 148 | "NOTES", | ||
| 149 | "SPEECH_TRANSCRIBER", | ||
| 150 | ] | ||
| 151 | |||
| 152 | |||
| 153 | def PROGRAM(USER_INPUT): | ||
| 154 | print("WELCOME TO THE I2C COMMAND LINE CENTER \n WHAT DO YOU WISH TO DO? ") | ||
| 155 | print(OPTIONS) | ||
| 156 | |||
| 157 | FOUND = False | ||
| 158 | while FOUND == False: | ||
| 159 | |||
| 160 | USER_INPUT = input().upper() | ||
| 161 | for i in OPTIONS: | ||
| 162 | if i == USER_INPUT: | ||
| 163 | FOUND = True | ||
| 164 | else: | ||
| 165 | print(ERROR_NOT_FOUND) | ||
| 166 | 135 | ||
| 167 | 136 | ||
| 168 | PROGRAM() | 137 | if __name__ == "__main__": |
| 138 | main() | ||
