Closed mriksman closed 4 years ago
I do not know where this screenshot comes from, but it does not look like Home.app, so I really do not know what it can do. But overall it sounds like a weird combination for the HomeKit.
It’s the native Apple Home app.
It IS a weird combination hahah. But I’m open to suggestions for how else to provide a way to list/cycle through a bunch of animations for the WS2812 addressable LED strips.
You need a custom iOS app that will a) use HomeKit APIs; b) understand your custom characteristics and provide UI for them. You can try some existing apps (e.g. "Eve for HomeKit"), they might be able to provide at least some UI (whereas stock Home.app do not display services it does not know).
In my homebridge led strip plugin I created a bunch of buttons, each being a different strip animation. Was a bit cumbersome in the Home app, but allowed access to different strip animations, and for Xmas allowed for turning on selected animation via home app automations.
Sent from my iPad
On Jan 13, 2020, at 1:14 AM, Maxim Kulkin notifications@github.com wrote:
You need a custom iOS app that will a) use HomeKit APIs; b) understand your custom characteristics and provide UI for them. You can try some existing apps (e.g. "Eve for HomeKit"), they might be able to provide at least some UI (whereas stock Home.app do not display services it does not know).
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.
I set LIGHTBULB to .primary=true and removed TELEVISION's .primary=true. I got exactly what I wanted!
Can you share a pointer to your code. I am interested the pice where you got it to display the animations as a selectable list .
It's really all thanks to the example code from @maximkulkin and his esp-it-tv
code.
I am having issues with naming the LIGHTBULB and TELEVISION though. It doesn't stick. Not sure what the issue is... Keeps reverting back to the values originally configured here HOMEKIT_CHARACTERISTIC(NAME,
for both the LIGHTBULB and TELEVISION.
void on_input_configured_name(homekit_characteristic_t *ch, homekit_value_t value, void *arg);
void on_configured_name(homekit_characteristic_t *ch, homekit_value_t value, void *arg) {
// sysparam_set_string("tv_name", value.string_value);
printf("sysparam_set_string('tv_name', %s)", value.string_value);
}
void on_active(homekit_characteristic_t *ch, homekit_value_t value, void *arg) {
// ir_tv_send(ir_tv_power);
printf("Animation activated? %d\n", value.int_value);
}
void on_active_identifier(homekit_characteristic_t *ch, homekit_value_t value, void *arg) {
switch (value.int_value) {
case 1:
// ir_hdmi_switch_send(ir_hdmi_switch_input_1);
printf("Animation 1 Selected\n");
break;
case 2:
// ir_hdmi_switch_send(ir_hdmi_switch_input_2);
printf("Animation 2 Selected\n");
break;
case 3:
// ir_hdmi_switch_send(ir_hdmi_switch_input_3);
printf("Animation 3 Selected\n");
break;
default:
printf("Unknown active identifier: %d", value.int_value);
}
}
homekit_characteristic_t input_source1_name = HOMEKIT_CHARACTERISTIC_(
CONFIGURED_NAME, "Animation 1",
.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_input_configured_name)
);
homekit_service_t input_source1 =
HOMEKIT_SERVICE_(INPUT_SOURCE, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "anim1"),
HOMEKIT_CHARACTERISTIC(IDENTIFIER, 1),
&input_source1_name,
HOMEKIT_CHARACTERISTIC(INPUT_SOURCE_TYPE, HOMEKIT_INPUT_SOURCE_TYPE_HDMI),
HOMEKIT_CHARACTERISTIC(IS_CONFIGURED, true),
HOMEKIT_CHARACTERISTIC(CURRENT_VISIBILITY_STATE, HOMEKIT_CURRENT_VISIBILITY_STATE_SHOWN),
NULL
});
homekit_characteristic_t input_source2_name = HOMEKIT_CHARACTERISTIC_(
CONFIGURED_NAME, "Animation 2",
.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_input_configured_name)
);
homekit_service_t input_source2 =
HOMEKIT_SERVICE_(INPUT_SOURCE, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "anim2"),
HOMEKIT_CHARACTERISTIC(IDENTIFIER, 2),
&input_source2_name,
HOMEKIT_CHARACTERISTIC(INPUT_SOURCE_TYPE, HOMEKIT_INPUT_SOURCE_TYPE_HDMI),
HOMEKIT_CHARACTERISTIC(IS_CONFIGURED, true),
HOMEKIT_CHARACTERISTIC(CURRENT_VISIBILITY_STATE, HOMEKIT_CURRENT_VISIBILITY_STATE_SHOWN),
NULL
});
homekit_characteristic_t input_source3_name = HOMEKIT_CHARACTERISTIC_(
CONFIGURED_NAME, "Animation 3",
.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_input_configured_name)
);
homekit_service_t input_source3 =
HOMEKIT_SERVICE_(INPUT_SOURCE, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "anim3"),
HOMEKIT_CHARACTERISTIC(IDENTIFIER, 3),
&input_source3_name,
HOMEKIT_CHARACTERISTIC(INPUT_SOURCE_TYPE, HOMEKIT_INPUT_SOURCE_TYPE_HDMI),
HOMEKIT_CHARACTERISTIC(IS_CONFIGURED, true),
HOMEKIT_CHARACTERISTIC(CURRENT_VISIBILITY_STATE, HOMEKIT_CURRENT_VISIBILITY_STATE_SHOWN),
NULL
});
homekit_characteristic_t tv_name = HOMEKIT_CHARACTERISTIC_(
CONFIGURED_NAME, "My TV",
.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_configured_name)
);
homekit_accessory_t *accessories[] = {
HOMEKIT_ACCESSORY(.id=1, .category=homekit_accessory_category_television, .services=(homekit_service_t*[]){
HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "TV"),
HOMEKIT_CHARACTERISTIC(MANUFACTURER, "HaPK"),
HOMEKIT_CHARACTERISTIC(SERIAL_NUMBER, "1"),
HOMEKIT_CHARACTERISTIC(MODEL, "ESP8266-1"),
HOMEKIT_CHARACTERISTIC(FIRMWARE_REVISION, "0.1"),
HOMEKIT_CHARACTERISTIC(IDENTIFY, led_identify),
NULL
}),
// HOMEKIT_SERVICE(TELEVISION, .primary=true, .characteristics=(homekit_characteristic_t*[]) {
HOMEKIT_SERVICE(TELEVISION, .characteristics=(homekit_characteristic_t*[]) {
HOMEKIT_CHARACTERISTIC(NAME, "Television"),
HOMEKIT_CHARACTERISTIC(
ACTIVE, true,
.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_active)
),
HOMEKIT_CHARACTERISTIC(
ACTIVE_IDENTIFIER, 1,
.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_active_identifier)
),
&tv_name,
HOMEKIT_CHARACTERISTIC(
SLEEP_DISCOVERY_MODE,
HOMEKIT_SLEEP_DISCOVERY_MODE_ALWAYS_DISCOVERABLE
),
NULL
}, .linked=(homekit_service_t*[]) {
&input_source1,
&input_source2,
&input_source3,
NULL
}),
&input_source1,
&input_source2,
&input_source3,
HOMEKIT_SERVICE(LIGHTBULB, .primary=true, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "Sample LED"),
HOMEKIT_CHARACTERISTIC(
ON, false,
.getter=led_on_get,
.setter=led_on_set
),
HOMEKIT_CHARACTERISTIC(
BRIGHTNESS, 100,
.getter = led_brightness_get,
.setter = led_brightness_set
),
HOMEKIT_CHARACTERISTIC(
HUE, 0,
.getter = led_hue_get,
.setter = led_hue_set
),
HOMEKIT_CHARACTERISTIC(
SATURATION, 0,
.getter = led_saturation_get,
.setter = led_saturation_set
),
NULL
}),
NULL
}),
NULL
};
void on_input_configured_name(homekit_characteristic_t *ch, homekit_value_t value, void *arg) {
const char *input_param_name = NULL;
if (ch == &input_source1_name) {
input_param_name = "input1_name";
} else if (ch == &input_source2_name) {
input_param_name = "input2_name";
} else if (ch == &input_source3_name) {
input_param_name = "input3_name";
}
if (!input_param_name)
return;
// sysparam_set_string(input_param_name, value.string_value);
printf("sysparam_set_string(%s, %s)", input_param_name, value.string_value);
}
For anyone who sees this. Do NOT use the CHARACTERISTIC 'NAME' for Television (remove this line; HOMEKIT_CHARACTERISTIC(NAME, "Television"),
).
Seems the original services use NAME, and they are persistent between restarts of the device (where is this data stored!? Local to the iPhone? What happens when you 'invite' someone to your 'Home'?).
TelevisionService uses CONFIGUREDNAME and must be saved to the devices memory and restored upon restart (much like the Input names).
@mriksman NAME characteristics are read-only, while required CONFIGUREDNAME characteristic should be writable (that's why it's a separate characteristic). Accessory is supposed to persist CONFIGUREDNAME values across reboots.
Looking at your esp-ir-tv code, you appear to save the CONFIGURED_NAME
for the tv_name
just like you save it for the input_source#
names. Which lines up with what I am seeing.
I found that
HOMEKIT_SERVICE(ACCESSORY_INFORMATION, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "UseMACAddr"),
This name only appeared when first connecting to the device. Then, once paired, you'll see it for about 5 seconds on the tile on the Home app, before it gets replaced by the name of the service configured as Primary. I had this as my Primary service;
HOMEKIT_SERVICE(LIGHTBULB, .primary=true, .characteristics=(homekit_characteristic_t*[]){
HOMEKIT_CHARACTERISTIC(NAME, "LightbulbName"),
So my Accessory (with a Lightbulb and Television service) was now collectively named LightbulbName, the Lightbulb Service was named LightbulbName, and the Television Service was named according to this;
homekit_characteristic_t tv_name = HOMEKIT_CHARACTERISTIC_(
CONFIGURED_NAME, "My TV",
.callback=HOMEKIT_CHARACTERISTIC_CALLBACK(on_configured_name)
);
When I changed the Accessory Name OR the Lightbulb Service name - it persisted between reboots. When I changed Television name - it did not. I had to save and restore the name - just like you did in your code.
I found the Characteristic NAME to have no impact on the Television service;
HOMEKIT_SERVICE(TELEVISION, .characteristics=(homekit_characteristic_t*[]) {
HOMEKIT_CHARACTERISTIC(NAME, "TelevisionName"),
It simply didn't appear anywhere.
This is just my observation. I'd be curious to see what other people see.
Hey,
Any idea if it’s possible to link an InputSource to a Lightbulb?
I want to create an accessory for an Addressable LED Strip that has a list of animations programmed. It’d be cool if you had on the UI just the dimmer/light/colour, and then underneath, an InputSource list where you could list all your Animation names.
I created a single Accessory with Television, linked InputSource and Lightbulb. But I really don’t want the power button that comes with the Television service. Can InputSource be used by itself with Lightbulb?