Movesense iOS API: devices disconnecting automatically - movesense

device firmware is custom based on 1.7.2
ios app is using the 1.28.1 cocoapod for Movesense.
app can see the device connect to it, and query the battery status. This all works fine, but a lot of times, after the battery status is queried, the device disconnects automatically, as seen via the response to MDS/ConnectedDevices, and on the device itself via debug logs:
Subscribed and listening for notifications. Press ESC to stop:
TODO not thoroughly tested
#6708 { {
"Timestamp": 5124990,
"Level": [
4,
"Verbose"
],
"Tag": "",
"Message": "BatteryChargeProvider::stoponGetRequest timeDiff: 51713"
} }
#6898 { {
"Timestamp": 5125142,
"Level": [
4,
"Verbose"
],
"Tag": "",
"Message": "Disconnect(const Address& rAddress) called"
} }
/Users/builduser/buildAgent/work/a29f59699a429e89/src/whiteboard /comm/internal/serial/SerialAdapter.cpp(246): ASSERT FAILED! [bufferData == TotalHeaderSize]
[1] 73425 abort wbcmd --port /dev/cu.usbserial-AI04RYMP SUBSCRIBESystem/Debug/4
and from the app debug:
Disconnected device: <MDSEvent at 0x282903300: header: {
"Content-Length" = 122;
"Content-Type" = "application/json";
Uri = "MDS/EventListener/23";
}
bodyDictionary: {
Body = {
Serial = 175030000645;
};
Method = DEL;
Response = {
Status = 200;
};
Uri = "suunto://MDS/ConnectedDevices";
}
0x282903300>
is anyone else seeing this? It happens randomly but frequently, and whether I'm connecting to one or multiple devices, makes no difference. When multiple devices are used, it happen to one at random. It will occur multiple times in a row: connect, get battery, disconnect, find the device, connect, get battery, disconnect.
Any help would be greatly appreciated.

Related

Device not going to Power off

I am reusing the following piece of code hr_wakeup app.
counter = counter + LED_BLINKING_PERIOD;
if (counter < AVAILABILITY_TIME)
{
asyncPut(WB_RES::LOCAL::UI_IND_VISUAL(), AsyncRequestOptions::Empty,
WB_RES::VisualIndTypeValues::SHORT_VISUAL_INDICATION);
return;
}
if (counter >= AVAILABILITY_TIME)
{
// Prepare AFE to wake-up mode
asyncPut(WB_RES::LOCAL::COMPONENT_MAX3000X_WAKEUP(),
AsyncRequestOptions(NULL, 0, true), (uint8_t)1);
// Make PUT request to switch LED on
asyncPut(WB_RES::LOCAL::COMPONENT_LED(), AsyncRequestOptions::Empty, true);
// Make PUT request to enter power off mode
asyncPut(WB_RES::LOCAL::SYSTEM_MODE(), AsyncRequestOptions(NULL, 0, true), // true = Force async
WB_RES::SystemModeValues::FULLPOWEROFF);
}
I have enabled Level 4 logs and I see the following
2022-01-11 13:59:52.693 14817-14817/D/LocationUpdatesServiceWithSensor: DEBUG LOG {"Body": {"Id": null, "Timestamp": 114284, "Level": 4, "Tag": "", "Message": "LedService::onPutRequest() called."}, "Uri": "184730000180/System/Debug/4", "Method": "PUT"}
2022-01-11 13:59:52.698 14817-14817D/LocationUpdatesServiceWithSensor: DEBUG LOG {"Body": {"Id": null, "Timestamp": 114284, "Level": 4, "Tag": "", "Message": "MAX3000X wake set to: 1"}, "Uri": "184730000180/System/Debug/4", "Method": "PUT"}
However, the device is not getting powered off. I can see the device in the phone.
I am using bootloader 2.0 and hence is there any change the api call I need to do ?
You should subscribe to the lead's detection in the startModule().
you will find the below code in the hrs_wakeup_app's startModule(0. do the same with your code.
// Subscribe to leads detection
asyncSubscribe(WB_RES::LOCAL::SYSTEM_STATES_STATEID(), AsyncRequestOptions::Empty, WB_RES::StateIdValues::CONNECTOR);
I am assuming you have already figured it out, as this was asked a year ago. I have started working with movesense recently and got this problem too. So just posting if anyone needs it.

Dialogflow - Firestore - Webhook call failed. Error: UNAVAILABLE, State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500

I am trying for a fulfillment in Dialogflow using Firebase. There is data in Firestore and the intent is expected to retrieve the results based on the given parameter in the related intent. The intent is enables for webhook call. But the intent returns with one of the predefined responses.
I always get the error "message": "Webhook call failed. Error: UNAVAILABLE, State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500."
Following is the Diagnostic Info from the test console
{
"responseId": "e27d24ba-cb14-4170-a7d8-a97314aee001-cad07fe1",
"queryResult": {
"queryText": "novaluron",
"parameters": {
"chemical": "novaluron"
},
"allRequiredParamsPresent": true,
"fulfillmentText": "This molecule is useful",
"fulfillmentMessages": [
{
"text": {
"text": [
"This molecule is useful"
]
}
}
],
"intent": {
"name": "projects/ppcagent-ahe9/agent/intents/6d9df198-9517-4d61-a480-87c158accdc5",
"displayName": "ChemicalDetails"
},
"intentDetectionConfidence": 0.3,
"diagnosticInfo": {
"webhook_latency_ms": 106
},
"languageCode": "en",
"sentimentAnalysisResult": {
"queryTextSentiment": {
"score": 0.3,
"magnitude": 0.3
}
}
},
"webhookStatus": {
"code": 14,
"message": "Webhook call failed. Error: UNAVAILABLE, State: URL_UNREACHABLE, Reason: UNREACHABLE_5xx, HTTP status code: 500."
}
}
Any help will be greatly appreciated.
This error could be due to different reasons, you can check these points:
Use of insecure connection.
You need to use HTTP requests. The service must use HTTPS and the URL must be publicly accessible in order for the fulfillment to function. DialogFlow does not support self-signed SSL certs. For information on SSL setup:
Permission errors.
Server files and folders need correct permissions and ownerships set in order to work properly. If Websites request files for which the server has no access then it will lead to an error.You can see more documentation about permission.
Bad scripting.
You need to check the code and check if there are any errors and modify them.

"The agent returned an empty TTS" when action is not opened separately to asking an intent

When I invoke the skill with 'okay Google, ask {skillname} to {utterance}' I get the response 'The agent returned an empty tts" and the conversation closes. It doesn't even seem to hit my backend - I've tried hosting the backend code on both a local server and on AWS and the same issue happens in both cases. There's no log of the request being made either on Stackdriver on Google or on CloudWatch on AWS. The only response I get is the following in the debug tab:
{
"response": "The agent returned an empty TTS.",
"expectUserResponse": false,
"conversationToken": "EosDS2o4d0...",
"audioResponse": "",
"ssmlMarkList": [],
"debugInfo": {
"sharedDebugInfoList": [
{
"name": "Response Validation",
"debugInfo": "The agent returned an empty TTS.",
"subDebugEntryList": []
}
],
"conversationBuilderExecutionEventsList": []
},
"visualResponse": {
"visualElementsList": [
{
"displayText": {
"content": "The agent returned an empty TTS."
}
}
],
"suggestionsList": [],
"agentLogoUrl": ""
},
"clientError": 0,
"is3pResponse": true,
"clientOperationList": [],
"projectName": "",
"renderedHtml": ""
}
Nothing in any of the other tabs. When I try invoking the phrases in the same way on my phone, I just see a loading symbol and again nothing in the logs to say it's even hitting the backend.
Weirdly, this doesn't happen when I say 'okay Google, talk to {skillname} {utterance}' - this works absolutely fine.
All the intents work perfectly well when I've opened my action first, and then invoke them. I've built this using Jovo and published on Alexa also and the problem is only happening on Google.

PWA - beforeinstallprompt not called

Hello I'm trying to install a custom PWA "Add to Homescreen".
The ServiceWorkerRegistration is successful.
But the function beforeinstallpromp is not calling after register.
<script type="text/javascript">
function request_debug(paramdata){
document.getElementById('output').innerHTML += '<BR>'+ paramdata;
}
window.addEventListener('load', function() {
document.getElementById('output').style.display = "block";
if('serviceWorker' in navigator) {
navigator.serviceWorker.register('sw.js').then(function(registration) {
console.log('Service worker registrado com sucesso:', registration);
request_debug(registration);
}).catch(function(error) {
console.log('Falha ao Registrar o Service Worker:', error);
request_debug(error);
});
var isTooSoon = true;
window.addEventListener('beforeinstallprompt', function(e) {
//e.preventDefault();
//e.prompt();
//promptEvent = e;
request_debug(' window.addEventListener beforeinstallprompt fired!')
if (isTooSoon) {
//e.preventDefault(); // Prevents prompt display
// Prompt later instead:
setTimeout(function() {
isTooSoon = false;
e.prompt(); // Throws if called more than once or default not prevented
}, 4000);
}
});
}else{
console.log('serviceWorker not in navigator');
request_debug('serviceWorker not in navigator');
}
});
</script>
Also my service worker in root directory...
HTTPS is secure!
my manifest:
{
"background_color": "purple",
"description": "lojaportaldotricot TESTE",
"display": "standalone",
"icons": [
{
"src": "/componentes/serviceWorker/fox-icon.png",
"sizes": "192x192",
"type": "image/png"
}
],
"name": "lojaportaldotricot",
"short_name": "lojaportaldotricot",
"start_url": "/dashboard"
}
It's only workes when I set "Enable" chrome://flags/#bypass-app-banner-engagement-checks
Edit: Look's like I've found the problem. The Audits tabs of Chrome's DevTools(F12) gives debugging information.
Try this :
<script>
let deferredPrompt;
window.addEventListener('beforeinstallprompt', function(event) {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
});
// Installation must be done by a user gesture! Here, the button click
btnAdd.addEventListener('click', (e) => {
// hide our user interface that shows our A2HS button
btnAdd.style.display = 'none';
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice
.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
});
</script>
beforeinstallprompt will only be fired when some conditions are true :
The PWA must not already be installed
Meets a user engagement heuristic (previously, the user had to interact with the domain for at least 30 seconds, this is not a requirement anymore).
Your web app must include a web app manifest.
Your web app must be served over a secure HTTPS connection.
Has registered a service worker with a fetch event handler.
Along with all of those steps above, also check that the app is uninstalled here:
chrome://apps
Just deleting the app from the Chrome Apps folder on your Mac does not seem to remove it from Chrome
If the app was previously installed, the beforeinstallprompt will not be triggered, and no errors will be thrown either :(
Yes, the "start_url" is incorrect in the manifest.
IF ANY PART OF THE MANIFEST IS BROKEN 'beforeinstallprompt' is not fired.
The event is not fired because... the manifest start_url is incorrect.
My favorite way to figure this out is to look in the > NETWORK tab of DevTools for 404's.
AND the other way to see why manifest is broken is to run > AUDIT in DevTools and see what the error is. Like what #sealabr found:
"Failures: Service worker does not successfully serve the manifest's start_url, Timed out waiting for fetched start_url.' Which means the 'start_url"
This thread was a big help troubleshooting production. Thanks.
Are you including the manifest file in the page header?
<link rel="manifest" href="/manifest.json">
To whoever needs to read this: A little side-note that I ran into when working on my Vue3 app while trying to figure out the prompt:
The beforeInstallPrompt will trigger shortly after the page load.
So make sure you set up the event listener close to the page load. Took me a couple of hours to find this out. I was trying to add the event listener somewhere down the line of onboarding the user. Way after the page load. And couldn't figure out why the prompt didn't show.
here is another reason why beforeinstallprompt is not triggered on a mobile device (observed on an Android device with Chrome):
A symbol file defined in manifest.webmanifest could not be found on the web server (the mobile browser reported a 404). That was the reason why beforeinstallprompt was not triggered in my case.
#example
// your manifest
{
/* ... */
"icons": [
{
"src": "maskable_icon_x192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
/*...*/
]
}
Make sure that all icon files (such as maskable_icon_x192.png) are present on your web server.
All the best,
Tom

Google Actions SDK Sign-In implicit flow

EDIT: On phone assistant its working now problem just exist in google action simulator
I just try to setup Google Actions SDK account Linking with implicit grant and try to test it in Simulator.
First question is this even possible in Simulator?
To Do so I added at the action console account linking with the type
implicit grant to my action.
The url I used is working.
Now I added a signup request to my action. For testing so if I write signup in simulator the server response with:
{
conversationToken: JSON.stringify(state),
expectUserResponse: true,
expectedInputs: [
{
inputPrompt: {
initialPrompts: [
{
textToSpeech: "PLACEHOLDER_FOR_SIGN_IN"
}
],
noInputPrompts: []
},
possibleIntents: [
{
"intent": "actions.intent.SIGN_IN",
"inputValueData": {}
}
],
speechBiasingHints: []
}
]
}
After this the server didn't request the sign in page route (the address is correct!). It just responds with SignIN intent ERROR :
{
"isInSandbox'": false,
"surface": {
"capabilities": [
{
"name": "actions.capability.AUDIO_OUTPUT"
},
{
"name": "actions.capability.SCREEN_OUTPUT"
}
]
},
"inputs": [
{
"rawInputs": [
{
"query": "i think so",
"inputType": "VOICE"
}
],
"arguments": [
{
"name": "SIGN_IN",
'extension': {
"#type": "type.googleapis.com/google.actions.v2.SignInValue",
"status": "Error"
}
}
],
"intent': "actions.intent.SIGN_IN"
}
],
"device": {
"locale": "en-US"
},
"conversation": {
"conversationId": "1494606917128",
"type": "ACTIVE",
"conversationToken": "[\"_actions_on_google_\"]"
}
}
Why? Where is the problem? Can I see a error message somewhere?
Here is what happen in the simulator between 3 and 4:
Is it same when you use the phone app? For me it opens an embedded browser with my /auth endpoint, which the simulator doesn’t do.
I am able to make it WORKING after a long time.
We have to enable the webhook first and we can see how to enable the webhook in the dialog flow fulfillment docs
If we are going to use Google Assistant, then we have to enable the Google Assistant Integration in the integrations first.
Then follow the steps mentioned below for the Account Linking in actions on google:-
Go to google cloud console -> APIsand Services -> Credentials -> OAuth 2.0 client IDs -> Web client -> Note the client ID, client secret from there
-> Download JSON - from json note down the project id, auth_uri, token_uri
-> Authorised Redirect URIs -> White list our app's URL -> in this URL fixed part is https://oauth-redirect.googleusercontent.com/r/ and append the project id in the URL
-> Save the changes
Actions on Google -> Account linking setup
1. Grant type = Authorisation code
2. Client info
1. Fill up client id,client secrtet, auth_uri, token_uri
2. Enter the auth uri as https://www.googleapis.com/auth and token_uri as https://www.googleapis.com/token
3. Save and run
4. It will show an error while running on the google assistant, but dont worry
5. Come back to the account linking section in the assistant settings and enter auth_uri as https://accounts.google.com/o/oauth2/auth
and token_uri as https://accounts.google.com/o/oauth2/token
6. Put the scopes as https://www.googleapis.com/auth/userinfo.profile and https://www.googleapis.com/auth/userinfo.email
and weare good to go.
7. Save the changes.
In the hosting server logs, we can see the access token value and through access token, we can get the details regarding the email address.
Append the access token to this link "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" and we can get the required details in the resulting json page.
accessToken = req.get("originalRequest").get("data").get("user").get("accessToken")
r = requests.get(link)
print("Email Id= " + r.json()["email"])
print("Name= " + r.json()["name"])
P.S. You can use the Grant Type as Implicit also instead of Authorisation code.