diff --git a/README.md b/README.md
index a9bf07c..2dfe313 100644
--- a/README.md
+++ b/README.md
@@ -3,25 +3,25 @@ Room-Computer is a simple room controller and is basically a controller for your
### Installation
git clone https://github.com/E-Almqvist/roomcomputer.git
-This is written in python, so you will literally only have to clone this repository.
+ pip install -r requirements.txt
-### Configuration
-Create a copy of the file "default-config.py" and name it "config.py" then configure its contents to your needs.
+### Setup and Configuration
+Run the `setup.sh` script in order to copy the necessary files to `~/.config/roomcomputer/`. If you are planning to create a service for the `speech_daemon.py` with systemd; then you can specify its configuration file as the first argument: `speech_daemon.py /path/to/config/config.json`.
-#### Hue Light Controller
-You can create presets in the "presets.py" file. Follow this syntax *(and Python syntax of course)*:
-```python
-PRESETS = {
+#### HUE Lights presets
+You can create presets in the `~/.config/roomcomputer/presets.json` file. Follow this syntax *(and JSON syntax of course)*:
+```json
+{
"mypreset": {
- "color": (178, 199, 255), # RGB, from 0-255
- "brightness": 100 # from 0-255
+ "color": [178, 199, 255],
+ "brightness": 100
},
}
```
### Usage
-#### Hue Light Controller
+#### HUE Remote
--Help page--
'hue' : Display this help page
'hue light (index)' ... : Specify light target, from 1-3
@@ -40,11 +40,12 @@ PRESETS = {
'hue lights set color 255 255 255' : Set all lights colors to white
-----------------
- For convenience, you can create an alias for the script file. Append this to your shells rc file:
- alias hue="/path/to/the/cloned/repo/hue_remote.py"
+For convenience, you can create an alias for the script file. Append this to your shells rc file:
+`alias hue="/path/to/the/cloned/repo/hue_cmd.py"`
Features
-* Hue Light Controller *(hue_remote.py)*
+* HUE Light Controller (command-line) `hue_cmd.py)`
+* HUE Light Controller (voice daemon) `speech_daemon.py`
And more to come!
diff --git a/default-config.json b/default-config.json
new file mode 100644
index 0000000..0bf08f9
--- /dev/null
+++ b/default-config.json
@@ -0,0 +1,10 @@
+{
+ "hue": {
+ "address": "",
+ "username": ""
+ },
+ "speech": {
+ "device_index": 30,
+ "prefixes": ["computer", "computers"]
+ }
+}
diff --git a/default-presets.json b/default-presets.json
new file mode 100644
index 0000000..65cee0f
--- /dev/null
+++ b/default-presets.json
@@ -0,0 +1,41 @@
+{
+ "default": {
+ "color": [178, 199, 255],
+ "brightness": 255
+ },
+
+ "dim": {
+ "color": [178, 199, 255],
+ "brightness": 111
+ },
+
+ "dim": {
+ "color": [178, 199, 255],
+ "brightness": 80
+ },
+
+ "red": {
+ "color": [255, 0, 0],
+ "brightness": 255
+ },
+
+ "green": {
+ "color": [0, 255, 0],
+ "brightness": 255
+ },
+
+ "blue": {
+ "color": [0, 0, 255],
+ "brightness": 255
+ },
+
+ "ice" : {
+ "color": [80, 100, 255],
+ "brightness": 120
+ },
+
+ "sleep": {
+ "color": [185, 155, 25],
+ "brightness": 60
+ }
+}
diff --git a/hue_cmd.py b/hue_cmd.py
new file mode 100755
index 0000000..8a048b9
--- /dev/null
+++ b/hue_cmd.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+from modules.hue.hue_controller import controller
+from modules.hue.hue_remote import parseCommandline
+
+def init():
+ controller.init() # very important to initialize the controller
+ parseCommandline()
+ controller.end() # also to end it
+
+if __name__ == "__main__":
+ init()
diff --git a/hue_remote/default-config.py b/hue_remote/default-config.py
deleted file mode 100644
index 372cacb..0000000
--- a/hue_remote/default-config.py
+++ /dev/null
@@ -1,6 +0,0 @@
-##################################
-# RENAME THIS FILE TO "config.py"#
-##################################
-
-address = ""
-username = ""
diff --git a/hue_remote/presets.py b/hue_remote/presets.py
deleted file mode 100644
index 2a3a0cc..0000000
--- a/hue_remote/presets.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Presets goes in here
-PRESETS = {
- "default": {
- "color": (178, 199, 255),
- "brightness": 255
- },
-
- "dim": {
- "color": (178, 199, 255),
- "brightness": 111
- },
-
- "dim": {
- "color": (178, 199, 255),
- "brightness": 80
- },
-
- "red": {
- "color": (255, 0, 0),
- "brightness": 255
- },
-
- "green": {
- "color": (0, 255, 0),
- "brightness": 255
- },
-
- "blue": {
- "color": (0, 0, 255),
- "brightness": 255
- },
-
- "ice" : {
- "color": ( 80, 100, 255 ),
- "brightness": 120
- },
-
- "sleep": {
- "color": (185, 155, 25),
- "brightness": 60
- }
-}
diff --git a/modules/configloader/__init__.py b/modules/configloader/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/modules/configloader/__init__.py
@@ -0,0 +1 @@
+
diff --git a/modules/configloader/__main__.py b/modules/configloader/__main__.py
new file mode 100644
index 0000000..e69de29
diff --git a/modules/configloader/loader.py b/modules/configloader/loader.py
new file mode 100644
index 0000000..87617db
--- /dev/null
+++ b/modules/configloader/loader.py
@@ -0,0 +1,12 @@
+import json
+
+def readconfig(path):
+ try:
+ with open(path) as cfg:
+ data = json.load(cfg)
+
+ return data
+
+ except:
+ print("[Error] Something went wrong reading the configuration file.")
+ print("--", path)
diff --git a/modules/hue/__init__.py b/modules/hue/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/modules/hue/__main__.py b/modules/hue/__main__.py
new file mode 100644
index 0000000..e69de29
diff --git a/hue_remote/hue_controller.py b/modules/hue/hue_controller.py
similarity index 84%
rename from hue_remote/hue_controller.py
rename to modules/hue/hue_controller.py
index 20bd133..bbc1b4a 100644
--- a/hue_remote/hue_controller.py
+++ b/modules/hue/hue_controller.py
@@ -3,17 +3,22 @@ import json # API uses JSON
import asyncio # ASync stuff
import time
-from lib.func import * # useful functions
+from .lib.func import * # useful functions
-import config # Configuration for the controller (/config.py <- change this file)
-from presets import * # presets for the lights
+from modules.configloader.loader import readconfig # used to read the config files
+from os.path import expanduser # to get the home dir
+
+homedir = expanduser("~") # get the home directory of the current user
LIGHTS = {} # dictionary of all the lights
+CONFIG = {} # the configuration
+PRESETS = {} # the presets
+PRE_URL = "" # prefix
loop = asyncio.get_event_loop() # ASync loop
def genUrl(params: str):
- return "http://" + config.address + "/api/" + config.username + params
+ return PRE_URL + params
class APIrequest:
# Get Req
@@ -142,9 +147,20 @@ class controller:
def delay(n:int):
time.sleep(n)
- def init():
- jsonLights = loop.run_until_complete(APIrequest.get("/lights"))
+ def init( cfgPath="{0}/.config/roomcomputer/config.json".format(homedir), presetPath="{0}/.config/roomcomputer/presets.json".format(homedir) ):
+ config = readconfig(cfgPath)
+ presets = readconfig(presetPath)
+
+ global CONFIG
+ CONFIG = config["hue"]
+ global PRESETS
+ PRESETS = presets
+
+ global PRE_URL
+ PRE_URL = "http://" + CONFIG["address"] + "/api/" + CONFIG["username"]
+
+ jsonLights = loop.run_until_complete(APIrequest.get("/lights"))
global LIGHTS
LIGHTS = json.loads(jsonLights.text)
diff --git a/hue_remote/hue_remote.py b/modules/hue/hue_remote.py
similarity index 82%
rename from hue_remote/hue_remote.py
rename to modules/hue/hue_remote.py
index d0bf730..fc81abd 100755
--- a/hue_remote/hue_remote.py
+++ b/modules/hue/hue_remote.py
@@ -3,7 +3,7 @@
import sys
-import hue_controller as hue # Actual controller
+from modules.hue import hue_controller as hue # Actual controller
cmd = "hue"
@@ -31,8 +31,7 @@ boolConvert = {
# this is the most spaghetti-ish code I have ever written but it works
-def parseCommand( cmd:list, pos:int, i=-1 ):
- index = int(i)
+def parseCommand( cmd:list, pos:int, index=-1, displayHelp=True ):
try:
if( cmd[pos] == "on" or cmd[pos] == "off" ):
if( index == -1 ):
@@ -82,26 +81,18 @@ def parseCommand( cmd:list, pos:int, i=-1 ):
help() # display help if function did nothing
except (RuntimeError, TypeError, NameError, IndexError) as err:
- help() # display the help page if parameters are missing (it will give out an IndexError)
- print( "\n\nError: " + str(err) )
+ if(displayHelp):
+ help() # display the help page if parameters are missing (it will give out an IndexError)
+ print( "\n\nError: " + str(err) )
-def parseCommandline():
- cmd = sys.argv
+def parseCommandline( cmd=sys.argv, needHelp=True ):
if( len(cmd) > 1 ):
if( cmd[1] == "light" ):
- parseCommand( cmd, 3, cmd[2] )
+ parseCommand( cmd, 3, cmd[2], displayHelp=needHelp )
elif( cmd[1] == "lights" ):
- parseCommand( cmd, 2 )
- else:
+ parseCommand( cmd, 2, displayHelp=needHelp )
+ elif( needHelp ):
help()
-
-
-def init():
- hue.controller.init() # very important to initialize the controller
- parseCommandline()
- hue.controller.end() # also to end it
-
-init() # actually call the init function
diff --git a/hue_remote/lib/func.py b/modules/hue/lib/func.py
similarity index 100%
rename from hue_remote/lib/func.py
rename to modules/hue/lib/func.py
diff --git a/modules/speech/__init__.py b/modules/speech/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/modules/speech/__main__.py b/modules/speech/__main__.py
new file mode 100644
index 0000000..e69de29
diff --git a/modules/speech/speech.py b/modules/speech/speech.py
new file mode 100644
index 0000000..1043fc8
--- /dev/null
+++ b/modules/speech/speech.py
@@ -0,0 +1,37 @@
+import speech_recognition as sr
+
+class voiceInput(object):
+ recognizer = sr.Recognizer()
+
+ muted = True
+
+ # "Error codes", can be used to check stuff
+ what = "??"
+ error = "ERROR"
+
+ def start( self, deviceIndex=30 ): # a generator for everything that is said
+ while( True ): # loop
+ try:
+ if( not self.muted ): # this thing is not the NSA
+ with sr.Microphone( deviceIndex ) as src:
+ self.recognizer.adjust_for_ambient_noise( src, 0.2 )
+ print("Listening...")
+ audio = self.recognizer.listen( src, phrase_time_limit=5 )
+ print("Thinking...")
+ text = self.recognizer.recognize_google(audio)
+ yield text
+
+ except sr.RequestError as err:
+ print("Unable to request results: {0}".format(err))
+ yield self.error
+
+ except sr.UnknownValueError:
+ yield self.what
+
+
+ def setMuted( self, setm: bool=True ):
+ self.muted = setm
+
+ def switchMute( self ):
+ self.setMuted( not self.muted )
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..8d2870c
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+SpeechRecognition>=3.8.1
\ No newline at end of file
diff --git a/setup.sh b/setup.sh
new file mode 100755
index 0000000..8b21409
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/bash
+
+cfgPath="$HOME/.config/roomcomputer"
+
+mkdir $cfgPath
+cp default-config.json $cfgPath/config.json
+cp default-presets.json $cfgPath/presets.json
diff --git a/speech/speech.py b/speech/speech.py
deleted file mode 100644
index fa70c3c..0000000
--- a/speech/speech.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import speech_recognition as sr
-
-class sr_microphone(object):
- recognizer = sr.Recognizer()
-
- muted = True
-
- def getInput(self): # use the object as a generator
- print("Awaiting input")
- if( not self.muted ):
- try:
- with sr.Microphone() as src:
- self.recognizer.adjust_for_ambient_noise( src, duration=0.2 ) # adjust for ambient noise
-
- audio = self.recognizer.listen(src)
-
- # Make audio -> text
- return (self.recognizer.recognize_google( audio )).lower() # use googles recognizer and lower its output
-
- except sr.RequestError as err:
- print("Unable to request results: {0}".format(err))
-
- except sr.UnknownValueError as err:
- print("Unknown Error: {0}".format(err))
-
- def setMuted( self, setm: bool=True ):
- self.muted = setm
-
- def switchMute( self ):
- self.setMuted( not self.muted )
-
-
-# Small test
-voice = sr_microphone()
-voice.setMuted(False)
-print( voice.getInput() )
diff --git a/speech_daemon.py b/speech_daemon.py
new file mode 100755
index 0000000..0683395
--- /dev/null
+++ b/speech_daemon.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+import sys
+
+from modules.hue.hue_remote import parseCommandline
+from modules.hue.hue_controller import controller
+from modules.speech.speech import voiceInput
+
+from modules.configloader.loader import readconfig
+
+from os.path import expanduser
+homedir = expanduser("~")
+
+CONFIG = {}
+
+class speech_daemon(object):
+ voiceInpObj = None
+ deviceIndex = 30
+
+ def __init__(self, deviceIndex=30):
+ self.voiceInpObj = voiceInput()
+ self.voiceInpObj.setMuted(False)
+
+ self.deviceIndex = deviceIndex
+
+ def loadconfig(self):
+ path = homedir + "/.config/roomcomputer/config.json"
+ # if no config path is
+ # specified then choose the users default
+
+ if( len(sys.argv) > 1 ):
+ path = sys.argv[1]
+
+ cfg = readconfig(path) # read the config
+
+ global CONFIG
+ CONFIG = cfg
+
+ def start(self):
+ controller.init()
+
+ for inp in self.voiceInpObj.start( self.deviceIndex ):
+ cmdBuf = inp.lower().split(" ")
+ if( cmdBuf[0] in CONFIG["speech"]["prefixes"] ):
+ print("CMD:", cmdBuf)
+ parseCommandline( cmdBuf, False )
+
+ controller.end()
+
+if __name__ == "__main__":
+ daemon = speech_daemon()
+ daemon.loadconfig()
+ daemon.start()