I try to get the characteristics everytime they change, the problem is, they change but the eventListener doesn't recognize it. So i only get the first value, after connecting to my BLE, but nothing happen after that. Is there something wrong in my code ?
Another Question, is there a way to update the characteristic every, i dont know 5 Seconds for example? And how would you do that, are there any code examples?(Maybe with setInterval() ? )
Thank you !
function test() {
console.log('Requesting Bluetooth Device...');
navigator.bluetooth.requestDevice({
acceptAllDevices: true,
optionalServices: ['af07ecb8-e525-f189-9043-0f9c532a02c7']
}) //c7022a53-9c0f-4390-89f1-25e5b8ec07af
.then(device => {
console.log('Gatt Server Verbindung');
return device.gatt.connect();
})
.then(server => {
console.log('Dose Service...');
return server.getPrimaryService('af07ecb8-e525-f189-9043-0f9c532a02c7');
})
.then(service => {
console.log('mgyh Characteristic...');
return service.getCharacteristic('a99e0be6-f705-f59c-f248-230f7d55c3c1');
})
.then(characteristic => {
// Set up event listener for when characteristic value changes.
characteristic.addEventListener('characteristicvaluechanged',dosechanged);
return characteristic.readValue();
})
.catch(error => {
console.log('Das geht nicht: ' + error);
});
}
function dosechanged(event) {
let dose = event.target.value.getUint8(0)+event.target.value.getUint8(1)*10+event.target.value.getUint8(2)*100 + event.target.value.getUint8(3)*1000+ event.target.value.getUint8(4)*10000;
console.log('Received ' + dose);
}
You missed a characteristic.startNotifications() call to start receive notification. example
setInterval would be fine to call readValue() every 5 seconds.
Related
I am new to automation and coding in general and I would like to compare two session ID values with the following steps:
Get first value right after logging in
Refresh page
Get second value and make an assertion.
I made a custom command in order to simplify things:
Cypress.Commands.add('getSessionId', () => {
let sessionId
cy.getCookie('development')
.its('value').then(($value) => {
sessionId = String($value)
})
})
I want the test script to look something like this:
let firstSessionId = cy.getSessionId()
cy.reload()
let secondSessionId = cy.getSessionId()
expect(firstSessionId).to.eq(secondSessionId)
There are two problems with this:
I cannot access the values as strings in this scenario
The expect runs before getting the ID's (i guess because of the asyncronous nature of cypress?)
I would appreciate any hint what I do wrong. Thanks
This is the simplest way to perform the test, no need for a custom command in this case.
cy.getCookie('development').its('value')
.then(sessionId1 => {
cy.reload()
cy.getCookie('development').its('value')
.then(sessionId2 => {
expect(sessionId1).to.eq(sessionId2)
})
})
If you want a custom command for other reasons,
Cypress.Commands.add('getSessionId', () => {
cy.getCookie('development').its('value') // last command is returned
})
cy.getSessionId().then(sessionId1 => {
cy.reload()
cy.getSessionId().then(sessionId2 => {
expect(sessionId1).to.eq(sessionId2)
})
})
You can return the value from the custom command like this:
Cypress.Commands.add('getSessionId', () => {
cy.getCookie('development')
.its('value')
.then((val) => {
return cy.wrap(val)
})
})
Then in your test, you can do this:
//Get First session Id
cy.getSessionId.then((sessionId1) => {
cy.wrap(sessionId1).as('sessionId1')
})
//Refresh Page
cy.reload()
//Get Second session Id
cy.getSessionId.then((sessionId2) => {
cy.wrap(sessionId2).as('sessionId2')
})
//Assert both
cy.get('#sessionId1').then((sessionId1) => {
cy.get('#sessionId2').then((sessionId2) => {
expect(sessionId1).to.eq(sessionId2)
})
})
I am working on a project that creates a google chrome extension and I am using chrome API's in it. Now, I am trying to work my handleTabUpdate function when tab is updated. However, I am getting Unchecked runtime.lastError: No tab with id: 60
How can I fixed that? Here is my code:
chrome.tabs.onUpdated.addListener(handleTabUpdate)
function handleTabUpdate(tabId, info) {
if (info.status === 'loading') {
store.dispatch({ type: 'RESET_TABHOSTS' })
chrome.tabs.get(tabId, (activeTab) => {
if (tabId === store.getState().currentTab['id']) {
store.dispatch({ type: 'ACTIVE_TAB', payload: activeTab })
}
})
}
}
My guess is the tab you are looking for was closed, so when you try to get it by id the operation fails.
To avoid the error, my suggestion is to first query all tabs and see if a tab with a specific id exists in the result. If it does, run chrome.tabs.get() and with your logic.
Just bumped up against this issue in MV3 and I've tooled a solution that allows a bit more ease when working with tabs.
Functions
const handleRuntimeError = () => {
const error = chrome.runtime.lastError;
if (error) {
throw new Error(error);
}
};
const safeGetTab = async (tabId) => {
const tab = await chrome.tabs.get(parseInt(tabId));
try {
handleRuntimeError();
return tab;
} catch (e){
console.log('safeGetTab', e.message);
}
return {};
};
Implementation
(async () => {
// assumes some tabId
const tab = await safeGetTab(tabId);
})()
This will return a value no matter what. It will either return the tab object or an empty object. Then you can can just do some basic checking in your script to decide how you want to handle that. In my case I can simply ignore the action that would have been taken on that tab and move on.
I have this effect that request serveral values to retrive a product from service. Afer dispatch REQUEST_PRODUCTS is called one time as expected, but when I tried go to other location in the routing the this.apiMarketServices is called serveral times, this trigger the router navigate and this will redirect to previous page. The action REQUEST_PRODUCTS is dispatched one time. Why this effect is called serveral times?
Do I need add some kind of stop to the effect in order to avoid the called after the return GetSuccess and GetFailed?
#Effect()
requestProductsFromMarket = this.actions$
.ofType(REQUEST_PRODUCTS)
.withLatestFrom(this.store)
.switchMap(([action, store]) => {
const id = store.product.id;
return this.savedProducts.getProduct(id, 'store');
})
.switchMap(_ => this.stateService.getMarketId())
.switchMap(({ marketId }) =>
this.apiMarketServices.get(MARKETS_PROFILES + marketId)
)
.withLatestFrom(this.store)
.map(([r, store]) => {
const ser = r.data.map(s => s.legId);
const storSer =
store.product.serIds;
if (storSer.every(s =>ser.includes(s))) {
this.router.navigate([
`/products/edit/${store.products.id}`
]);
return GetSuccess;
} else {
return GetFailed;
}
})
.catch(() => of(GetQueryFailed));
The solution for defect is related to an Observable. In the debugging the "this.apiMarketServices.get(MARKETS_PROFILES + marketId)" was called several times, I realted this services like cause of the defect:
.switchMap(({ marketId }) =>
this.apiMarketServices.get(MARKETS_PROFILES + marketId)
)
But the real cause was the stateSevice, this behavior subject was updated with next, in anothers parts of the app.
.switchMap(_ => this.stateService.getMarketId())
In order to avoid those calls, I created a function in order to retrive the current value from the BehaviorSubject.
getCurrentMarketId(): ClientData {
return this.currentMarket.value; // BehaviorSubject
}
I added this function to the effect the call is once per dispatched effect.
...
.switchMap(([action, store]) => {
const id = store.product.id;
return this.savedProducts.getProduct(id, 'store');
})
.map(_ => this.stateService.getCurrentMarketId())
.switchMap(({ marketId }) =>
this.apiMarketServices.get(MARKETS_PROFILES + marketId)
)
The promise that is returned by userRef.remove() is not giving any error, it always goes to then block even though if I change the non existing path dbRef.child('userssafasfsadf/' + userID); like so.
function deleteButtonClicked(e) {
e.stopPropagation();
var userID = e.target.getAttribute("userid");
const userRef = dbRef.child('users/' + userID);
userRef.remove()
.then(() => {
console.log('success!, show alert now');
})
.catch(err => {
console.log('errorcode', err.code);
});
}
Any help would be appreciated. Thanks.
It sounds like you're expecting the remove() function to generate an error if there was no data at the given location. It doesn't work that way, because the remove() is not transactional. Someone else could have removed the data a split second ahead of you, and that's OK. Database operations only return errors when a security rule is violated.
I created a service that gets the some data from the api this is the code
getChallenges(): Observable<IChallenge[]> {
if (this._challengeUrl != null) {
return this.http.get(this._challengeUrl)
.map((res:Response) => <IChallenge[]>res.json())
.do(data => console.log('data: ' + JSON.stringify(data)))
.catch(this.handleError);
} else {
//;
}
}
and i subscribe inside the component where i want to use the service inside ngOnInit and everything is running my fine.
this._challengeService.getChallenges()
.subscribe(challenges => this.challenges = challenges,
error => this.errorMessage = <any>error);
but now i need to use a filter on the data which should run after ngInit finishes getting the data. this is the filter:
filterByLvl(lvl){
this.challenges.filter((obj)=> obj.level == lvl);
}
well my problem is when i try to put the function after the subscribe code i keep getting an empty array because the ngOnInit runs this function first and then gets the data. how can i inverse this? i need to get the data and then run this function.
so any ideas on how to do this? and thanks
I haven't tried ( don't have access to angular2 at work :-( ), but you can have multiple statements in the lambda function in subscribe.
this._challengeService.getChallenges()
.subscribe(challenges =>
{
this.challenges = challenges;
filterByLvl(expert_level);
},
error => this.errorMessage = <any>error
);
One method would be filter directly when it retrieves the data something like:
this._challengeService.getChallenges()
.subscribe(challenges => this.challenges = challenges.filter((obj)=> obj.level == lvl),
error => this.errorMessage = <any>error);
NOTE The lvl will be undefined so you've to define it someway with your logic