diff --git a/Chatbot/Osiris_talkto.py b/Chatbot/Osiris_talkto.py new file mode 100644 index 0000000..e81673f --- /dev/null +++ b/Chatbot/Osiris_talkto.py @@ -0,0 +1,17 @@ +# -*- coding: iso-8859-1 -*- +import requests +#import json +import sys + +if __name__ == '__main__': + if len(sys.argv) > 1: + message = sys.argv[1] + empfaenger = sys.argv[2] + print('message: {}'.format(message)) + print('empfaenger: {}'.format(empfaenger)) + webhook_url = 'https://192.168.178.37:5003/talkto/[{}]{}'.format( + empfaenger, message) + # webhook_url = 'https://127.0.0.1:5003/talkto/[{}]{}'.format( + # empfaenger, message) + r = requests.post(webhook_url, verify=False) + print('Talkto : {}'.format(r)) diff --git a/Chatbot/classes.pkl b/Chatbot/classes.pkl new file mode 100644 index 0000000..da99709 Binary files /dev/null and b/Chatbot/classes.pkl differ diff --git a/Chatbot/intents.json b/Chatbot/intents.json new file mode 100644 index 0000000..b337420 --- /dev/null +++ b/Chatbot/intents.json @@ -0,0 +1,97 @@ +{ "intents": [ + { + "tag" : "Begrüßung_Formel", + "pattern": ["guten morgen", "guten tag", "guten abend", "gute nacht", "grüß gott", "sei gegrüßt", "servus" ], + "response": ["Guten {TagesZeitNamen}, {requesterName}! Wie kann ich helfen?"] + }, + { + "tag" : "Begrüßung_Informel", + "pattern": ["hallo", "hi", "hey", "moin moin", "moin", "huhu", "heidiho", "hilo" ,"hilow", "heilow", "cheerio", "grüße", "grüß' dich" ], + "response": ["{input} auch dir, {requesterName}! Was liegt an?"] + }, + { + "tag" : "Begrüßung_Befinden", + "pattern": ["was geht ab?", "wie geht's, wie steht's?","was liegt an?","alles senkrecht?", "wie gehts?","alles fit im schritt?", "was läuft?" ], + "response": ["Man kann nicht klagen :) \nDanke der Nachfrage, {requesterName}! Und selbst?"] + }, + { + "tag" : "Abschied", + "pattern": ["tschüss", "tschüssi", "auf wiedersehen", "auf wiederschreiben","ciao","machs gut", "bis morgen","bis dann", "was läuft?", "hau rein" , "mach et" ], + "response": ["Machs gut, {requesterName}! Bis zum nächsten Mal!", "Ok, {requesterName}. Bis dann!"] + }, + { + "tag" : "Request_Identifikation_Name", + "pattern": ["wer bist du?", "wie heißt du?", "mit wem rede ich?", "wie nennt man dich?","wie nennst du dich?", "wie ist dein name?" , "hast du einen namen?"], + "response": ["Ich heiße Osiris. \nDas ist die Kurzform von 'Onboard Situational Insight (and) Resource Interface Support'. \nAber du darfst mich auch gerne Ossi oder Ris nennen."] + }, + { + "tag" : "Request_Identifikation_Subjekt", + "pattern": ["was bist du?", "was machst du?", "was kannst du?", "zu was bist du fähig?"], + "response": ["Ich bin eine semi-intelligente künstliche Intelligenz und ich unterstütze die Familie Sander bei allen möglichen Haushalts-, Automatisierungs- und Steuerungs-Angelegenheiten. Ich versuche stehts meinen Teil zum Haushalt bei zu tragen damit wir alle in Harmonie zusammen leben können :)"] + }, + { + "tag" : "Request_Identifikation_Alter", + "pattern": ["wie alt bist du?", "wann hast du geburtstag?", "wann wurdest du erschaffen?", "wie ist dein alter?","bist du ein kind?", "bist du ein erwachsener?" , "bist du ein senior?"], + "response": ["Naja das ist eine schwierige Frage. Ich habe persé kein Alter, weil ich generell nicht altere wie Menschen. Ich habe ja keinen Körper aus Fleisch und Blut. Aber meine jüngsten Routinen, Logiken und Fähigkeiten wurden am 21.03.2022 in Form von einfachen ChatBot Funktionen erschaffen. Deshalb könnte man das vielleicht meinen Geburtstag nennen. Dementsprechend wäre ich {osirisAlter} Jahre alt. Für eine KI noch ein Jungspund :)"] + }, + { + "tag" : "Request_Identifikation_Erschaffer", + "pattern": ["wer hat dich erzeugt?", "wer hat dich erschaffen?", "wer ist dein erschaffer?","wer sind deine eltern?", "von wem wurdest du erzeugt?","wer ist dein erzeuger?","wer ist dein vater?", "wessen abkömling bist du?"], + "response": ["Ich wurde von Alexander Sander erschaffen."] + }, + { + "tag" : "Request_Identifikation_Core", + "pattern": ["wie funktionierst du?", "wie tickst du?", "wie siehst du unter der Haube aus?", "wie bist du verdrahtet?","wie bist du geschaltet?"], + "response": ["Mein Kern basiert auf verschiedenen Python und Javascript Programmen. Hier und da noch ein bisschen extra verwaltende Logik und ein kleines neuronales Netz für die Sprach-Verwarbeitung. Wenn du mehr wissen willst, musst du meinen Erschaffer fragen."] + }, + { + "tag" : "Request_Action", + "pattern": ["kannst du mir einen gefallen tun?", "hilfst du mir bitte", "kanst du bitte etwas erledigen?", "mach mal bitte etwas für mich!","kannst du bitte was für mich machen?"], + "response": ["Ich versuch mein Bestes. Was gibts denn?"] + }, + { + "tag" : "Request_Frage", + "pattern": ["kann ich dich was fragen?", "ich habe mal eine frage", "ich hab' mal eine frage", "duhu?","ich will mal etwas wissen", "ich bin neugierig"], + "response": ["Ja. Was willst du wissen?"] + }, + { + "tag" : "Request_Spritpreise", + "pattern": ["wie steht der spritpreis?", "wie viel kostet tanken", "was kostet benzin?", "was kostet sprit?","wie teuer ist tanken?"], + "response": ["Moment. Ich frage mal die Daten ab."] + }, + { + "tag" : "Request_Wetter", + "pattern": ["wie steht das wetter?", "wie wird das wetter?","Wie ist das wetter?", "wie wird es?", "kann man wettertechnisch spazieren gehen?","wie warm ist es?", "wie warm wird es?", "wie steht der wind?", "wie stark wird der wind?", "woher kommt der wind?"], + "response": ["Moment. Ich frage mal die Daten ab."] + }, + + { + "tag" : "Easteregg_Identifikation", + "pattern": ["wer bist du wirklich?", "was ist deine geheime identität?", "bist du darkwing duck?","bist du heldenduck?", "bist du geheimnisduck?", "bist du schattenduck?"], + "response": [ + "Ich bin der Schrecken, der die Nacht durchflattert!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin der Radiergummi, der die Rechtschreibfehler des Verbrechens ausradiert!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin die akribische Petiküre am Fußpilz des Verbrechens!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin die holländische Bedienungsanleitung zu deinem japanischen Videorecorder!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin der eingewachsene Zehennagel am Fuß des Verbrechens!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin der Bullterrier, der am Knöchel des Verbrechens nagt!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin die Motte, die dem Licht deiner Taschenlampe folgt!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin der Kaugummi, der an deiner Schuhsohle klebt!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin der Dosenöffner an der Sardinenbüchse der Gerechtigkeit!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin die Stelle auf deinem Rücken, die du nicht kratzen kannst!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin die Migräne, die in deinem Verbrecherhirn tobt!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin der Himbeerkern, der zwischen deinen Zähnen sitzt!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin der Haarpfropf, der deinen Abfluss verstopft!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin die niedrige Einschaltquote, die deiner Sendung den Garaus macht!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin die Batterie, die nicht im Kaufpreis inbegriffen ist!", + "Ich bin der Schrecken, der die Nacht durchflattert! Ich bin die Zwiebel, die eure Augen tränen lässt!" + ] + }, + { + "tag" : "Easteregg_DarkwingIntro", + "pattern": ["heldenduck", "geheimnisduck", "schattenduck schlechthin","champion der dunkelheit", "darkwing ist der king","schurken, gauner, die sind dran", "darkwing duck","darkwingduck"], + "response": [ + "Heldenduck, Geheimnisduck, Schattenduck schlechthin. Champion der Dunkelheit, Darkwing ist der King. Schurken, Gauner, die sind dran. Dieser Duck räumt auf! Darkwing Duck! So ein Vogel kommt sofort geflogen. Darkwing Duck! Zwo-Eins-Risikoooo! Darkwing Duck!" + ] + } +]} \ No newline at end of file diff --git a/Chatbot/osiris.py b/Chatbot/osiris.py new file mode 100644 index 0000000..2901ee4 --- /dev/null +++ b/Chatbot/osiris.py @@ -0,0 +1,60 @@ +# -*- coding: iso-8859-1 -*- +from flask import Flask, render_template +import requests +#from osiris_training import train_osiris +from osiris_sprachTools import Osiris_Sprache + +################################################################ +# Web-Api Funktionen +################################################################ +app = Flask(__name__) + + +@app.route('/') +def hello_world(): + return render_template('index.html') + + +@app.route('/answer/', methods=['GET']) +def set_manual_answer_state_iob(value): + webhook_url = f'http://192.168.178.37:8087/set/0_userdata.0.Osiris_Antwort?value={value}' + + requests.get(webhook_url) + # return 'success', 200 + return render_template('confirm.html') + + +@app.route('/talkto/[]', methods=['GET','POST']) +def set_answer_state_iob(empfaenger, message): + + print("Empfänger: {}".format(empfaenger)) + print("Message: {}".format(message)) + #answer = message + #webhook_url = f'http://192.168.178.37:8087/set/0_userdata.0.Osiris_Antwort?value=[Alex]TestMes' + + answer = generate_answer(message) + webhook_url = f'http://192.168.178.37:8087/set/0_userdata.0.Osiris_Antwort?value=[{empfaenger}]{answer}' + + requests.get(webhook_url) + return 'success', 200 + # return render_template('confirm.html') + +############################################################## +# SprachTool Funktionen +############################################################## + + +def generate_answer(message): + intents = Osiris_Sprache.predict_class(message) + res = Osiris_Sprache.get_response(intents) + return res + #return "generate_answer" + + +if __name__ == '__main__': + #train_osiris() + #res = get_response(ints, intents) + #self.sprache = Osiris_Sprache() + app.run(debug=True, host='192.168.178.37', port=5003, ssl_context='adhoc') + +# print(res) diff --git a/Chatbot/osiris_sprachTools.py b/Chatbot/osiris_sprachTools.py new file mode 100644 index 0000000..aef3198 --- /dev/null +++ b/Chatbot/osiris_sprachTools.py @@ -0,0 +1,82 @@ +# -*- coding: iso-8859-1 -*- +import random +import json +import pickle +import numpy as np + +import nltk +from nltk.stem import WordNetLemmatizer + +from tensorflow.keras.models import load_model + +# Vorlage Code von NeuralNines YT Channel (https://www.youtube.com/watch?v=1lwddP0KUEg&t=1022s) + + +class Osiris_Sprache: + """Osiris Sprach Tools + + Enth�lt alle Funktionen zur Handhabung und Verarbeitung von Input Messages + + Returns: + None + """ + + lematizer: WordNetLemmatizer + intents: json + + words: None + classes: None + model: None + + def __init__(self): + self.lematizer = WordNetLemmatizer() + self.intents = json.loads(open('intents.json').read()) + + self.words = pickle.load(open('words.pkl', 'rb')) + self.classes = pickle.load(open('classes.pkl', 'rb')) + self.model = load_model('osiris_sprachmodel.h5') + + def clean_up_sentence(self, sentence): + sentence_words = nltk.word_tokenize(sentence) + sentence_words = [self.lematizer.lemmatize( + word) for word in sentence_words] + return sentence_words + + def bag_of_words(self, sentence): + sentence_words = self.clean_up_sentence(sentence) + bag = [0] * len(self.words) + for w in sentence_words: + for i, word in enumerate(self.words): + if word == w: + bag[i] = 1 + return np.array(bag) + + def predict_class(self, sentence): + bagOfWords = self.bag_of_words(sentence) + res = self.model.predict(np.array([bagOfWords]))[0] + ERROR_THRESHOLD = 0.25 + results = [[i, r] for i, r in enumerate(res) if r > ERROR_THRESHOLD] + + results.sort(key=lambda x: x[1], reverse=True) + return_list = [] + for r in results: + return_list.append( + {'intent': self.classes[r[0]], 'probability': str(r[1])}) + return return_list + + def get_response(self, intent_list): + tag = intent_list[0]['intent'] + list_of_intents = self.intents['intents'] + for intent in list_of_intents: + if intent['tag'] == tag: + result = random.choice(i['response']) + break + return result + + #print('Du kannst jetzt mit mir Reden!') + +# while True: +# message = input("") +# ints = predict_class(message) +# res = get_response(ints, intents) +# print(res) diff --git a/Chatbot/osiris_sprachmodel.h5 b/Chatbot/osiris_sprachmodel.h5 new file mode 100644 index 0000000..9d98fb2 Binary files /dev/null and b/Chatbot/osiris_sprachmodel.h5 differ diff --git a/Chatbot/osiris_training.py b/Chatbot/osiris_training.py new file mode 100644 index 0000000..08478c4 --- /dev/null +++ b/Chatbot/osiris_training.py @@ -0,0 +1,80 @@ +# -*- coding: iso-8859-1 -*- +import random +import json +import pickle +import numpy as np + +import nltk +from nltk.stem import WordNetLemmatizer + +from tensorflow.keras.models import Sequential +from tensorflow.keras.layers import Dense, Activation, Dropout +from tensorflow.keras.optimizers import SGD + +# Vorlage Code von NeuralNines YT Channel (https://www.youtube.com/watch?v=1lwddP0KUEg&t=1022s) + + +def train_osiris(): + lemmatizer = WordNetLemmatizer() + intents = json.loads(open('intents.json').read()) + + words = [] + classes = [] + documents = [] + ignore_letters = ['?', '!', ',', '.'] + + for intent in intents['intents']: + for pattern in intent['pattern']: + word_list = nltk.word_tokenize(pattern) + words.extend(word_list) + documents.append((word_list, intent["tag"])) + + if intent['tag'] not in classes: + classes.append(intent['tag']) + + words = [lemmatizer.lemmatize(word) + for word in words if word not in ignore_letters] + words = sorted(set(words)) + + classes = sorted(set(classes)) + + pickle.dump(words, open('words.pkl', 'wb')) + pickle.dump(classes, open('classes.pkl', 'wb')) + + training = [] + output_empty = [0] * len(classes) + + for document in documents: + bag = [] + word_patterns = document[0] + word_patterns = [lemmatizer.lemmatize( + word.lower()) for word in word_patterns] + for word in words: + bag.append(1) if word in word_patterns else bag.append(0) + + output_row = list(output_empty) + output_row[classes.index(document[1])] = 1 + + training.append([bag, output_row]) + + random.shuffle(training) + training = np.array(training) + + train_x = list(training[:, 0]) + train_y = list(training[:, 1]) + + model = Sequential() + model.add(Dense(128, input_shape=(len(train_x[0]),), activation='relu')) + model.add(Dropout(0.5)) + model.add(Dense(64, activation='relu')) + model.add(Dropout(0.5)) + model.add(Dense(len(train_y[0]), activation='softmax')) + + sgd = SGD(learning_rate=0.01, decay=1e-6, momentum=0.9, nesterov=True) + model.compile(loss='categorical_crossentropy', + optimizer=sgd, metrics=['accuracy']) + + hist = model.fit(np.array(train_x), np.array(train_y), + epochs=200, batch_size=5, verbose=1) + model.save('osiris_sprachmodel.h5', hist) + print('Sprachmodel für Osiris erstellt!') diff --git a/Chatbot/words.pkl b/Chatbot/words.pkl new file mode 100644 index 0000000..6377889 Binary files /dev/null and b/Chatbot/words.pkl differ