@Emil Sorry. Didn't write that it's when I'm in my car on my way home.😉
-
I’m working with a Flic 2 button and a Raspberry Pi Zero 2 W, using the fliclib-linux-hci Git SDK.
I successfully built my own Debian package from the SDK and installed it on the Pi:
Package:
flicd_1.0-1_arm64.debThe daemon installs and runs correctly. Below is the systemd service I’m using:
cat /etc/systemd/system/flicd.service
[Unit]
Description=Flic Button Daemon
After=bluetooth.target
Requires=bluetooth.target[Service]
Type=simple
ExecStart=/usr/bin/flicd -f /var/lib/flicd/flic.sqlite3
Restart=always
RestartSec=3
User=root[Install]
WantedBy=multi-user.targetPairing and button events work fine, so communication with the button is confirmed.
Issue
I’m trying to read RSSI (signal strength) from the Flic 2 button, or otherwise estimate distance between the Pi and the button.
I’ve tried multiple code variants (both modifying the SDK and external BLE approaches), but I’m unable to retrieve:
RSSI values
Any distance-related data
It seems like RSSI is either not exposed through the SDK, or not available during normal operation.
Questions
Is RSSI data available at all from Flic 2 via fliclib-linux-hci?
If not, is there an alternative supported way to estimate proximity or distance?
Does the Flic firmware intentionally block RSSI access for power or privacy reasons?
Has anyone successfully retrieved RSSI from a Flic 2 on Linux/Raspberry Pi?
Any guidance, confirmation, or examples would be greatly appreciated.
Thanks in advance! -
Hello,
I have purchased several Flic hubs, Buttons, Twists and trying to get them integrated into Home Assistant.
When the sales pitch originally went out for the Flic Twist .. there was a carrot dangled that Home Assistant support may be considered .. since then .. nothing ..
Can we please, please, please get any clarity if your are even close, or considering any updates on a native Flic integration for Home Assistant to support your Buttons and Twist?
-
I had my Matter Bridge commissioned to my Flic hub and all working great,
Accidentally I managed to decommision the bridge from the flic fabric via the iOS Matter settings but it didn't remove from the flic app.
Now I'm in a state where the flic app thinks there is a bridge (and all its associated devices) there but it shows as offline and I can't remove it.
I managed to recommision the Bridge back to flic but now I have a duplicate set of 22 device in my list!
Is there a way I can remove the old bridge from the Flic Hub?
24f86297-d670-4628-8f9d-09b3bef31c63-Screen Shot 2026-01-06 at 8.59.22 AM.png
-
What is it?
Hub TCP server for using the IR module via HTTP.
Both to record of new signals with a given name and to play them back.
Using net since SDK doesn't have the nodejs HTTP-module available.Why?
I really wanted to be able to call my IR module from my phone homescreen or Google Home (via IFTTT). I got it working so I wanted to share it if anyone else find it helpful 🙂The code is what could be called a POC, so code feedback and/or changes are totally welcome.
How does it work?
Record a signal GET {ip}:1338?record={name_of_signal} Plays a signal GET {ip}:1338?cmd={name_of_signal} Cancel recording GET {ip}:1338?cancelRecord=trueExample;
call GET 192.168.0.100:1338?record=volume_up Press Volume Up on remote towards IR module returns 200 OK Signal volume_up stored! call GET 192.168.0.100:1338?cmd=volume_up returns 200 OK Signal sent! Volume goes up 🙂The code
module.json
{ "name": "IRTCP", "version": "1.0.0" }main.js
// main.js const net = require("net"); const ir = require("ir"); const datastore = require("datastore"); const utils = require("./utils"); const respondToClient = function(c, statusCode, message) { c.write( "HTTP/1.1 " + statusCode + "\r\n" + "\r\n" ); c.write(message); c.end(); } const handleCmd = function(c, cmd) { datastore.get(cmd, function(err, strBuffer) { if (!err && strBuffer) { var signal = new Uint32Array(utils.str2ab(strBuffer)); if (!ArrayBuffer.isView(signal)) { return respondToClient(c, "422 Unprocessable Entity", "Unknown signal"); } ir.play(signal, function(err) { if (!err) { return respondToClient(c, "200 OK", "Signal sent"); } return respondToClient(c, "500 Internal Server Error", "Couldn't send signal"); }); } else { return respondToClient(c, "422 Unprocessable Entity", "Unknown cmd"); } }); } const handleRecord = function(c, name) { /* TODO: add a timeout for listening for complete */ ir.record(); console.log("recording signal..."); ir.on("recordComplete", function(signal) { datastore.put(name, utils.ab2str(signal.buffer), function(err) { if (!err) { console.log("Signal " + name + " stored!"); return respondToClient(c, "200 OK", "Signal " + name + " stored!"); } else { return respondToClient(c, "500 Internal Server Error", "Couldn't store signal"); } }); }); } var server = net.createServer(function(c) { console.log('server connected'); c.on('end', function() { console.log('server disconnected'); }); c.on('data', function(data) { console.log(data); var match = data.toString().match(/GET \/\?.[^ ]*/); if (!match) { return respondToClient(c, "403 Forbidden", "Forbidden method"); } var params = utils.parseParams(match[0].split("GET /?")[1]); if (params.cmd) { return handleCmd(c, params.cmd); } else if (params.record && params.record.length > 0) { return handleRecord(c, params.record); } else if (params.cancelRecord) { ir.cancelRecord(); console.log("recording canceled!"); return respondToClient(c, "200 OK", "Recording canceled!"); } else { return respondToClient(c, "403 Forbidden", "Forbidden params"); } }); }); server.listen(1338, "0.0.0.0", function() { console.log('server bound', server.address().port); });utils.js
const ab2str = function(buf) { return String.fromCharCode.apply(null, new Uint16Array(buf)); } const str2ab = function(str) { var buf = new ArrayBuffer(str.length*2); var bufView = new Uint16Array(buf); for (var i=0, strLen=str.length; i < strLen; i++) { bufView[i] = str.charCodeAt(i); } return buf; } const parseParams = function (s) { var obj = {}; var arr = s.split("&"); var temp; for (i = 0; i < arr.length; i++) { temp = arr[i].split("="); obj[temp[0]] = temp[1]; } return obj; }; exports.ab2str = ab2str; exports.str2ab = str2ab; exports.parseParams = parseParams;