Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an example how to attach persistent metadata to button events #75

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions clientlib/nodejs/persistent-metadata-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Persistent button metadata example

This is an example how to attach persistent metadata to button events.

## How it works

On start the program fetches a lists of verified Flic buttons and adds a record for each button to a `buttons.json` file. The record can store any number of properties and metadata.

When a button is clicked the metadata for that button is attached to the registered callback function.

## Quick start

1. Start the `flicd` deamon.
1. Run `node index.js`
1. Edit the created `buttons.json` file and add some metadata.
```
{
"80:e4:da:11:11:1d": {
"name": "Button One"
},
"80:e4:da:22:22:2d": {
"name": "Button Two"
}
}
```
1. Restart `node index.js`
73 changes: 73 additions & 0 deletions clientlib/nodejs/persistent-metadata-example/flic.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const flicLib = require('../fliclibNodeJs')
const JSONStore = require('./jsonStore')

const Flic = (opt) => {
const options = Object.assign({
dbFile: 'buttons.json',
defaultButtonProps: {
name: "UNNAMED"
}
}, opt)

const state = {
buttons: {},
eventListeners: {}
}

const client = new flicLib.FlicClient('localhost', 5551)

const db = JSONStore(options.dbFile)

const mergeButtons = (defaultButtonProps) => (buttons, buttonId) => {
buttons[buttonId] = Object.assign({}, defaultButtonProps, buttons[buttonId])
return buttons
}

const getNewAndOldButtons = (buttonIds, defaultButtonProps) => (storedButtons) => {
return buttonIds.reduce(mergeButtons(defaultButtonProps), storedButtons)
}

const updateState = (key) => (value) => {
state[key] = value
return value
}

const addEventListener = (buttonId) => {
const cc = new flicLib.FlicConnectionChannel(buttonId)
client.addConnectionChannel(cc)
cc.on('buttonSingleOrDoubleClickOrHold', (clickType, wasQueued, timeDiff) => {
if (state.eventListeners[clickType]) {
state.eventListeners[clickType].forEach((callback) => {
callback(clickType, wasQueued, timeDiff, state.buttons[buttonId])
})
}
})
}

const addEventListenerToButtons = () => {
Object.keys(state.buttons).forEach(addEventListener)
}

client.once('ready', () => {
client.getInfo(info => {
db.get()
.then(getNewAndOldButtons(info.bdAddrOfVerifiedButtons, options.defaultButtonProps))
.then(updateState('buttons'))
.then(db.save)
.then(addEventListenerToButtons)
})
})

const on = (type, callback) => {
if (!state.eventListeners[type]) {
state.eventListeners[type] = []
}
state.eventListeners[type].push(callback)
}

return {
on
}
}

module.exports = Flic
18 changes: 18 additions & 0 deletions clientlib/nodejs/persistent-metadata-example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const flicConnector = require('./flic')

const flic = flicConnector({
defaultButtonProps: {
name: "UNNAMED"
}
})

flic.on('ButtonSingleClick', (type, wasQueued, timeDiff, metadata) => {
console.log('Click detected on button with metadata', metadata)
})

flic.on('ButtonHold', (type, wasQueued, timediff, metadata) => {
console.log('Hold detected on button with metadata', metadata)
})

console.log('Listening for single click and button hold')

31 changes: 31 additions & 0 deletions clientlib/nodejs/persistent-metadata-example/jsonStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const fs = require('fs')

const JSONStore = (filename) => {
const get = () => new Promise((resolve, reject) => {
try {
resolve(JSON.parse(fs.readFileSync(filename), 'utf8'))
} catch (e) {
if (e.code === 'ENOENT') {
resolve({})
} else {
reject(e)
}
}
})

const save = (data) => new Promise((resolve, reject) => {
try {
fs.writeFileSync(filename, JSON.stringify(data, null, 4), 'utf8')
resolve()
} catch (e) {
reject(e)
}
})

return {
get,
save
}
}

module.exports = JSONStore