Skip to content

Commit

Permalink
Merge pull request #3 from kantimam/deploy
Browse files Browse the repository at this point in the history
fixed syncing bug and major devicecontroller refactoring
  • Loading branch information
kimamov committed Jan 18, 2021
2 parents 33638f3 + 3a21dee commit 2f81e16
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 48 deletions.
2 changes: 1 addition & 1 deletion client/.eslintcache

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/src/components/reader/ReaderShow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const ShowPropsExtractor=({children, ...props})=>{

const onSuccess = () => {
notify(`successfully added key to reader`)
refresh();
//refresh();
};

return (
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/reader/ReaderShowActions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const ReaderShowActions = ({ basePath, data, resource }) => {
const json=await response.json();
dispatch(fetchEnd());
notify(json.message? json.message :`reader ${data.id} deleted all keys. Reader keys will be refreshed shortly`, "info")
setTimeout(refresh, 1000);
setTimeout(refresh, 4000);
} catch (error) {
dispatch(fetchEnd());
console.log(error)
Expand All @@ -58,7 +58,7 @@ const ReaderShowActions = ({ basePath, data, resource }) => {
dispatch(fetchEnd());
//notify(json.message? json.message :`reader ${data.id} synced all keys`, "info")
notify(`reader ${data.id} synced all keys`, "info");
setTimeout(refresh, 800);
setTimeout(refresh, 6000);
} catch (error) {
dispatch(fetchEnd());
console.log(error)
Expand Down
119 changes: 83 additions & 36 deletions src/controllers/deviceController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ export async function deleteAllKeys(req: Request, res: Response){


export async function syncAllKeys(req: Request, res: Response){
// first delete all key off the reader
// tells the device to delete all its users/keys waits for it to finish then sends keys from our db one by one
const {id}=req.params;
const readerResult = await getRepository(Reader).findOne(id, {relations: ["readerKeys", "readerKeys.key"]})

Expand All @@ -321,47 +321,94 @@ export async function syncAllKeys(req: Request, res: Response){
if(!client.connected){
return res.status(500).send({error: "connection to the MQTT client was lost"})
}

let deviceDeletingUsers=true;
let addedUserCount=0;

if(!readerResult.readerKeys || !readerResult.readerKeys.length){
return res.status(404).send({message: `looks like the reader does not have any keys related to it in the database`})
}

const sendUserToDevice=(readerKey)=>{
if(client.connected && readerKey.key){
client.publish('devnfc', JSON.stringify({
cmd: "adduser",
doorip: readerResult.ip,
uid: readerKey.key.uid,
user: readerKey.key.name,
acctype: readerKey.acctype,
acctype2: readerKey.acctype2,
acctype3: readerKey.acctype3,
acctype4: readerKey.acctype4,
acctype5: readerKey.acctype5,
acctype6: readerKey.acctype6,
validuntil: dateToUnix(readerKey.key.validUntil)
}))
}

}

const sendResponse=()=>{
// remove the handler
client.off("message", mqttMessageHandler);
// send response to the client and return
return res.send({message: `started syncing ${addedUserCount} to the device ${readerResult.readerName}`})
}

let mqttTimeout;
const mqttMaxResponseTime: number=4000; // give the device max 4 seconds between messages and otherwise return


const mqttMessageHandler=(topic: string, message: Buffer)=> {
if(topic==="devnfc/devicestate" || topic==="/devnfc/devicestate"){
const messageString = message.toString()
const messageJSON = JSON.parse(messageString)
if(messageJSON.deviceName===readerResult.readerName){ // make sure message comes from the same controller
if(deviceDeletingUsers){
if(messageJSON.cmd==="deleteAllUsersState"){
// once deleting is done we can send the first user
deviceDeletingUsers=false;
const readerKey=readerResult.readerKeys[0]
sendUserToDevice(readerKey);
console.log("finished deleting users")
}
}else if(messageJSON.cmd==="dbUserAdded"){
// first dbUserAdded message means our first user was added so increment the counter
addedUserCount++;
if(readerResult.readerKeys.length === addedUserCount){
// once length is the same we are successfully done
console.log("finished syncing keys");
return sendResponse();
}else {
console.log("sending next user");
const readerKey=readerResult.readerKeys[addedUserCount]
sendUserToDevice(readerKey);
}

}
console.log(messageJSON);
// everytime we receive a valid message from the device we reset the timer
clearTimeout(mqttTimeout);
mqttTimeout=setTimeout(sendResponse, mqttMaxResponseTime);
}

}
}

// start listening for delete user and create user state updates from the device
client.on("message", mqttMessageHandler)

// tell the device to start deleting all the users
client.publish('devnfc', JSON.stringify({
cmd: "deletusers",
doorip: readerResult.ip,
doorname: readerResult.readerName
}))
/* create listener that waits for delete done identify the reader by name and send code */
}));

const deleteWaitTime=readerConfig.deleteTime; // lets give the reader some time to delete all the keys
await wait(deleteWaitTime);


if(readerResult.readerKeys && readerResult.readerKeys.length){
const delay=readerConfig.syncTime;
const keyCount=readerResult.readerKeys.length;
const totalTime=delay*keyCount;
//readerResult.keys.forEach()
for(let readerKey of readerResult.readerKeys){
if(client.connected && readerKey.key){
// if we are connected we send each key to the reader with delay of 0.3s
await wait(delay);
client.publish('devnfc', JSON.stringify({
cmd: "adduser",
doorip: readerResult.ip,
uid: readerKey.key.uid,
user: readerKey.key.name,
acctype: readerKey.acctype,
acctype2: readerKey.acctype2,
acctype3: readerKey.acctype3,
acctype4: readerKey.acctype4,
acctype5: readerKey.acctype5,
acctype6: readerKey.acctype6,
validuntil: dateToUnix(readerKey.key.validUntil)
}))
}
}
const timeInSeconds=(totalTime+deleteWaitTime) / 1000;
return res.send({message: `started syncing ${keyCount} keys to the reader it should be done in ${timeInSeconds} seconds`, time: timeInSeconds})
// after starting our event chain by publishing deleteuser
// we give the device 4 seconds to return a message and otherwise return early
mqttTimeout=setTimeout(sendResponse, mqttMaxResponseTime)

}else {
return res.status(404).send({message: `looks like the reader does not have any keys related to it in the database`})
}


}
8 changes: 4 additions & 4 deletions src/mqtt/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ export const setupMqtt = () => {

client.on("error", (err) => console.log(err))
client.on('connect', function () {
// devnfc/devicestate
client.subscribe('devnfc/#', function (err) {

})
client.subscribe('devnfc', function (err) {
if (!err) {
if(err){
console.log("mqtt could not subscribe to devnfc/#");
throw err;
}
})
})
Expand Down
8 changes: 4 additions & 4 deletions src/mqtt/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@ export default function messageHandler(topic: string, message: Buffer) {
//handleDoorKeyList(messageJSON);
handleAccessAndEvent(messageJSON);
break;
case "devnfc/accesslist":
/* case "/devnfc/accesslist":
/* case "devnfc/accesslist":
case "/devnfc/accesslist":
handleDoorKeyList(messageJSON);
break; */
case "devnfc/#":
/* case "devnfc/#":
case "/devnfc/#":
console.log("messageJSON")
console.log("messageJSON") */
default:
console.warn("there is no handler for this topic either create one or consider unsubscribing from it");
break;
Expand Down

0 comments on commit 2f81e16

Please sign in to comment.