Flic hub intergration

Thanks @PanicRide, yes - I have the config.js line as:
exports.SERVER_HOST = 'http://192.168.86.114:8123';

For reference, the complete console output is:

Request: {"method":"POST","url":"http://192.168.86.114:8123/api/states/binary_sensor.flic_80e4da787142_connectivity","content":"{\"state\":\"on\",\"attributes\":{\"device_class\":\"connectivity\",\"icon\":\"mdi:bluetooth\",\"friendly_name\":\"One Connectivity\"}}","headers":{"Authorization":"Bearer [TOKEN]","Content-Type":"application/json"}}

Error: "connect timed out"

Where [TOKEN] is my Long-Lived Access Token string.

Does anything in there help to troubleshoot?

Hi @MaesterDaemon, from console output the URL seems fine. I never really tested what happens if the API integration is not properly enabled as mine was enabled by default. But you can test it by executing the following cURL from a terminal:

curl --location --request GET 'http://192.168.86.114:8123/api/' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer [TOKEN]'

If everything is working fine you should get the next response: {"message": "API running."}

In case the API integration is working, I can only assume there is some network issue. Also, the API integration depends on the HTTP integration, some http configurations can affect as well.

1 Like

Thanks for the tip! The cURL worked - which helped me to narrow it down to a network issue. Turned out to be a problem with my firewall settings.

Flic Hub integration is now up and running - it’s awesome, thanks for all your work on it!

Hi @blunan I just got the flic hub lr and have tried to followed your module but when i copy the main.js i got this error: Any idea how can i solve it please? Thanks a lot in advance!!!
\
TypeError: undefined not callable (property ‘initButtonEventTimestamp’ of [object Object])
at [anon] (duktape.c:65024) internal
at initButton (root/HA module/main.js:18)
at initButtons (root/HA module/main.js:13)
at [anon] (root/HA module/main.js:7)
at require (init.js:131)
at [anon] (init.js:139) preventsyield
at runInit () native strict preventsyield
at handlePacket (pipe_communication.js:48)
at readCallback (pipe_communication.js:93) preventsyield
\\

Hi @aramanrique , it looks like utils.js file is missing in your module, that is why initButtonEventTimestamp is marked as undefined.

Make sure to copy all the files not just main.js and edit config.js with your SERVER_HOST and SERVER_AUTH_TOKEN values.

I had something similar happen to me. It’s not obvious in the file editor they give you, but after copying in the contents of each file, you need to press [CTRL][S] to save it.

Brilliant work @blunan

Took me a while but eventually got there.

Many thanks

Thanks so much for providing these details @PanicRide. It’s ultimately what I went with for its simplicity. It didn’t work for me exactly as you described–probably something changed int he last year–but in case it’s helpful to others, on the Flic “Internet Request” screen, you now need to provide a value for “Content Type” (“application/json” WITH quotes) and while a value for “Body” isn’t required by the app, if it’s not included, I got an error on the HA side. The solution I found is to just include “{}” (WITHOUT quotes).

Are you saying the flic app is requiring you to specify a content type now? I just checked and that’s not the case for me in the android app. 🤷

Interesting. I’m on iOS app version 5.2.0 and it’s required :man_shrugging:

If you use MQTT and have Auto discovery enabled, you can run this on the Flic Hub to have it automatically created flic buttons in Home assistant.

var server = ""

var options = {
	client_id : "flic_hub",
	keep_alive: 60,
	port: 1883,
	clean_session: true,
	username: "",
	password: "",
	protocol_name: "MQTT",
	protocol_level: 4
}

var mqtt = require("./mqtt.js").create(server, options)
var buttonManager = require("buttons")
var buttons = buttonManager.getButtons()
var actions = {
	button_short_press: "click", 
	button_double_press: "double_click",
	button_long_press: "hold"
}	

var buttonsAddedToHa = false


buttonManager.on("buttonSingleOrDoubleClickOrHold", function(obj) {
	console.log("Event called buttonSingleOrDoubleClickOrHold")
	var button = buttonManager.getButton(obj.bdaddr)
	var clickType = obj.isSingleClick ? actions.button_short_press : obj.isDoubleClick ? actions.button_double_press : actions.button_long_press
	mqtt.publish("flic/"+ button.uuid +"/action", clickType)
})

buttonManager.on("buttonAdded", function(obj) {
	console.log("Event called buttonAdded")
	configureButtons()
})

buttonManager.on("buttonUpdated", function(obj) {
	console.log("Event called buttonUpdated")
	refreshButtonhState(obj)
})

buttonManager.on("buttonConnected", function(obj) {
	console.log("Event called buttonConnected")
	refreshButtonhState(buttonManager.getButton(obj.bdaddr))
})

buttonManager.on("buttonReady", function(obj) {
	console.log("Event called buttonReady")
	refreshButtonhState(buttonManager.getButton(obj.bdaddr))
})

buttonManager.on("buttonDisconnected", function(obj) {
	console.log("Event called buttonDisconnected")
	refreshButtonhState(buttonManager.getButton(obj.bdaddr))
})

mqtt.on('connected', function(){
	console.log("MQTT Connected")
	if(buttonsAddedToHa === false){
		configureButtons()
	}

})

mqtt.on('publish', function(pub){
    console.log("Received a message with: ")
    console.log("topic: "+pub.topic)
    console.log("message: "+pub.message)
});

mqtt.on('disconnected', function() {
	console.log("MQTT Disconnected")
	mqtt.connect()
});

mqtt.on('error', function(err) {
	console.log("MQTT Error: " + err)
  setTimeout(function (){
    mqtt.connect();
  }, 5000);
});

function configureButtons(){
	for (var i = 0; i < buttons.length; i++) {
		var button = buttons[i];
		var deviceConfig = {
			identifiers: [
				button.uuid
			],
			name: (button.name === null)? button.serialNumber : button.name.toString(),
			sw_version: button.firmwareVersion.toString(),
			hw_version: button.flicVersion.toString(),
			model: "Flic " + button.flicVersion.toString(),
			manufacturer: "Flic"
		}
		var deviceAutomationConfig = {
			automation_type: "trigger",
			type: "",
			subtype: "button_1",
			payload: "",
			topic: "",
			unique_id: "",
			device: deviceConfig
		}

		console.log("Creating HA device: "+ deviceConfig.name)
		Object.keys(actions).forEach(function(ha) {
			var flic = actions[ha]
			deviceAutomationConfig.type = ha
			deviceAutomationConfig.payload = flic
			deviceAutomationConfig.topic = "flic/"+ button.uuid +"/action"
			deviceAutomationConfig.unique_id = button.uuid +"_"+ flic

			mqtt.publish("homeassistant/device_automation/flic/"+ deviceAutomationConfig.device.name +"_"+ flic +"/config", JSON.stringify(deviceAutomationConfig), {retain: true})
		})
		
		var batteryConfig = {
			name: deviceConfig.name + "_battery_charge_level",
			device_class: "battery",
			state_topic: "flic/"+ button.uuid +"/battery_charge_level/state",
			availability: [
				{
					topic: "flic/"+ button.uuid +"/battery_charge_level/status"
				},
				{
					topic: "flic/"+ button.uuid +"/status"
				}
			],
			availability_mode: "all",
			unit_of_measurement: "%",
			value_template: "{{ value | int }}",
			unique_id: button.uuid +"_battery_charge_level",
			device: deviceConfig
		}
		mqtt.publish("homeassistant/sensor/"+ button.uuid +"/battery_charge_level/config", JSON.stringify(batteryConfig), {retain: true})
		
		var connectedConfig = {
			name: deviceConfig.name + "_connected",
			device_class: "connectivity",
			state_topic: "flic/"+ button.uuid +"/connected/state",
			availability_topic:  "flic/"+ button.uuid +"/status",
			value_template: "{{ value }}",
			unique_id: button.uuid +"_connected",
			device: deviceConfig
		}
		mqtt.publish("homeassistant/binary_sensor/"+ button.uuid +"/connected/config", JSON.stringify(connectedConfig), {retain: true})
				
		var readyConfig = {
			name: deviceConfig.name + "_ready",
			state_topic: "flic/"+ button.uuid +"/ready/state",
			availability_topic:  "flic/"+ button.uuid +"/status",
			value_template: "{{ value }}",
			unique_id: button.uuid +"_ready",
			device: deviceConfig
		}
		mqtt.publish("homeassistant/binary_sensor/"+ button.uuid +"/ready/config", JSON.stringify(readyConfig), {retain: true})

		var activeDisconnectConfig = {
			name: deviceConfig.name + "_active_disconnect",
			state_topic: "flic/"+ button.uuid +"/active_disconnect/state",
			availability_topic:  "flic/"+ button.uuid +"/status",
			value_template: "{{ value }}",
			unique_id: button.uuid +"_active_disconnect",
			device: deviceConfig
		}
		mqtt.publish("homeassistant/binary_sensor/"+ button.uuid +"/active_disconnect/config", JSON.stringify(activeDisconnectConfig), {retain: true})
		
		setTimeout(function(){ refreshButtonhState(button) }, 5 * 1000)
		
	}
	buttonsAddedToHa = true
}

function refreshButtonhState(button){
	console.log("Refresh Button State: "+ JSON.stringify(button))
	
	var availability = (button.ready)? "online" : "offline"
	mqtt.publish("flic/"+ button.uuid +"/status", availability)
	if(button.batteryStatus == null){
		mqtt.publish("flic/"+ button.uuid +"/battery_charge_level/status", "offline")
	} else {
		mqtt.publish("flic/"+ button.uuid +"/battery_charge_level/status", "online")
		mqtt.publish("flic/"+ button.uuid +"/battery_charge_level/state", JSON.stringify(button.batteryStatus))
	}
	mqtt.publish("flic/"+ button.uuid +"/connected/state", (button.connected)?"ON":"OFF")
	mqtt.publish("flic/"+ button.uuid +"/ready/state", (button.ready)?"ON":"OFF")
	mqtt.publish("flic/"+ button.uuid +"/active_disconnect/state", (button.activeDisconnect)?"ON":"OFF")
}

mqtt.connect()

Just add your MQTT server IP, username and password. Flic buttons should be automatically added with battery and other sensors and of course triggers for the button events.

3 Likes

For anyone else who’s looking, you can find mqtt.js for the Flic Hub here: GitHub - 50ButtonsEach/flic-hub-sdk-mqtt-js

Just before mqtt support was added I was in the finishing stages of my tcp server/client based integration for the FlicHub. It can be found here: GitHub - JohNan/home-assistant-flichub

I’ve been running this integration for some weeks now and it works pretty well for what I can tell. Let me know what you think and feel free to contribute.

In comparison to the mqtt version above my integration creates binary sensors for each button belonging to the FlicHub as device. I guess each button could be turned into a separate device with its own sensors, but that’s for the future. :smirk:

@JohNan Just installed your tcp integration. Works quite well. Cheers!

1 Like