Skip to content
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