Chrome App bluetooth - javascript

I am trying to create a chrome app that displays when a certain Bluetooth device is sending data. specifically, I have 2 bluetooth mice and I want to identify which one is being moved at a specific time.
I followed the Chrome dev doc and was successful until I tried to implement adding a listener on receive to view the data coming from the device. I am getting a "Cannot read property 'addListener' of undefined" error.
This is when I started getting this error:
Error message
Here's the code I'm working with
chrome.bluetooth.getDevices(function(devices) {
for (var i = 0; i < devices.length; i++) {
//Displaying device names
console.log(i+": "+devices[i].name);
}
//uuid for a specific device
var uuid = "00001200-0000-1000-8000-00805f9b34fb";
// var uuid = devices[4].uuid;
var onConnectedCallback = function() {
if (chrome.runtime.lastError) {
console.log("Connection failed: " + chrome.runtime.lastError.message);
} else {
// Profile implementation here.
}
};
chrome.bluetoothSocket.create(function(createInfo) {
chrome.bluetoothSocket.connect(createInfo.socketId,
devices[4].address, uuid, onConnectedCallback);
console.log(createInfo);
chrome.bluetoothSocket.onRecieve.addListener(function(receiveInfo) {
if (receiveInfo.socketId != socketId)
return;
console.log(receiveInfo);
});
});
});

Checked out this docs and managed to see a similar code snippet:
chrome.bluetoothSocket.onRecieve.addListener(function(receiveInfo) {
if (receiveInfo.socketId != socketId)
return;
// receiveInfo.data is an ArrayBuffer.
});
If you look at it carefully, it seems there was a typo in the sample at the onRecieve part. It should be onReceive. You can see a correct sample here.
I before E, except after C.

Related

QZ tray printing to multiple printers

I have been trying to print to multiple printers with QZ tray using the examples provided here https://qz.io/wiki/2.0-Raw-Printing#promise-loop
but I am getting an error saying TypeError: Cannot read property 'sendData' of null
I have rsvp-3.1.0.min.js, sha-256.min.js and qz-tray.js included.
I use the exact same code provided by the example but obviously changed the printers names to the ones I have installed.
Everything works fine if I try to print to each printer separately (the default way of doing it)
Any idea of what could be wrong or if I am missing a library or something?
Thank you
This is the full error message on Safari:
TypeError: Cannot read property 'sendData' of null
at qz-tray.js:323
at lib$rsvp$$internal$$initializePromise (rsvp-3.1.0.min.js:10)
at new lib$rsvp$promise$$Promise (rsvp-3.1.0.min.js:10)
at Object.promise (qz-tray.js:456)
at Object.dataPromise (qz-tray.js:314)
at Object.find (qz-tray.js:788)
at link (test.html:388)
at lib$rsvp$$internal$$tryCatch (rsvp-3.1.0.min.js:10)
at lib$rsvp$$internal$$invokeCallback (rsvp-3.1.0.min.js:10)
at rsvp-3.1.0.min.js:10
So I found the problem and it was my own mistake, I forgot to initiate QZ tray, the script works perfectly, tested sending a Pixel job to a laser printer and a Raw job to a thermal printer.
EDIT: Solution
function promiseLoop() {
var data = [
"^XA\n^FO50,50^ADN,36,20^FDPRINT 1 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 2 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 3 ^FS\n^XZ\n",
"^XA\n^FO50,50^ADN,36,20^FDPRINT 4 ^FS\n^XZ\n"
];
var configs = [
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" },
{ "printer": "ZDesigner LP2844-Z" }
];
var chain = [];
for(var i = 0; i < data.length; i++) {
(function(i_) {
//setup this chain link
var link = function() {
return qz.printers.find(configs[i_].printer).then(function(found) {
return qz.print(qz.configs.create(found), [data[i_]]);
});
};
chain.push(link);
})(i);
//closure ensures this promise's concept of `i` doesn't change
}
//can be .connect or `Promise.resolve()`, etc
var firstLink = new RSVP.Promise(function(r, e) { r(); });
var lastLink = null;
chain.reduce(function(sequence, link) {
lastLink = sequence.then(link);
return lastLink;
}, firstLink);
//this will be the very last link in the chain
lastLink.catch(function(err) {
console.error(err);
});
}
//Always make sure you are establishing a connection before printing
qz.websocket.connect().then(promiseLoop).catch(errorHandler);

Example/Explanation on chrome.sockets.udp multicasting

I am making an Chrome app which will have a 'chat' feature (like what this app has). When a user joins the chat (by connecting to a port), the user would receive all messages that were created during his/her session. However, although I understand most of the app's code, I couldn't understand how the multicasting part of the code exactly works.
From what I understand, this is how it should go:
var socket = 0;
chrome.sockets.udp.create({bufferSize: 1024 * 1024}, function (createInfo) //Create socket entry
{
socket = createInfo.socketId;
console.log(socket); //This works - tells me an integer
var ttl = 12;
chrome.sockets.udp.setMulticastTimeToLive(socket, ttl, function (result)
{
if(result < 0)
{
console.log("MULTICAST FAILED" + result);
}
else
{
chrome.sockets.udp.bind(socket, "0.0.0.0", 8080, function(result) //Bind to socket
{
if(result < 0)
{
console.log("BIND FAILED" + result);
chrome.sockets.udp.close(socket);
}
else
{
chrome.sockets.udp.joinGroup(socket, "237.132.123.123", function(result) //join Multicast group
{
if(result < 0)
{
console.log("Couldn't join Group!");
chrome.sockets.udp.close(socket);
}
else
{
console.log("GOT HERE"); //Outputs this
chrome.sockets.udp.onReceive.addListener(function(msg) //Listen for receiving messages
{
console.log(msg.socketId);
})
chrome.sockets.udp.onReceiveError.addListener(function(error) //If error while receiving, do this
{
console.log(error.socketId + " " + error.resultCode);
});
}
})
}
});
}
})
})
//Later in the code (linked to a button I press (and when app closes)
chrome.sockets.udp.close(socket);
The problem with this is that although the code reaches the callback function of .send() (which should mean that it sent successfully), I also get errors while binding saying that the socket doesn't exist (although I created it and the socket number outputted an integer). When I make two application with the same code as above and try to make them listen/send to each other, neither gets the message.
Can someone provide a clear example (no gui code, no runtime messaging) which illustrates how to multicast correctly using the newer chrome.sockets.udp?
Just had to deal with this, your code should work if you include this in your manifest:
"sockets": {
"udp": {
"send": ["*"],
"bind": ["*"],
"multicastMembership": [""]
}
}
If you already did, try changing your port / address in case your network is already using them. If that still doesn't work, try removing the options on create() and see if anything happens.
Sorry if I'm too late.

chrome.hid.send fails on second use

Something about my use of chrome.hid.send seems to be leaving the bus in a bad state. I consistently can NOT get my second usage of the API call to work. Sometimes, it will also fail on the first usage. WITH THE EXACT SAME CODE, I can come back and try a while later (maybe 10min) and the first send will work.
The device I'm working with does not return a response to all messages sent to it. The test message for example, is just a dummy message that is ignored by the device. I've tested this both on a mac and a PC. My call stack depth is 2 at this point in my application (literally first one is kicked off by a button click and then a setTimeout calls the same method 5s later).
I've testing sending buffers of length 64Bytes as well as 58Bytes. The properties from the HidDeviceInfo object read "maxInputReportSize":64,"maxOutputReportSize":64
Params on first usage:
Params on second usage:
I really can't identify how I'm using the API incorrectly. When messages do succeed, I can see them on the device side.
// Transmits the given data
//
// #param[in] outData, The data to send as an ArrayBuffer
// #param[in] onTxCompleted, The method called on completion of the outgoing transfer. The return
// code is passed as a string.
// #param[in] onRxCompleted, The method called on completion of the incoming transfer. The return
// code is passed as a string along with the response as an ArrayBuffer.
send: function(outData, onTxCompleted, onRxCompleted) {
if (-1 === connection_) {
console.log("Attempted to send data with no device connected.");
return;
}
if (0 == outData.byteLength) {
console.log("Attempted to send nothing.");
return;
}
if (COMMS.receiving) {
console.log("Waiting for a response to a previous message. Aborting.");
return;
}
if (COMMS.transmitting) {
console.log("Waiting for a previous message to finish sending. Aborting.");
return;
}
COMMS.transmitting = true;
var dummyUint8Array = new Uint8Array(outData);
chrome.hid.send(connection_, REPORT_ID, outData, function() {
COMMS.transmitting = false;
if (onTxCompleted) {
onTxCompleted(chrome.runtime.lastError ? chrome.runtime.lastError.message : '');
}
if (chrome.runtime.lastError) {
console.log('Error in COMMS.send: ' + chrome.runtime.lastError.message);
return;
}
// Register a response handler if one is expected
if (onRxCompleted) {
COMMS.receiving = true;
chrome.hid.receive(connection_, function(reportId, inData) {
COMMS.receiving = false;
onRxCompleted(chrome.runtime.lastError ? chrome.runtime.lastError.message : '', inData);
});
}
});
}
// Example usage
var testMessage = new Uint8Array(58);
var testTransmission = function() {
message[0] = 123;
COMMS.send(message.buffer, null, null);
setTimeout(testTransmission, 5000);
};
testTranmission();
The issue is that Windows requires buffers to be the full report size expected by the device. I have filed a bug against Chromium to track adding a workaround or at least a better error message to pinpoint the problem.
In general you can get more detailed error messages from the chrome.hid API by enabling verbose logging with the --enable-logging --v=1 command line options. Full documentation of Chrome logging is here.

Socket.IO disconnecting first user in room

I am having trouble with having the first user of the room I am trying to communicate to always leaving but this only happens when I check for its id.
socket.on('player moved', function(msg) {
var curr_room = msg.room_number;
var room_data = io.sockets.adapter.rooms[curr_room];
var temp_room = [];
console.log(room_data);
for (var id in room_data) {
temp_room.push(io.sockets.adapter.nsp.connected[id]);
}
var player1_id = temp_room[0].id;
var player2_id = temp_room[1].id;
console.log(player1_id);
console.log(player2_id);
console.log(msg.player_id);
if (player1_id && player2_id) {
if (player1_id === msg.player_id) {
temp_room[1].emit('update coords', "dude");
} else if ("ffff" === msg.player_id) {
console.log('tessting to see wheter i can be in')
temp_room[0].emit('update coords', "sweet");
}
}
So this works without any errors and when I console.log room data I see two sockets which is what I want, however if I change "ffff" to player2_id I get this weird error where for the first iteration of this function I get the two sockets but after that the first player disconnects and I'm left with
var player1_id = temp_room[0].id;
^
TypeError: Cannot read property 'id' of undefined
I have absolutely no idea why having this check would make the user disconnect and furthermore I have no idea why the user is disconnecting if the page remains open.
Anybody have any insights, it would be greatly appreciated!
Thanks!!

Check for duplicate record in Chrome Storage extension before saving

I'm developing a small Chrome extension that would allow me to save some records to chrome.storage and then display them.
I've managed to make the set and get process work as I wanted (kinda), but now I'd like to add a duplicate check before saving any record, and I'm quite stuck trying to find a nice and clean solution.
That's what I came up for now:
var storage = chrome.storage.sync;
function saveRecord(record) {
var duplicate = false;
var recordName = record.name;
storage.get('records', function(data) {
var records = data.records;
console.log('im here');
for (var i = 0; i < records.length; i++) {
var Record = records[i];
if (Record.name === recordName) {
duplicate = true;
break;
} else {
console.log(record);
}
}
if (duplicate) {
console.log('this record is already there!');
} else {
arrayWithRecords.push(record);
storage.set({ bands: arrayWithRecords }, function() {
console.log('saved ' + record.name);
});
}
});
}
I'm basically iterating on the array containing the records and checking if the name property already exists. The problem is it breaks basic set and get functionality -- in fact, when saving it correctly logs 'im here' and the relative record object, but it doesn't set the value. Plus, after a while (generally after trying to list the bands with a basic storage.get function) it returns this error:
Error in response to storage.get: TypeError: Cannot read property
'name' of null
I'm guessing this is due to the async nature of the set and get and my incompetence working with it, but I can't get my head around it in order to find a better alternative. Ideas?
Thanks in advance.

Categories