alexa-actions
alexa-actions copied to clipboard
ResponseNone automation is not triggered
Hi there. I'm just new with actionable notifications, but my project is step by step taking a form.
The target is a notification as this: "Tomorrow the plastic garbage will be collected. Did you take the garbage outside?" If yes, nothing happens. If the answer will be "no" or no answer is given, an automation will ask the same question in a 10 minutes.
How to do that:
My project is quite simple: I have a input.boolean that I toggle with a scheduler every week. (the garbage is collected every 2 weeks, so in week 1 the boolean is off and the week 2 the boolean will be on). An automation triggered by the "on" state of the input.boolean calls the "plastic garbage" script, wich contains the actionable notification.
If no or none, another automation (1 for NO and 1 for None, of course ;)) calls back the script with a delay of 10 minutes.
This is how magic happens. Now the problem:
The automations for RespondeNo and ResponseNone are identical, but the ResponseNo works, the RespondeNone is not working, I mean that seems that it's not triggered.
Here's the automations (5 seconds of delay because i'm testing them)
-alias: "Buttare la plastica No"
trigger:
-platform: event
event_type: alexa_actionable_notification
event_data:
event_id: rifiuti_plastica
event_response_type: ResponseNo
action:
-service: notify.alexa_media_echo_dot_studio
data:
message: te lo ricorderò a breve.
data:
type: tts
-delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
-service: script.buttare_la_plastica
-alias: "Buttare la plastica No"
trigger:
-platform: event
event_type: alexa_actionable_notification
event_data:
event_id: rifiuti_plastica
event_response_type: ResponseNone
action:
-service: notify.alexa_media_echo_dot_studio
data:
message: te lo ricorderò a breve.
data:
type: tts
-delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
-service: script.buttare_la_plastica
And there is the script:
alias: Buttare la plastica
sequence:
- service: script.activate_alexa_actionable_notification
data:
text: Domani ritireranno la plastica. Avete portato fuori il sacco?
event_id: rifiuti_plastica
alexa_device: media_player.echo_dot_studio
mode: single
Some advices? Thanks.
This integration doesn't have a handler for that so it makes sense it won't work. You either need to develop a handler for Alexa or wait for the devs to do so.
Added this to the backlog :)
@DEADSEC-SECURITY Are you sating that "ResponseNone" feature doesn't work in any case? :)
Nop it hasn't been implemented yet. I added it to the backlog for future development.
@calcioscacchi could you confirm what device your using?
Also I don't have an alexa near me to test this so if you can would you be able to update the class SessionEndedRequestHandler
to the following code?
class SessionEndedRequestHandler(AbstractRequestHandler):
"""Handler for Session End."""
def can_handle(self, handler_input):
"""Check for Session End."""
return is_request_type('SessionEndedRequest')(handler_input)
def handle(self, handler_input):
"""Clean up and stop the skill."""
logger.info('Session Ended Request Handler triggered')
ha_obj = HomeAssistant(handler_input)
reason = handler_input.request_envelope.request.reason
logger.info("------ OUTPUT FROM REASON ------")
logger.info(reason)
if reason == SessionEndedReason.EXCEEDED_MAX_REPROMPTS:
ha_obj.post_ha_event(RESPONSE_NONE, RESPONSE_NONE)
return handler_input.response_builder.response
and ask alexa but don't respond so it triggers the end of the session and then post here the cloudwatch log.
If you don't feel confortable with technical stuff its ok but it might take a couple time until I'm able to fully test this and merge to main
This code will simply log the reason returned by amazon to cloudwatch so I can check what type of reason is amazon associating to no response.
I'm using an echo 4gen, the one with zigbee hub. I think that i can test your code but here is the 01:32 AM so i'm a little unable to do it XD
All that i will do will be to cut this section in lambda_function.py (starting from row 314):
class SessionEndedRequestHandler(AbstractRequestHandler):
"""Handler for Session End."""
def can_handle(self, handler_input):
return ask_utils.is_request_type("SessionEndedRequest")(handler_input)
def handle(self, handler_input):
home_assistant_object = HomeAssistant(handler_input)
if handler_input.request_envelope.request.reason == SessionEndedReason.EXCEEDED_MAX_REPROMPTS:
home_assistant_object.post_ha_event(RESPONSE_NONE, RESPONSE_NONE)
return handler_input.response_builder.response
and replace it with your code. Just an hint... where can i find the cloudwatch log?
Tried with alexa simulator in test area of Developer Console... The skill once activated give me this Json output:
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Domani ritireranno la plastica. Avete portato fuori il sacco?</speak>"
},
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak></speak>"
}
},
"shouldEndSession": false,
"type": "_DEFAULT_RESPONSE"
},
"sessionAttributes": {},
"userAgent": "ask-python/1.11.0 Python/3.7.13"
}
}
Ok, first time trying it, not sure that this is what you need. Once again, I only try to activate the skill via test area
START RequestId: 46dc38bc-51e3-4583-87d5-2c6071123121 Version: 10
[INFO] 2022-07-13T00:03:24.859Z 46dc38bc-51e3-4583-87d5-2c6071123121 Locale is it CatchAllExceptionHandler [ERROR] 2022-07-13T00:03:24.860Z 46dc38bc-51e3-4583-87d5-2c6071123121 name 'is_request_type' is not defined Traceback (most recent call last): File "/var/task/ask_sdk_runtime/dispatch.py", line 118, in dispatch output = self.__dispatch_request(handler_input) # type: Union[Output, None] File "/var/task/ask_sdk_runtime/dispatch.py", line 159, in __dispatch_request handler_input) File "/var/task/ask_sdk_runtime/dispatch_components/request_components.py", line 365, in get_request_handler_chain if handler.can_handle(handler_input=handler_input): File "/var/task/lambda_function.py", line 319, in can_handle return is_request_type('SessionEndedRequest')(handler_input) NameError: name 'is_request_type' is not defined [ERROR] AttributeError: 'HomeAssistant' object has no attribute 'handler_input'Traceback (most recent call last): File "/var/task/ask_sdk_core/skill_builder.py", line 111, in wrapper request_envelope=request_envelope, context=context) File "/var/task/ask_sdk_core/skill.py", line 207, in invoke handler_input=handler_input) File "/var/task/ask_sdk_runtime/dispatch.py", line 131, in dispatch return exception_handler.handle(handler_input, e) File "/var/task/lambda_function.py", line 365, in handle home_assistant_object = HomeAssistant() File "/var/task/lambda_function.py", line 57, in init self.get_ha_state() File "/var/task/lambda_function.py", line 99, in get_ha_state errors = self._check_response_errors(response) File "/var/task/lambda_function.py", line 66, in check_response_errors data = self.handler_input.attributes_manager.request_attributes[""] END RequestId: 46dc38bc-51e3-4583-87d5-2c6071123121 REPORT RequestId: 46dc38bc-51e3-4583-87d5-2c6071123121 Duration: 442.99 ms Billed Duration: 443 ms Memory Size: 512 MB Max Memory Used: 50 MB Init Duration: 343.91 ms START RequestId: 5b493eea-5207-4beb-ab54-25c89ffe7409 Version: 10 [INFO] 2022-07-13T00:03:25.340Z 5b493eea-5207-4beb-ab54-25c89ffe7409 Locale is it END RequestId: 5b493eea-5207-4beb-ab54-25c89ffe7409 REPORT RequestId: 5b493eea-5207-4beb-ab54-25c89ffe7409 Duration: 250.49 ms Billed Duration: 251 ms Memory Size: 512 MB Max Memory Used: 51 MB
Ill resume this tomorrow :) Thanks
@calcioscacchi Can you send me your code? You seem to be missing some import statements
This is my lambda function:
## VERSION 0.8.2
# UPDATE THESE VARIABLES WITH YOUR CONFIG
HOME_ASSISTANT_URL = 'https://calcioscacchi.duckdns.org:9000' # REPLACE WITH THE URL FOR YOUR HA FRONTEND
VERIFY_SSL = True # SET TO FALSE IF YOU DO NOT HAVE VALID CERTS
TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIzNzYzZWZkZmRlYzk0MzVmOTkwZjYzOTQ3NzQxYmZkZCIsImlhdCI6MTY1NTY1NTA2OCwiZXhwIjoxOTcxMDE1MDY4fQ.krZVZujwdLv1ssQOrr-AGcSyS87BtpEWn4yF6M--FtQ" # ADD YOUR LONG LIVED TOKEN IF NEEDED OTHERWISE LEAVE BLANK
### NO NEED TO EDIT ANYTHING UNDER THE LINE ###
import logging
import urllib3
import json
import isodate
import prompts
from datetime import datetime
import ask_sdk_core.utils as ask_utils
from ask_sdk_core.skill_builder import SkillBuilder
from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.dispatch_components import AbstractExceptionHandler
from ask_sdk_core.dispatch_components import AbstractRequestInterceptor
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model import SessionEndedReason
from ask_sdk_model.slu.entityresolution import StatusCode
from ask_sdk_model import Response
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
INPUT_TEXT_ENTITY = "input_text.alexa_actionable_notification"
RESPONSE_YES = "ResponseYes"
RESPONSE_NO = "ResponseNo"
RESPONSE_NONE = "ResponseNone"
RESPONSE_SELECT = "ResponseSelect"
RESPONSE_NUMERIC = "ResponseNumeric"
RESPONSE_DURATION = "ResponseDuration"
class Borg:
"""Borg MonoState Class for State Persistence."""
_shared_state = {}
def __init__(self):
self.__dict__ = self._shared_state
class HomeAssistant(Borg):
"""HomeAssistant Wrapper Class."""
def __init__(self, handler_input=None):
Borg.__init__(self)
if handler_input:
self.handler_input = handler_input
self.token = self._fetch_token() if TOKEN == "" else TOKEN
if not hasattr(self, 'ha_state') or self.ha_state is None:
self.get_ha_state()
def _clear_state(self):
self.ha_state = None
def _fetch_token(self):
return ask_utils.get_account_linking_access_token(self.handler_input)
def _check_response_errors(self, response):
data = self.handler_input.attributes_manager.request_attributes["_"]
if response.status == 401:
logger.error("401 Error", response.data)
speak_output = "Error 401 " + data[prompts.ERROR_401]
return speak_output
elif response.status == 404:
logger.error("404 Error", response.data)
speak_output = "Error 404 " + data[prompts.ERROR_404]
return speak_output
elif response.status >= 400:
logger.error("{response.status} Error", response.data)
speak_output = "Error {response.status} " + data[prompts.ERROR_400]
return speak_output
return None
def get_ha_state(self):
"""Get State from HA."""
http = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED' if VERIFY_SSL else 'CERT_NONE',
timeout=urllib3.Timeout(connect=10.0, read=10.0)
)
response = http.request(
'GET',
'{}/api/states/{}'.format(HOME_ASSISTANT_URL, INPUT_TEXT_ENTITY),
headers={
'Authorization': 'Bearer {}'.format(self.token),
'Content-Type': 'application/json'
},
)
errors = self._check_response_errors(response)
if not errors:
self.ha_state = {
"error": True,
"text": errors
}
decoded_response = json.loads(response.data.decode('utf-8'))['state']
self.ha_state = {
"error": False,
"event_id": json.loads(decoded_response)['event'],
"text": json.loads(decoded_response)['text']
}
def post_ha_event(self, response: str, response_type: str, **kwargs):
"""Send event to HA."""
http = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED' if VERIFY_SSL else 'CERT_NONE',
timeout=urllib3.Timeout(connect=10.0, read=10.0)
)
request_body = {
"event_id": self.ha_state['event_id'],
"event_response": response,
"event_response_type": response_type
}
request_body.update(kwargs)
if self.handler_input.request_envelope.context.system.person:
person_id = self.handler_input.request_envelope.context.system.person.person_id
request_body['event_person_id'] = person_id
response = http.request(
'POST',
'{}/api/events/alexa_actionable_notification'.format(HOME_ASSISTANT_URL),
headers={
'Authorization': 'Bearer {}'.format(self.token),
'Content-Type': 'application/json'
},
body=json.dumps(request_body).encode('utf-8')
)
error = self._check_response_errors(response)
if error:
return error
data = self.handler_input.attributes_manager.request_attributes["_"]
speak_output = data[prompts.OKAY]
self._clear_state()
return speak_output
def get_value_for_slot(self, slot_name):
""""Get value from slot, also know as the (why does amazon make you do this)"""
slot = ask_utils.get_slot(self.handler_input, slot_name=slot_name)
if slot and slot.resolutions and slot.resolutions.resolutions_per_authority:
for resolution in slot.resolutions.resolutions_per_authority:
if resolution.status.code == StatusCode.ER_SUCCESS_MATCH:
for value in resolution.values:
if value.value and value.value.name:
return value.value.name
class LaunchRequestHandler(AbstractRequestHandler):
"""Handler for Skill Launch."""
def can_handle(self, handler_input):
return ask_utils.is_request_type("LaunchRequest")(handler_input)
def handle(self, handler_input):
home_assistant_object = HomeAssistant(handler_input)
speak_output = home_assistant_object.ha_state['text']
return (
handler_input.response_builder
.speak(speak_output)
.ask('')
.response
)
class YesIntentHanlder(AbstractRequestHandler):
"""Handler for Yes Intent."""
def can_handle(self, handler_input):
return ask_utils.is_intent_name("AMAZON.YesIntent")(handler_input)
def handle(self, handler_input):
home_assistant_object = HomeAssistant(handler_input)
speak_output = home_assistant_object.post_ha_event(RESPONSE_YES, RESPONSE_YES)
return (
handler_input.response_builder
.speak(speak_output)
.response
)
class NoIntentHanlder(AbstractRequestHandler):
"""Handler for No Intent."""
def can_handle(self, handler_input):
return ask_utils.is_intent_name("AMAZON.NoIntent")(handler_input)
def handle(self, handler_input):
home_assistant_object = HomeAssistant(handler_input)
speak_output = home_assistant_object.post_ha_event(RESPONSE_NO, RESPONSE_NO)
return (
handler_input.response_builder
.speak(speak_output)
.response
)
class NumericIntentHandler(AbstractRequestHandler):
"""Handler for Select Intent."""
def can_handle(self, handler_input):
return ask_utils.is_intent_name("Number")(handler_input)
def handle(self, handler_input):
home_assistant_object = HomeAssistant(handler_input)
number = ask_utils.get_slot_value(handler_input, "Numbers")
if number == '?':
raise
speak_output = home_assistant_object.post_ha_event(number, RESPONSE_NUMERIC)
return (
handler_input.response_builder
.speak(speak_output)
.response
)
class SelectIntentHandler(AbstractRequestHandler):
"""Handler for Select Intent."""
def can_handle(self, handler_input):
return ask_utils.is_intent_name("Select")(handler_input)
def handle(self, handler_input):
home_assistant_object = HomeAssistant(handler_input)
selection = home_assistant_object.get_value_for_slot("Selections")
if selection:
home_assistant_object.post_ha_event(selection, RESPONSE_SELECT)
data = handler_input.attributes_manager.request_attributes["_"]
speak_output = data[prompts.SELECTED].format(selection)
else:
raise
return (
handler_input.response_builder
.speak(speak_output)
.response
)
class DurationIntentHandler(AbstractRequestHandler):
"""Handler for Select Intent."""
def can_handle(self, handler_input):
return ask_utils.is_intent_name("Duration")(handler_input)
def handle(self, handler_input):
home_assistant_object = HomeAssistant(handler_input)
duration = ask_utils.get_slot_value(handler_input, "Durations")
speak_output = home_assistant_object.post_ha_event(isodate.parse_duration(duration).total_seconds(), RESPONSE_DURATION)
return (
handler_input.response_builder
.speak(speak_output)
.response
)
class DateTimeIntentHandler(AbstractRequestHandler):
"""Handler for Select Intent."""
def can_handle(self, handler_input):
return ask_utils.is_intent_name("Date")(handler_input)
def handle(self, handler_input):
home_assistant_object = HomeAssistant(handler_input)
dates = ask_utils.get_slot_value(handler_input, "Dates")
times = ask_utils.get_slot_value(handler_input, "Times")
if not dates and not times:
raise
data = handler_input.attributes_manager.request_attributes["_"]
speak_output = data[prompts.ERROR_SPECIFIC_DATE]
return (
handler_input.response_builder
.speak(speak_output)
.ask('')
.response
)
class CancelOrStopIntentHandler(AbstractRequestHandler):
"""Single handler for Cancel and Stop Intent."""
def can_handle(self, handler_input):
return (ask_utils.is_intent_name("AMAZON.CancelIntent")(handler_input) or
ask_utils.is_intent_name("AMAZON.StopIntent")(handler_input))
def handle(self, handler_input):
print("CancelOrStopIntentHandler")
data = handler_input.attributes_manager.request_attributes["_"]
speak_output = data[prompts.STOP_MESSAGE]
return (
handler_input.response_builder
.speak(speak_output)
.response
)
class SessionEndedRequestHandler(AbstractRequestHandler):
"""Handler for Session End."""
def can_handle(self, handler_input):
"""Check for Session End."""
return is_request_type('SessionEndedRequest')(handler_input)
def handle(self, handler_input):
"""Clean up and stop the skill."""
logger.info('Session Ended Request Handler triggered')
ha_obj = HomeAssistant(handler_input)
reason = handler_input.request_envelope.request.reason
logger.info("------ OUTPUT FROM REASON ------")
logger.info(reason)
if reason == SessionEndedReason.EXCEEDED_MAX_REPROMPTS:
ha_obj.post_ha_event(RESPONSE_NONE, RESPONSE_NONE)
return handler_input.response_builder.response
class IntentReflectorHandler(AbstractRequestHandler):
"""The intent reflector is used for interaction model testing and debugging.
It will simply repeat the intent the user said. You can create custom handlers
for your intents by defining them above, then also adding them to the request
handler chain below.
"""
def can_handle(self, handler_input):
return ask_utils.is_request_type("IntentRequest")(handler_input)
def handle(self, handler_input):
intent_name = ask_utils.get_intent_name(handler_input)
speak_output = "You just triggered " + intent_name + "."
return (
handler_input.response_builder
.speak(speak_output)
.response
)
class CatchAllExceptionHandler(AbstractExceptionHandler):
"""Generic error handling to capture any syntax or routing errors. If you receive an error
stating the request handler chain is not found, you have not implemented a handler for
the intent being invoked or included it in the skill builder below.
"""
def can_handle(self, handler_input, exception):
return True
def handle(self, handler_input, exception):
print("CatchAllExceptionHandler")
logger.error(exception, exc_info=True)
home_assistant_object = HomeAssistant()
data = handler_input.attributes_manager.request_attributes["_"]
if hasattr(home_assistant_object, 'ha_state') and home_assistant_object.ha_state != None and 'text' in home_assistant_object.ha_state:
speak_output = data[prompts.ERROR_ACOUSTIC].format(home_assistant_object.ha_state['text'])
return (
handler_input.response_builder
.speak(speak_output)
.ask('')
.response
)
else:
speak_output = data[prompts.ERROR_CONFIG].format(home_assistant_object.ha_state['text'])
return (
handler_input.response_builder
.speak(speak_output)
.response
)
class LocalizationInterceptor(AbstractRequestInterceptor):
"""Add function to request attributes, that can load locale specific data."""
def process(self, handler_input):
locale = handler_input.request_envelope.request.locale
logger.info("Locale is {}".format(locale[:2]))
# localized strings stored in language_strings.json
with open("language_strings.json") as language_prompts:
language_data = json.load(language_prompts)
# set default translation data to broader translation
data = language_data[locale[:2]]
# if a more specialized translation exists, then select it instead
# example: "fr-CA" will pick "fr" translations first, but if "fr-CA" translation exists,
# then pick that instead
if locale in language_data:
data.update(language_data[locale])
handler_input.attributes_manager.request_attributes["_"] = data
# The SkillBuilder object acts as the entry point for your skill, routing all request and response
# payloads to the handlers above. Make sure any new handlers or interceptors you've
# defined are included below. The order matters - they're processed top to bottom.
sb = SkillBuilder()
# register request / intent handlers
sb.add_request_handler(LaunchRequestHandler())
sb.add_request_handler(YesIntentHanlder())
sb.add_request_handler(NoIntentHanlder())
sb.add_request_handler(SelectIntentHandler())
sb.add_request_handler(NumericIntentHandler())
sb.add_request_handler(DurationIntentHandler())
sb.add_request_handler(DateTimeIntentHandler())
sb.add_request_handler(CancelOrStopIntentHandler())
sb.add_request_handler(SessionEndedRequestHandler())
sb.add_request_handler(IntentReflectorHandler())
# register exception handlers
sb.add_exception_handler(CatchAllExceptionHandler())
# register response interceptors
sb.add_global_request_interceptor(LocalizationInterceptor())
lambda_handler = sb.lambda_handler()
All the is_request_type
you need to change to ask_utils.is_request_type
and that should fix it
Ok, i think that the only one that doesn't have that correction is this one:
class SessionEndedRequestHandler(AbstractRequestHandler):
"""Handler for Session End."""
def can_handle(self, handler_input):
"""Check for Session End."""
return **is_request_type**('SessionEndedRequest')(handler_input)
what about this log?
<html>
<body>
<!--StartFragment-->
START RequestId: 443a2317-b541-40da-86fd-c8a27641bc48 Version: 11
--
[INFO] 2022-07-21T20:25:01.077Z 443a2317-b541-40da-86fd-c8a27641bc48 Locale is it
END RequestId: 443a2317-b541-40da-86fd-c8a27641bc48
REPORT RequestId: 443a2317-b541-40da-86fd-c8a27641bc48 Duration: 468.61 ms Billed Duration: 469 ms Memory Size: 512 MB Max Memory Used: 50 MB Init Duration: 393.39 ms
<!--EndFragment-->
</body>
</html>
Can you send the new version of the code plus logs?
Do you mean the device log?
skill log
I tried to activate the skill cia Test area in developer console. I have 2 Input/Outputs messages:
This is the Json output 1:
{
"body": {
"version": "1.0",
"response": {
"type": "_DEFAULT_RESPONSE"
},
"sessionAttributes": {},
"userAgent": "ask-python/1.11.0 Python/3.7.13"
}
}
This is the JSON Output 2:
{
"body": {
"version": "1.0",
"response": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak>Questo è un test della skill personale. Funziona?</speak>"
},
"reprompt": {
"outputSpeech": {
"type": "SSML",
"ssml": "<speak></speak>"
}
},
"shouldEndSession": false,
"type": "_DEFAULT_RESPONSE"
},
"sessionAttributes": {},
"userAgent": "ask-python/1.11.0 Python/3.7.13"
}
}
Hope to be usefull.
not adding anything useful to the conversation by saying this but I have the same issue. There is no ReponseNone trigger and I'm using the latest code from a few days ago.
Let me know if I can assist in anyway I'd like to get this fixed and working.
Thanks
i have notice the same problem on my end but.... the none response works with my computer room echo dot 3rd gen but not the kitchen echo dot 2nd gen
I mean the actually cloudwacth log @calcioscacchi
i have notice the same problem on my end but.... the none response works with my computer room echo dot 3rd gen but not the kitchen echo dot 2nd gen
Interesting, I only tried on my echo show, I could try on my old echo dot to see if I get the none response.
i have notice the same problem on my end but.... the none response works with my computer room echo dot 3rd gen but not the kitchen echo dot 2nd gen
I have tried on my older "echo dot 2nd generation" and it works, but on my "echo show 8" doesn't. At this point I have no idea if this can even be fixed in the code here.
i have notice the same problem on my end but.... the none response works with my computer room echo dot 3rd gen but not the kitchen echo dot 2nd gen
I have tried on my older "echo dot 2nd generation" and it works, but on my "echo show 8" doesn't. At this point I have no idea if this can even be fixed in the code here.
Have you tried the recent code update on the show?
Have you tried the recent code update on the show?
I updated it last night, same result I'm afraid.
Have you tried this? https://www.amazon.com/gp/help/customer/display.html?nodeId=G62ZU6D99SYG3BWU
I have done that, a couple of times after updating the code.
In the Alexa skill as client ID I used the European one as suggested here https://youtu.be/uoifhNyEErE at 8:51, I'm in the UK should I try the UK one, or is it a pointless test?
Try the US one