diff --git a/queries/iot_connect.py b/queries/iot_connect.py index 5bd4effe..37c9c3d1 100644 --- a/queries/iot_connect.py +++ b/queries/iot_connect.py @@ -126,33 +126,6 @@ def QIoTCreateSpeakerToken(node: Node, params: QueryStateDict, result: Result) - result.action = "create_speaker_token" -def audioClip(audioclip_url): - """ - Plays an audioclip - """ - import requests - import json - - url = f"https://api.ws.sonos.com/control/api/v1/players/RINCON_542A1B599FF201400/audioClip" - - payload = json.dumps( - { - "name": "Embla", - "appId": "com.acme.app", - "streamUrl": f"{audioclip_url}", - "volume": 30, - "priority": "HIGH", - "clipType": "CUSTOM", - } - ) - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer bEy3xnmpvoxrLcP7syVxVdjO2maj", - } - - response = requests.request("POST", url, headers=headers, data=payload) - - def sentence(state: QueryStateDict, result: Result) -> None: """Called when sentence processing is complete""" q: Query = state["query"] @@ -195,7 +168,6 @@ def sentence(state: QueryStateDict, result: Result) -> None: sonos_key = read_api_key("SonosKey") answer = "Skráðu þig inn hjá Sonos" voice_answer, response = answer, dict(answer=answer) - audioClip(text_to_audio_url(voice_answer)) q.set_answer(response, answer, voice_answer) q.set_url( f"https://api.sonos.com/login/v3/oauth?client_id={sonos_key}&response_type=code&state={client_id}&scope=playback-control-all&redirect_uri=http://{host}/connect_sonos.api" @@ -203,30 +175,145 @@ def sentence(state: QueryStateDict, result: Result) -> None: return elif result.qtype == "create_speaker_token": - sonos_encoded_credentials = read_api_key("SonosEncodedCredentials") - answer = "Ég bjó til tóka frá Sonos" - voice_answer, response = answer, dict(answer=answer) - audioClip(text_to_audio_url(voice_answer)) code = str(q.client_data("sonos_code")) - q.set_answer(response, answer, voice_answer) - - url = f"https://api.sonos.com/login/v3/oauth/access?grant_type=authorization_code&code={code}&redirect_uri=http://{host}/connect_sonos.api" - payload = {} - headers = { - "Authorization": f"Basic {sonos_encoded_credentials}", - "Cookie": "JSESSIONID=2DEFC02D2184D987F4CCAD5E45196948; AWSELB=69BFEFC914A689BF6DC8E4652748D7B501ED60290D5EA56F2E543ABD7CF357A5F65186AEBC76E6A16196350947ED84835621A185D1BF63900D4B3E7BC7FE3CF19CCF26B78C; AWSELBCORS=69BFEFC914A689BF6DC8E4652748D7B501ED60290D5EA56F2E543ABD7CF357A5F65186AEBC76E6A16196350947ED84835621A185D1BF63900D4B3E7BC7FE3CF19CCF26B78C", - } - response = requests.request("POST", url, headers=headers, data=payload) + sonos_credentials_dict = {} + sonos_encoded_credentials = read_api_key("SonosEncodedCredentials") + response = create_token(code, sonos_encoded_credentials, host) if response.status_code != 200: print("Error:", response.status_code) print(response.text) return response_json = response.json() - sonos_credentials_dict = { - "access_token": response_json["access_token"], - "refresh_token": response_json["refresh_token"], - } + sonos_credentials_dict.update( + { + "access_token": response_json["access_token"], + "refresh_token": response_json["refresh_token"], + } + ) + response = get_households(sonos_credentials_dict["access_token"]) + if response.status_code != 200: + print("Error:", response.status_code) + print(response.text) + return + response_json = response.json() + sonos_credentials_dict.update( + { + "household_id": response_json["households"][0]["id"], + } + ) + response = get_groups( + sonos_credentials_dict["household_id"], + sonos_credentials_dict["access_token"], + ) + if response.status_code != 200: + print("Error:", response.status_code) + print(response.text) + return + response_json = response.json() + sonos_credentials_dict.update( + { + "group_id": response_json["groups"][0]["id"], + "player_id": response_json["players"][0]["id"], + } + ) q.store_query_data( str(q.client_id), "sonos_credentials", sonos_credentials_dict ) + answer = "Ég bjó til tóka frá Sonos" + voice_answer = answer + audio_clip( + text_to_audio_url(answer), + sonos_credentials_dict["player_id"], + sonos_credentials_dict["access_token"], + ) + q.set_answer(response, answer, voice_answer) return + + +# put this in a separate file +def get_households(token): + """ + Returns the list of households of the user + """ + url = f"https://api.ws.sonos.com/control/api/v1/households" + + payload = {} + headers = {"Authorization": f"Bearer {token}"} + + response = requests.request("GET", url, headers=headers, data=payload) + + return response + + +def get_groups(household_id, token): + """ + Returns the list of groups of the user + """ + url = f"https://api.ws.sonos.com/control/api/v1/households/{household_id}/groups" + + payload = {} + headers = {"Authorization": f"Bearer {token}"} + + response = requests.request("GET", url, headers=headers, data=payload) + + return response + + +def create_token(code, sonos_encoded_credentials, host): + """ + Creates a token given a code + """ + url = f"https://api.sonos.com/login/v3/oauth/access?grant_type=authorization_code&code={code}&redirect_uri=http://{host}/connect_sonos.api" + + payload = {} + headers = { + "Authorization": f"Basic {sonos_encoded_credentials}", + "Cookie": "JSESSIONID=F710019AF0A3B7126A8702577C883B5F; AWSELB=69BFEFC914A689BF6DC8E4652748D7B501ED60290D5EA56F2E543ABD7CF357A5F65186AEBCFB059E28075D83A700FD504C030A53CC28683B515BE3DCA3CC587AFAF606E171; AWSELBCORS=69BFEFC914A689BF6DC8E4652748D7B501ED60290D5EA56F2E543ABD7CF357A5F65186AEBCFB059E28075D83A700FD504C030A53CC28683B515BE3DCA3CC587AFAF606E171", + } + + response = requests.request("POST", url, headers=headers, data=payload) + + return response + + +def toggle_play_pause(group_id, token): + """ + Toggles the play/pause of a group + """ + url = ( + f"https://api.ws.sonos.com/control/api/v1/groups/{group_id}/playback/playPause" + ) + + payload = {} + headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}"} + + response = requests.request("POST", url, headers=headers, data=payload) + + return response + + +def audio_clip(audioclip_url, player_id, token): + """ + Plays an audioclip from link to .mp3 file + """ + import requests + import json + + url = f"https://api.ws.sonos.com/control/api/v1/players/{player_id}/audioClip" + + payload = json.dumps( + { + "name": "Embla", + "appId": "com.acme.app", + "streamUrl": f"{audioclip_url}", + "volume": 50, + "priority": "HIGH", + "clipType": "CUSTOM", + } + ) + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {token}", + } + + response = requests.request("POST", url, headers=headers, data=payload) diff --git a/queries/iot_speakers.py b/queries/iot_speakers.py index f0348115..ba7f5254 100644 --- a/queries/iot_speakers.py +++ b/queries/iot_speakers.py @@ -1,659 +1,498 @@ -""" - - Greynir: Natural language processing for Icelandic - - Randomness query response module - - Copyright (C) 2022 Miðeind ehf. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +# """ - You should have received a copy of the GNU General Public License - along with this program. If not, see http://www.gnu.org/licenses/. +# Greynir: Natural language processing for Icelandic - This query module handles queries related to the generation - of random numbers, e.g. "Kastaðu tengingi", "Nefndu tölu milli 5 og 10", etc. +# Randomness query response module -""" +# Copyright (C) 2022 Miðeind ehf. -# TODO: add "láttu", "hafðu", "litaðu", "kveiktu" functionality. -# TODO: make the objects of sentences more modular, so that the same structure doesn't need to be written for each action -# TODO: ditto the previous comment. make the initial non-terminals general and go into specifics at the terminal level instead. -# TODO: substituion klósett, baðherbergi hugmyndÆ senda lista i javascript og profa i röð -# TODO: Embla stores old javascript code cached which has caused errors -# TODO: Cut down javascript sent to Embla -# TODO: Two specified groups or lights. -# TODO: No specified location -# TODO: Fix scene issues +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. -from typing import Dict, Mapping, Optional, cast -from typing_extensions import TypedDict +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. -import logging -import random -import json -import flask +# This query module handles queries related to the generation +# of random numbers, e.g. "Kastaðu tengingi", "Nefndu tölu milli 5 og 10", etc. -from query import Query, QueryStateDict, AnswerTuple -from queries import gen_answer, read_jsfile, read_grammar_file -from tree import Result, Node +# """ +# # TODO: add "láttu", "hafðu", "litaðu", "kveiktu" functionality. +# # TODO: make the objects of sentences more modular, so that the same structure doesn't need to be written for each action +# # TODO: ditto the previous comment. make the initial non-terminals general and go into specifics at the terminal level instead. +# # TODO: substituion klósett, baðherbergi hugmyndÆ senda lista i javascript og profa i röð +# # TODO: Embla stores old javascript code cached which has caused errors +# # TODO: Cut down javascript sent to Embla +# # TODO: Two specified groups or lights. +# # TODO: No specified location +# # TODO: Fix scene issues -class SmartLights(TypedDict): - selected_light: str - philips_hue: Dict[str, str] +# from typing import Dict, Mapping, Optional, cast +# from typing_extensions import TypedDict +# import logging +# import random +# import json +# import flask -class DeviceData(TypedDict): - smartlights: SmartLights +# from query import Query, QueryStateDict, AnswerTuple +# from queries import gen_answer, read_jsfile, read_grammar_file +# from tree import Result, Node -_IoT_QTYPE = "IoT" +# _IoT_QTYPE = "IoT" -TOPIC_LEMMAS = [ - "ljós", - "kveikja", - "litur", - "birta", - "hækka", - "stemmning", - "sena", - "stemming", - "stemning", -] +# TOPIC_LEMMAS = [ +# "tónlist", +# ] -def help_text(lemma: str) -> str: - """Help text to return when query.py is unable to parse a query but - one of the above lemmas is found in it""" - return "Ég skil þig ef þú segir til dæmis: {0}.".format( - random.choice( - ( - "Kveiktu á ljósunum inni í eldhúsi", - "Slökktu á leslampanum", - "Breyttu lit lýsingarinnar í stofunni í bláan", - "Gerðu ljósið í borðstofunni bjartara", - "Stilltu á bjartasta niðri í kjallara", - ) - ) - ) - - -_COLORS = { - "gulur": 60 * 65535 / 360, - "rauður": 360 * 65535 / 360, - "grænn": 120 * 65535 / 360, - "blár": 240 * 65535 / 360, - "ljósblár": 180 * 65535 / 360, - "bleikur": 300 * 65535 / 360, - "hvítur": [], - "fjólublár": [], - "brúnn": [], - "appelsínugulur": [], -} - - -# This module wants to handle parse trees for queries -HANDLE_TREE = True - -# The grammar nonterminals this module wants to handle -QUERY_NONTERMINALS = {"QCHANGE"} - -# The context-free grammar for the queries recognized by this plug-in module -# GRAMMAR = read_grammar_file("iot_hue") - -GRAMMAR = f""" - -/þgf = þgf -/ef = ef - -Query → - QCHANGE '?'? - -QCHANGE → - QCHANGEQuery - -QCHANGEQuery -> - QCHANGEMakeVerb QCHANGEMakeRest - | QCHANGESetVerb QCHANGESetRest - | QCHANGEChangeVerb QCHANGEChangeRest - | QCHANGELetVerb QCHANGELetRest - | QCHANGETurnOnVerb QCHANGETurnOnRest - | QCHANGETurnOffVerb QCHANGETurnOffRest - | QCHANGEIncreaseOrDecreaseVerb QCHANGEIncreaseOrDecreaseRest - -QCHANGEMakeVerb -> - 'gera:so'_bh - -QCHANGESetVerb -> - 'setja:so'_bh - | 'stilla:so'_bh - -QCHANGEChangeVerb -> - 'breyta:so'_bh - -QCHANGELetVerb -> - 'láta:so'_bh - -QCHANGETurnOnVerb -> - 'kveikja:so'_bh - -QCHANGETurnOffVerb -> - 'slökkva:so'_bh - -QCHANGEIncreaseOrDecreaseVerb -> - QCHANGEIncreaseVerb - | QCHANGEDecreaseVerb - -QCHANGEIncreaseVerb -> - 'hækka:so'_bh - | 'auka:so'_bh - -QCHANGEDecreaseVerb -> - 'lækka:so'_bh - | 'minnka:so'_bh - -QCHANGEMakeRest -> - QCHANGESubject/þf QCHANGEHvar? QCHANGEHvernigMake - | QCHANGESubject/þf QCHANGEHvernigMake QCHANGEHvar? - | QCHANGEHvar? QCHANGESubject/þf QCHANGEHvernigMake - | QCHANGEHvar? QCHANGEHvernigMake QCHANGESubject/þf - | QCHANGEHvernigMake QCHANGESubject/þf QCHANGEHvar? - | QCHANGEHvernigMake QCHANGEHvar? QCHANGESubject/þf - -# TODO: Add support for "stilltu rauðan lit á ljósið í eldhúsinu" -QCHANGESetRest -> - QCHANGESubject/þf QCHANGEHvar? QCHANGEHvernigSet - | QCHANGESubject/þf QCHANGEHvernigSet QCHANGEHvar? - | QCHANGEHvar? QCHANGESubject/þf QCHANGEHvernigSet - | QCHANGEHvar? QCHANGEHvernigSet QCHANGESubject/þf - | QCHANGEHvernigSet QCHANGESubject/þf QCHANGEHvar? - | QCHANGEHvernigSet QCHANGEHvar? QCHANGESubject/þf - -QCHANGEChangeRest -> - QCHANGESubjectOne/þgf QCHANGEHvar? QCHANGEHvernigChange - | QCHANGESubjectOne/þgf QCHANGEHvernigChange QCHANGEHvar? - | QCHANGEHvar? QCHANGESubjectOne/þgf QCHANGEHvernigChange - | QCHANGEHvar? QCHANGEHvernigChange QCHANGESubjectOne/þgf - | QCHANGEHvernigChange QCHANGESubjectOne/þgf QCHANGEHvar? - | QCHANGEHvernigChange QCHANGEHvar? QCHANGESubjectOne/þgf - -QCHANGELetRest -> - QCHANGESubject/þf QCHANGEHvar? QCHANGEHvernigLet - | QCHANGESubject/þf QCHANGEHvernigLet QCHANGEHvar? - | QCHANGEHvar? QCHANGESubject/þf QCHANGEHvernigLet - | QCHANGEHvar? QCHANGEHvernigLet QCHANGESubject/þf - | QCHANGEHvernigLet QCHANGESubject/þf QCHANGEHvar? - | QCHANGEHvernigLet QCHANGEHvar? QCHANGESubject/þf - -QCHANGETurnOnRest -> - QCHANGETurnOnLightsRest - | QCHANGEAHverju QCHANGEHvar? - | QCHANGEHvar? QCHANGEAHverju - -QCHANGETurnOnLightsRest -> - QCHANGELightSubject/þf QCHANGEHvar? - | QCHANGEHvar QCHANGELightSubject/þf? - -# Would be good to add "slökktu á rauða litnum" functionality -QCHANGETurnOffRest -> - QCHANGETurnOffLightsRest - -QCHANGETurnOffLightsRest -> - QCHANGELightSubject/þf QCHANGEHvar? - | QCHANGEHvar QCHANGELightSubject/þf? - -# TODO: Make the subject categorization cleaner -QCHANGEIncreaseOrDecreaseRest -> - QCHANGELightSubject/þf QCHANGEHvar? - | QCHANGEBrightnessSubject/þf QCHANGEHvar? - -QCHANGESubject/fall -> - QCHANGESubjectOne/fall - | QCHANGESubjectTwo/fall - -# TODO: Decide whether LightSubject/þgf should be accepted -QCHANGESubjectOne/fall -> - QCHANGELightSubject/fall - | QCHANGEColorSubject/fall - | QCHANGEBrightnessSubject/fall - | QCHANGESceneSubject/fall - -QCHANGESubjectTwo/fall -> - QCHANGEGroupNameSubject/fall # á bara að styðja "gerðu eldhúsið rautt", "gerðu eldhúsið rómó" "gerðu eldhúsið bjartara", t.d. - -QCHANGEHvar -> - QCHANGELocationPreposition QCHANGEGroupName/þgf - -QCHANGEHvernigMake -> - QCHANGEAnnadAndlag # gerðu litinn rauðan í eldhúsinu EÐA gerðu birtuna meiri í eldhúsinu - | QCHANGEAdHverju # gerðu litinn að rauðum í eldhúsinu - | QCHANGEThannigAd - -QCHANGEHvernigSet -> - QCHANGEAHvad - | QCHANGEThannigAd - -QCHANGEHvernigChange -> - QCHANGEIHvad - | QCHANGEThannigAd - -QCHANGEHvernigLet -> - QCHANGEBecome QCHANGESomethingOrSomehow - | QCHANGEBe QCHANGESomehow - -QCHANGEThannigAd -> - "þannig" "að"? pfn_nf QCHANGEBeOrBecomeSubjunctive QCHANGEAnnadAndlag - -# I think these verbs only appear in these forms. -# In which case these terminals should be deleted and a direct reference should be made in the relevant non-terminals. -QCHANGEBe -> - "vera" - -QCHANGEBecome -> - "verða" - -QCHANGEBeOrBecomeSubjunctive -> - "verði" - | "sé" - -QCHANGELightSubject/fall -> - QCHANGELight/fall - -QCHANGEColorSubject/fall -> - QCHANGEColorWord/fall QCHANGELight/ef? - | QCHANGEColorWord/fall "á" QCHANGELight/þgf - -QCHANGEBrightnessSubject/fall -> - QCHANGEBrightnessWord/fall QCHANGELight/ef? - | QCHANGEBrightnessWord/fall "á" QCHANGELight/þgf - -QCHANGESceneSubject/fall -> - QCHANGESceneWord/fall - -QCHANGEGroupNameSubject/fall -> - QCHANGEGroupName/fall - -QCHANGELocationPreposition -> - QCHANGELocationPrepositionFirstPart? QCHANGELocationPrepositionSecondPart - -# The latter proverbs are grammatically incorrect, but common errors, both in speech and transcription. -# The list provided is taken from StefnuAtv in Greynir.grammar. That includes "aftur:ao", which is not applicable here. -QCHANGELocationPrepositionFirstPart -> - StaðarAtv - | "fram:ao" - | "inn:ao" - | "niður:ao" - | "upp:ao" - | "út:ao" - -QCHANGELocationPrepositionSecondPart -> - "á" | "í" - -QCHANGEGroupName/fall -> - no/fall - -QCHANGELightName/fall -> - no/fall - -QCHANGEColorName -> - {" | ".join(f"'{color}:lo'" for color in _COLORS.keys())} - -QCHANGESceneName -> - no - | lo - -QCHANGEAnnadAndlag -> - QCHANGENewSetting/nf - | QCHANGESpyrjaHuldu/nf - -QCHANGEAdHverju -> - "að" QCHANGENewSetting/þgf - -QCHANGEAHvad -> - "á" QCHANGENewSetting/þf - -QCHANGEIHvad -> - "í" QCHANGENewSetting/þf - -QCHANGEAHverju -> - "á" QCHANGELight/þgf - | "á" QCHANGENewSetting/þgf - -QCHANGESomethingOrSomehow -> - QCHANGEAnnadAndlag - | QCHANGEAdHverju - -QCHANGESomehow -> - QCHANGEAnnadAndlag - | QCHANGEThannigAd - -QCHANGELight/fall -> - QCHANGELightName/fall - | QCHANGELightWord/fall - -# Should 'birta' be included -QCHANGELightWord/fall -> - 'ljós'/fall - | 'lýsing'/fall - | 'birta'/fall - | 'Birta'/fall - -QCHANGEColorWord/fall -> - 'litur'/fall - | 'litblær'/fall - | 'blær'/fall +# def help_text(lemma: str) -> str: +# """Help text to return when query.py is unable to parse a query but +# one of the above lemmas is found in it""" +# return "Ég skil þig ef þú segir til dæmis: {0}.".format( +# random.choice( +# ("Hækkaðu í tónlistinni", "Kveiktu á tónlist", "Láttu vera tónlist") +# ) +# ) + + +# # This module wants to handle parse trees for queries +# HANDLE_TREE = True + +# # The grammar nonterminals this module wants to handle +# QUERY_NONTERMINALS = {"QIoTSpeaker"} + +# # The context-free grammar for the queries recognized by this plug-in module +# # GRAMMAR = read_grammar_file("iot_hue") + +# GRAMMAR = f""" + +# /þgf = þgf +# /ef = ef + +# Query → +# QIoTSpeaker '?'? + +# QIoTSpeaker → +# QIoTSpeakerQuery + +# QIoTSpeakerQuery -> +# QIoTSpeakerMakeVerb QIoTSpeakerMakeRest +# | QIoTSpeakerSetVerb QIoTSpeakerSetRest +# | QIoTSpeakerChangeVerb QIoTSpeakerChangeRest +# | QIoTSpeakerLetVerb QIoTSpeakerLetRest +# | QIoTSpeakerTurnOnVerb QIoTSpeakerTurnOnRest +# | QIoTSpeakerTurnOffVerb QIoTSpeakerTurnOffRest +# | QIoTSpeakerIncreaseOrDecreaseVerb QIoTSpeakerIncreaseOrDecreaseRest + +# QIoTSpeakerMakeVerb -> +# 'gera:so'_bh + +# QIoTSpeakerSetVerb -> +# 'setja:so'_bh +# | 'stilla:so'_bh + +# QIoTSpeakerChangeVerb -> +# 'breyta:so'_bh + +# QIoTSpeakerLetVerb -> +# 'láta:so'_bh + +# QIoTSpeakerTurnOnVerb -> +# 'kveikja:so'_bh + +# QIoTSpeakerTurnOffVerb -> +# 'slökkva:so'_bh + +# QIoTSpeakerIncreaseOrDecreaseVerb -> +# QIoTSpeakerIncreaseVerb +# | QIoTSpeakerDecreaseVerb + +# QIoTSpeakerIncreaseVerb -> +# 'hækka:so'_bh +# | 'auka:so'_bh + +# QIoTSpeakerDecreaseVerb -> +# 'lækka:so'_bh +# | 'minnka:so'_bh + +# QCHANGEMakeRest -> +# # QCHANGESubject/þf QCHANGEHvar? QCHANGEHvernigMake +# # | QCHANGESubject/þf QCHANGEHvernigMake QCHANGEHvar? +# # | QCHANGEHvar? QCHANGESubject/þf QCHANGEHvernigMake +# # | QCHANGEHvar? QCHANGEHvernigMake QCHANGESubject/þf +# # | QCHANGEHvernigMake QCHANGESubject/þf QCHANGEHvar? +# # | QCHANGEHvernigMake QCHANGEHvar? QCHANGESubject/þf +# QIoTSpeakerMusicWord/þf QIoTSpeakerHvar? + +# # TODO: Add support for "stilltu rauðan lit á ljósið í eldhúsinu" +# QCHANGESetRest -> +# # QCHANGESubject/þf QCHANGEHvar? QCHANGEHvernigSet +# # | QCHANGESubject/þf QCHANGEHvernigSet QCHANGEHvar? +# # | QCHANGEHvar? QCHANGESubject/þf QCHANGEHvernigSet +# # | QCHANGEHvar? QCHANGEHvernigSet QCHANGESubject/þf +# # | QCHANGEHvernigSet QCHANGESubject/þf QCHANGEHvar? +# # | QCHANGEHvernigSet QCHANGEHvar? QCHANGESubject/þf +# "á" QIoTSpeakerMusicWord/þf QIoTSpeakerHvar? + +# QCHANGEChangeRest -> +# # QCHANGESubjectOne/þgf QCHANGEHvar? QCHANGEHvernigChange +# # | QCHANGESubjectOne/þgf QCHANGEHvernigChange QCHANGEHvar? +# # | QCHANGEHvar? QCHANGESubjectOne/þgf QCHANGEHvernigChange +# # | QCHANGEHvar? QCHANGEHvernigChange QCHANGESubjectOne/þgf +# # | QCHANGEHvernigChange QCHANGESubjectOne/þgf QCHANGEHvar? +# # | QCHANGEHvernigChange QCHANGEHvar? QCHANGESubjectOne/þgf + +# QCHANGELetRest -> +# QCHANGESubject/þf QCHANGEHvar? QCHANGEHvernigLet +# | QCHANGESubject/þf QCHANGEHvernigLet QCHANGEHvar? +# | QCHANGEHvar? QCHANGESubject/þf QCHANGEHvernigLet +# | QCHANGEHvar? QCHANGEHvernigLet QCHANGESubject/þf +# | QCHANGEHvernigLet QCHANGESubject/þf QCHANGEHvar? +# | QCHANGEHvernigLet QCHANGEHvar? QCHANGESubject/þf +# "vera" QIoTSpeakerMusicWord/þf QIoTSpeakerHvar? + +# QCHANGETurnOnRest -> +# # QCHANGETurnOnLightsRest +# # | QCHANGEAHverju QCHANGEHvar? +# # | QCHANGEHvar? QCHANGEAHverju +# "á" QIoTSpeakerMusicWord/þgf QIoTSpeakerHvar? + +# # QCHANGETurnOnLightsRest -> +# # QCHANGELightSubject/þf QCHANGEHvar? +# # | QCHANGEHvar QCHANGELightSubject/þf? + +# # Would be good to add "slökktu á rauða litnum" functionality +# QCHANGETurnOffRest -> +# # QCHANGETurnOffLightsRest +# "á" QIoTSpeakerMusicWord/þgf QIoTSpeakerHvar? + +# # QCHANGETurnOffLightsRest -> +# # QCHANGELightSubject/þf QCHANGEHvar? +# # | QCHANGEHvar QCHANGELightSubject/þf? + +# # TODO: Make the subject categorization cleaner +# QCHANGEIncreaseOrDecreaseRest -> +# # QCHANGELightSubject/þf QCHANGEHvar? +# # | QCHANGEBrightnessSubject/þf QCHANGEHvar? +# QIoTSpeakerMusicWord/þf QIoTSpeakerHvar? +# | "í" QIoTSpeakerMusicWord/þgf QIoTSpeakerHvar? + +# # QCHANGESubject/fall -> +# # QCHANGESubjectOne/fall +# # | QCHANGESubjectTwo/fall + +# QIoTMusicWord -> +# 'tónlist'/fall + +# # # TODO: Decide whether LightSubject/þgf should be accepted +# # QCHANGESubjectOne/fall -> +# # QCHANGELightSubject/fall +# # | QCHANGEColorSubject/fall +# # | QCHANGEBrightnessSubject/fall +# # | QCHANGESceneSubject/fall + +# # QCHANGESubjectTwo/fall -> +# # QCHANGEGroupNameSubject/fall # á bara að styðja "gerðu eldhúsið rautt", "gerðu eldhúsið rómó" "gerðu eldhúsið bjartara", t.d. + +# QIoTSpeakerHvar -> +# QIoTSpeakerLocationPreposition QIoTSpeakerGroupName/þgf + +# # QCHANGEHvernigMake -> +# # QCHANGEAnnadAndlag # gerðu litinn rauðan í eldhúsinu EÐA gerðu birtuna meiri í eldhúsinu +# # | QCHANGEAdHverju # gerðu litinn að rauðum í eldhúsinu +# # | QCHANGEThannigAd + +# # QCHANGEHvernigSet -> +# # QCHANGEAHvad +# # | QCHANGEThannigAd + +# # QCHANGEHvernigChange -> +# # QCHANGEIHvad +# # | QCHANGEThannigAd + +# # QCHANGEHvernigLet -> +# # QCHANGEBecome QCHANGESomethingOrSomehow +# # | QCHANGEBe QCHANGESomehow + +# # QCHANGEThannigAd -> +# # "þannig" "að"? pfn_nf QCHANGEBeOrBecomeSubjunctive QCHANGEAnnadAndlag + +# # I think these verbs only appear in these forms. +# # In which case these terminals should be deleted and a direct reference should be made in the relevant non-terminals. +# # QCHANGEBe -> +# # "vera" + +# # QCHANGEBecome -> +# # "verða" + +# # QCHANGEBeOrBecomeSubjunctive -> +# # "verði" +# # | "sé" + +# # QCHANGELightSubject/fall -> +# # QCHANGELight/fall + +# # QCHANGEColorSubject/fall -> +# # QCHANGEColorWord/fall QCHANGELight/ef? +# # | QCHANGEColorWord/fall "á" QCHANGELight/þgf + +# # QCHANGEBrightnessSubject/fall -> +# # QCHANGEBrightnessWord/fall QCHANGELight/ef? +# # | QCHANGEBrightnessWord/fall "á" QCHANGELight/þgf + +# # QCHANGESceneSubject/fall -> +# # QCHANGESceneWord/fall + +# # QCHANGEGroupNameSubject/fall -> +# # QCHANGEGroupName/fall + +# QIoTSpeakerLocationPreposition -> +# QIoTSpeakerLocationPrepositionFirstPart? QIoTSpeakerLocationPrepositionSecondPart + +# # The latter proverbs are grammatically incorrect, but common errors, both in speech and transcription. +# # The list provided is taken from StefnuAtv in Greynir.grammar. That includes "aftur:ao", which is not applicable here. +# QIoTSpeakerLocationPrepositionFirstPart -> +# StaðarAtv +# | "fram:ao" +# | "inn:ao" +# | "niður:ao" +# | "upp:ao" +# | "út:ao" + +# QIoTSpeakerLocationPrepositionSecondPart -> +# "á" | "í" + +# QIoTSpeakerGroupName/fall -> +# no/fall + +# # QCHANGELightName/fall -> +# # no/fall + +# # QCHANGEColorName -> +# # {" | ".join(f"'{color}:lo'" for color in _COLORS.keys())} + +# # QCHANGESceneName -> +# # no +# # | lo + +# # QCHANGEAnnadAndlag -> +# # QCHANGENewSetting/nf +# # | QCHANGESpyrjaHuldu/nf + +# # QCHANGEAdHverju -> +# # "að" QCHANGENewSetting/þgf + +# # QCHANGEAHvad -> +# # "á" QCHANGENewSetting/þf + +# # QCHANGEIHvad -> +# # "í" QCHANGENewSetting/þf + +# # QCHANGEAHverju -> +# # "á" QCHANGELight/þgf +# # | "á" QCHANGENewSetting/þgf + +# # QCHANGESomethingOrSomehow -> +# # QCHANGEAnnadAndlag +# # | QCHANGEAdHverju + +# # QCHANGESomehow -> +# # QCHANGEAnnadAndlag +# # | QCHANGEThannigAd + +# # QCHANGELight/fall -> +# # QCHANGELightName/fall +# # | QCHANGELightWord/fall + +# # # Should 'birta' be included +# # QCHANGELightWord/fall -> +# # 'ljós'/fall +# # | 'lýsing'/fall +# # | 'birta'/fall +# # | 'Birta'/fall + +# # QCHANGEColorWord/fall -> +# # 'litur'/fall +# # | 'litblær'/fall +# # | 'blær'/fall + +# # QCHANGEBrightnessWords/fall -> +# # 'bjartur'/fall +# # | QCHANGEBrightnessWord/fall + +# # QCHANGEBrightnessWord/fall -> +# # 'birta'/fall +# # | 'Birta'/fall +# # | 'birtustig'/fall + +# # QCHANGESceneWord/fall -> +# # 'sena'/fall +# # | 'stemning'/fall +# # | 'stemming'/fall +# # | 'stemmning'/fall -QCHANGEBrightnessWords/fall -> - 'bjartur'/fall - | QCHANGEBrightnessWord/fall - -QCHANGEBrightnessWord/fall -> - 'birta'/fall - | 'Birta'/fall - | 'birtustig'/fall - -QCHANGESceneWord/fall -> - 'sena'/fall - | 'stemning'/fall - | 'stemming'/fall - | 'stemmning'/fall - -# Need to ask Hulda how this works. -QCHANGESpyrjaHuldu/fall -> - # QCHANGEHuldaColor/fall - QCHANGEHuldaBrightness/fall - # | QCHANGEHuldaScene/fall - -# Do I need a "new light state" non-terminal? -QCHANGENewSetting/fall -> - QCHANGENewColor/fall - | QCHANGENewBrightness/fall - | QCHANGENewScene/fall - -# Missing "meira dimmt" -QCHANGEHuldaBrightness/fall -> - QCHANGEMoreBrighterOrHigher/fall QCHANGEBrightnessWords/fall? - | QCHANGELessDarkerOrLower/fall QCHANGEBrightnessWords/fall? - -#Unsure about whether to include /fall after QCHANGEColorName -QCHANGENewColor/fall -> - QCHANGEColorWord/fall QCHANGEColorName - | QCHANGEColorName QCHANGEColorWord/fall? - -QCHANGENewBrightness/fall -> - 'sá'/fall? QCHANGEBrightestOrDarkest/fall - | QCHANGEBrightestOrDarkest/fall QCHANGEBrightnessOrSettingWord/fall - -QCHANGENewScene/fall -> - QCHANGESceneWord/fall QCHANGESceneName - | QCHANGESceneName QCHANGESceneWord/fall? - -QCHANGEMoreBrighterOrHigher/fall -> - 'mikill:lo'_mst/fall - | 'bjartur:lo'_mst/fall - | 'ljós:lo'_mst/fall - | 'hár:lo'_mst/fall - -QCHANGELessDarkerOrLower/fall -> - 'lítill:lo'_mst/fall - | 'dökkur:lo'_mst/fall - | 'dimmur:lo'_mst/fall - | 'lágur:lo'_mst/fall - -QCHANGEBrightestOrDarkest/fall -> - QCHANGEBrightest/fall - | QCHANGEDarkest/fall - -QCHANGEBrightest/fall -> - 'bjartur:lo'_evb - | 'bjartur:lo'_esb - | 'ljós:lo'_evb - | 'ljós:lo'_esb - -QCHANGEDarkest/fall -> - 'dimmur:lo'_evb - | 'dimmur:lo'_esb - | 'dökkur:lo'_evb - | 'dökkur:lo'_esb - -QCHANGEBrightnessOrSettingWord/fall -> - QCHANGEBrightnessWord/fall - | QCHANGESettingWord/fall - -QCHANGESettingWord/fall -> - 'stilling'/fall - -""" - - -def QCHANGEColorWord(node: Node, params: QueryStateDict, result: Result) -> None: - result.changing_color = True - - -def QCHANGESceneWord(node: Node, params: QueryStateDict, result: Result) -> None: - result.changing_scene = True - - -def QCHANGEBrightnessWord(node: Node, params: QueryStateDict, result: Result) -> None: - result.changing_brightness = True - - -def QCHANGEQuery(node: Node, params: QueryStateDict, result: Result) -> None: - result.qtype = _IoT_QTYPE - - -def QCHANGETurnOnLightsRest(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "turn_on" - if "hue_obj" not in result: - result["hue_obj"] = {"on": True} - else: - result["hue_obj"]["on"] = True - - -def QCHANGETurnOffLightsRest(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "turn_off" - if "hue_obj" not in result: - result["hue_obj"] = {"on": False} - else: - result["hue_obj"]["on"] = False - - -def QCHANGENewColor(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "set_color" - print(result.color_name) - color_hue = _COLORS.get(result.color_name, None) - print(color_hue) - if color_hue is not None: - if "hue_obj" not in result: - result["hue_obj"] = {"on": True, "hue": int(color_hue)} - else: - result["hue_obj"]["hue"] = int(color_hue) - result["hue_obj"]["on"] = True - - -def QCHANGEMoreBrighterOrHigher( - node: Node, params: QueryStateDict, result: Result -) -> None: - result.action = "increase_brightness" - if "hue_obj" not in result: - result["hue_obj"] = {"on": True, "bri_inc": 64} - else: - result["hue_obj"]["bri_inc"] = 64 - result["hue_obj"]["on"] = True - - -def QCHANGELessDarkerOrLower(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "decrease_brightness" - if "hue_obj" not in result: - result["hue_obj"] = {"bri_inc": -64} - else: - result["hue_obj"]["bri_inc"] = -64 - - -def QCHANGEIncreaseVerb(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "increase_brightness" - if "hue_obj" not in result: - result["hue_obj"] = {"on": True, "bri_inc": 64} - else: - result["hue_obj"]["bri_inc"] = 64 - result["hue_obj"]["on"] = True - - -def QCHANGEDecreaseVerb(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "decrease_brightness" - if "hue_obj" not in result: - result["hue_obj"] = {"bri_inc": -64} - else: - result["hue_obj"]["bri_inc"] = -64 - - -def QCHANGEBrightest(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "decrease_brightness" - if "hue_obj" not in result: - result["hue_obj"] = {"bri": 255} - else: - result["hue_obj"]["bri"] = 255 - - -def QCHANGEDarkest(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "decrease_brightness" - if "hue_obj" not in result: - result["hue_obj"] = {"bri": 0} - else: - result["hue_obj"]["bri"] = 0 - - -def QCHANGENewScene(node: Node, params: QueryStateDict, result: Result) -> None: - result.action = "set_scene" - scene_name = result.get("scene_name", None) - print(scene_name) - if scene_name is not None: - if "hue_obj" not in result: - result["hue_obj"] = {"on": True, "scene": scene_name} - else: - result["hue_obj"]["scene"] = scene_name - result["hue_obj"]["on"] = True - - -def QCHANGEColorName(node: Node, params: QueryStateDict, result: Result) -> None: - result["color_name"] = ( - node.first_child(lambda x: True).string_self().strip("'").split(":")[0] - ) - - -def QCHANGESceneName(node: Node, params: QueryStateDict, result: Result) -> None: - result["scene_name"] = result._indefinite - print(result.get("scene_name", None)) - - -def QCHANGEGroupName(node: Node, params: QueryStateDict, result: Result) -> None: - result["group_name"] = result._indefinite - - -def QCHANGELightName(node: Node, params: QueryStateDict, result: Result) -> None: - result["light_name"] = result._indefinite - - -# Convert color name into hue -# Taken from home.py -_COLOR_NAME_TO_CIE: Mapping[str, float] = { - "gulur": 60 * 65535 / 360, - "grænn": 120 * 65535 / 360, - "ljósblár": 180 * 65535 / 360, - "blár": 240 * 65535 / 360, - "bleikur": 300 * 65535 / 360, - "rauður": 360 * 65535 / 360, - # "Rauð": 360 * 65535 / 360, -} - - -def sentence(state: QueryStateDict, result: Result) -> None: - """Called when sentence processing is complete""" - q: Query = state["query"] - changing_color = result.get("changing_color", False) - changing_scene = result.get("changing_scene", False) - changing_brightness = result.get("changing_brightness", False) - print("error?", sum((changing_color, changing_scene, changing_brightness)) > 1) - if ( - sum((changing_color, changing_scene, changing_brightness)) > 1 - or "qtype" not in result - ): - q.set_error("E_QUERY_NOT_UNDERSTOOD") - return - - q.set_qtype(result.qtype) - - smartdevice_type = "smartlights" - client_id = str(q.client_id) - print("client_id:", client_id) - - # Fetch relevant data from the device_data table to perform an action on the lights - device_data = cast(Optional[DeviceData], q.client_data(smartdevice_type)) - print("location :", q.location) - print("device data :", device_data) - - selected_light: Optional[str] = None - print("selected light:", selected_light) - hue_credentials: Optional[Dict[str, str]] = None - - if device_data is not None and smartdevice_type in device_data: - dev = device_data[smartdevice_type] - assert dev is not None - selected_light = dev.get("selected_light") - hue_credentials = dev.get("philips_hue") - bridge_ip = hue_credentials.get("ipAddress") - username = hue_credentials.get("username") - - if not device_data or not hue_credentials: - answer = "Það vantar að tengja Philips Hub-inn." - q.set_answer(*gen_answer(answer)) - return - - # Successfully matched a query type - print("bridge_ip: ", bridge_ip) - print("username: ", username) - print("selected light :", selected_light) - print("hue credentials :", hue_credentials) - - try: - # kalla í javascripts stuff - light_or_group_name = result.get("light_name", result.get("group_name", "")) - color_name = result.get("color_name", "") - print("GROUP NAME:", light_or_group_name) - print("COLOR NAME:", color_name) - print(result.hue_obj) - q.set_answer( - *gen_answer( - "ég var að kveikja ljósin! " - # + group_name - # + " " - # + color_name - # + " " - # + result.action - # + " " - # + str(result.hue_obj.get("hue", "enginn litur")) - ) - ) - js = ( - read_jsfile("IoT_Embla/fuse.js") - + f"var BRIDGE_IP = '{bridge_ip}';var USERNAME = '{username}';" - + read_jsfile("IoT_Embla/Philips_Hue/fuse_search.js") - + read_jsfile("IoT_Embla/Philips_Hue/lights.js") - + read_jsfile("IoT_Embla/Philips_Hue/set_lights.js") - ) - js += f"setLights('{light_or_group_name}', '{json.dumps(result.hue_obj)}');" - q.set_command(js) - except Exception as e: - logging.warning("Exception while processing random query: {0}".format(e)) - q.set_error("E_EXCEPTION: {0}".format(e)) - raise - - # f"var BRIDGE_IP = '192.168.1.68';var USERNAME = 'p3obluiXT13IbHMpp4X63ZvZnpNRdbqqMt723gy2';" +# # # Need to ask Hulda how this works. +# # QCHANGESpyrjaHuldu/fall -> +# # # QCHANGEHuldaColor/fall +# # QCHANGEHuldaBrightness/fall +# # # | QCHANGEHuldaScene/fall + +# # # Do I need a "new light state" non-terminal? +# # QCHANGENewSetting/fall -> +# # QCHANGENewColor/fall +# # | QCHANGENewBrightness/fall +# # | QCHANGENewScene/fall + +# # # Missing "meira dimmt" +# # QCHANGEHuldaBrightness/fall -> +# # QCHANGEMoreBrighterOrHigher/fall QCHANGEBrightnessWords/fall? +# # | QCHANGELessDarkerOrLower/fall QCHANGEBrightnessWords/fall? + +# # #Unsure about whether to include /fall after QCHANGEColorName +# # QCHANGENewColor/fall -> +# # QCHANGEColorWord/fall QCHANGEColorName +# # | QCHANGEColorName QCHANGEColorWord/fall? + +# # QCHANGENewBrightness/fall -> +# # 'sá'/fall? QCHANGEBrightestOrDarkest/fall +# # | QCHANGEBrightestOrDarkest/fall QCHANGEBrightnessOrSettingWord/fall + +# # QCHANGENewScene/fall -> +# # QCHANGESceneWord/fall QCHANGESceneName +# # | QCHANGESceneName QCHANGESceneWord/fall? + +# # QCHANGEMoreBrighterOrHigher/fall -> +# # 'mikill:lo'_mst/fall +# # | 'bjartur:lo'_mst/fall +# # | 'ljós:lo'_mst/fall +# # | 'hár:lo'_mst/fall + +# # QCHANGELessDarkerOrLower/fall -> +# # 'lítill:lo'_mst/fall +# # | 'dökkur:lo'_mst/fall +# # | 'dimmur:lo'_mst/fall +# # | 'lágur:lo'_mst/fall + +# # QCHANGEBrightestOrDarkest/fall -> +# # QCHANGEBrightest/fall +# # | QCHANGEDarkest/fall + +# # QCHANGEBrightest/fall -> +# # 'bjartur:lo'_evb +# # | 'bjartur:lo'_esb +# # | 'ljós:lo'_evb +# # | 'ljós:lo'_esb + +# # QCHANGEDarkest/fall -> +# # 'dimmur:lo'_evb +# # | 'dimmur:lo'_esb +# # | 'dökkur:lo'_evb +# # | 'dökkur:lo'_esb + +# # QCHANGEBrightnessOrSettingWord/fall -> +# # QCHANGEBrightnessWord/fall +# # | QCHANGESettingWord/fall + +# # QCHANGESettingWord/fall -> +# # 'stilling'/fall + +# """ + + +# def QIoTSpeakerIncreaseVerb(node: Node, params: QueryStateDict, result: Result) -> None: +# result.action = "increase_volume" +# if "hue_obj" not in result: +# result["hue_obj"] = {"on": True, "bri_inc": 64} +# else: +# result["hue_obj"]["bri_inc"] = 64 +# result["hue_obj"]["on"] = True + + +# def QIoTSpeakerDecreaseVerb(node: Node, params: QueryStateDict, result: Result) -> None: +# result.action = "decrease_volume" +# if "hue_obj" not in result: +# result["hue_obj"] = {"bri_inc": -64} +# else: +# result["hue_obj"]["bri_inc"] = -64 + + +# def QIoTSpeakerGroupName(node: Node, params: QueryStateDict, result: Result) -> None: +# result["group_name"] = result._indefinite + + +# def sentence(state: QueryStateDict, result: Result) -> None: +# """Called when sentence processing is complete""" +# q: Query = state["query"] + +# q.set_qtype(result.get["qtype"]) + +# smartdevice_type = "smartSpeaker" + +# # Fetch relevant data from the device_data table to perform an action on the lights +# device_data = cast(Optional[DeviceData], q.client_data(smartdevice_type)) + +# selected_light: Optional[str] = None +# print("selected light:", selected_light) +# hue_credentials: Optional[Dict[str, str]] = None + +# if device_data is not None and smartdevice_type in device_data: +# dev = device_data[smartdevice_type] +# assert dev is not None +# selected_light = dev.get("selected_light") +# hue_credentials = dev.get("philips_hue") +# bridge_ip = hue_credentials.get("ipAddress") +# username = hue_credentials.get("username") + +# if not device_data or not hue_credentials: +# answer = "Það vantar að tengja Philips Hub-inn." +# q.set_answer(*gen_answer(answer)) +# return + +# # Successfully matched a query type +# print("bridge_ip: ", bridge_ip) +# print("username: ", username) +# print("selected light :", selected_light) +# print("hue credentials :", hue_credentials) + +# try: +# # kalla í javascripts stuff +# light_or_group_name = result.get("light_name", result.get("group_name", "")) +# color_name = result.get("color_name", "") +# print("GROUP NAME:", light_or_group_name) +# print("COLOR NAME:", color_name) +# print(result.hue_obj) +# q.set_answer( +# *gen_answer( +# "ég var að kveikja ljósin! " +# # + group_name +# # + " " +# # + color_name +# # + " " +# # + result.action +# # + " " +# # + str(result.hue_obj.get("hue", "enginn litur")) +# ) +# ) +# js = ( +# read_jsfile("IoT_Embla/fuse.js") +# + f"var BRIDGE_IP = '{bridge_ip}';var USERNAME = '{username}';" +# + read_jsfile("IoT_Embla/Philips_Hue/fuse_search.js") +# + read_jsfile("IoT_Embla/Philips_Hue/lights.js") +# + read_jsfile("IoT_Embla/Philips_Hue/set_lights.js") +# ) +# js += f"setLights('{light_or_group_name}', '{json.dumps(result.hue_obj)}');" +# q.set_command(js) +# except Exception as e: +# logging.warning("Exception while processing random query: {0}".format(e)) +# q.set_error("E_EXCEPTION: {0}".format(e)) +# raise + +# # f"var BRIDGE_IP = '192.168.1.68';var USERNAME = 'p3obluiXT13IbHMpp4X63ZvZnpNRdbqqMt723gy2';" diff --git a/routes/sonos.py b/queries/sonos.py similarity index 86% rename from routes/sonos.py rename to queries/sonos.py index dce575b9..7be9869c 100644 --- a/routes/sonos.py +++ b/queries/sonos.py @@ -25,11 +25,11 @@ import requests -def getHouseholds(token): +def get_households(token): """ Returns the list of households of the user """ - url = "https://api.ws.sonos.com/control/api/v1/households" + url = f"https://api.ws.sonos.com/control/api/v1/households" payload = {} headers = {"Authorization": f"Bearer {token}"} @@ -39,11 +39,11 @@ def getHouseholds(token): return response -def getGroups(houshold_id, token): +def get_groups(household_id, token): """ Returns the list of groups of the user """ - url = "https://api.ws.sonos.com/control/api/v1/households/{household_id}/groups" + url = f"https://api.ws.sonos.com/control/api/v1/households/{household_id}/groups" payload = {} headers = {"Authorization": f"Bearer {token}"} @@ -53,11 +53,11 @@ def getGroups(houshold_id, token): return response -def createToken(code, sonos_encoded_credentials): +def create_token(code, sonos_encoded_credentials, host): """ Creates a token given a code """ - url = f"https://api.sonos.com/login/v3/oauth/access?grant_type=authorization_code&code={code}&redirect_uri=http://localhost:5000/connect_sonos.api" + url = f"https://api.sonos.com/login/v3/oauth/access?grant_type=authorization_code&code={code}&redirect_uri=http://{host}/connect_sonos.api" payload = {} headers = { @@ -70,7 +70,7 @@ def createToken(code, sonos_encoded_credentials): return response -def togglePlayPause(group_id, token): +def toggle_play_pause(group_id, token): """ Toggles the play/pause of a group """ @@ -86,7 +86,7 @@ def togglePlayPause(group_id, token): return response -def audioClip(audioclip_url, player_id, token): +def audio_clip(audioclip_url, player_id, token): """ Plays an audioclip from link to .mp3 file """ @@ -100,7 +100,7 @@ def audioClip(audioclip_url, player_id, token): "name": "Embla", "appId": "com.acme.app", "streamUrl": f"{audioclip_url}", - "volume": 30, + "volume": 50, "priority": "HIGH", "clipType": "CUSTOM", }