diyhue / diyHue

Main diyHue software repo
https://diyhue.org/
Other
1.55k stars 275 forks source link

diyHue Integration with Hyperion Ambilight (WS2812B) #322

Open Araforn opened 4 years ago

Araforn commented 4 years ago

Request - Integration with Hyperion Ambilight (WS2812B) Im looking for a way to combine a DIYHue connected lightstrip (WS2812B) with an instance of the same light strip on Hyperion.

Possible Solution - Combine Sketches - Hyperion-Scilor with diyhue-WS2812B I already have Hyperion up and running using Scilors code here: https://github.com/SciLor/Hyperion_LED-Controller. It uses a NodeMCU Board (ESP8266) and works great. The Hyperion Ambilight kicks in when one of my HDMI inputs is active and then turns off when one is not. It is transferring image data over wifi UDP.

I also have DIY Hue up and running with the provided WS282b lightstrip code running on a NodeMCU Board (again ESP8266), on a separate lightstrip of course.

What I would like achieve is primarily have my connected WS2812B lightstrip as a HUE light in DIYHue but have Hyperion Ambilight kick in when one of my HDMI devices turns on.

Maybe this is not possible but maybe there is interest from others here and we could build it?. I'm looking at the code and can see where I can begin to build a new sketch but my development in Arduino is at early stages.

If anyone is interested or could tell me if this is simply not possible given the nature of the current scripts/Node MCU restrictions it would be much appreciated.

mariusmotea commented 4 years ago

Try to understand the udp protocol used by hyperion. In WS2812B we have the entertainment UDP service that accept raw RGB data. There are 4 bytes on every frame / virtual light, first (or the last i don't remember exactly) is the virtual light id, remaining 3 the virtual light RGB data. If Hyperion use something similar then is easy to accommodate. If you change this on the sketch the strip only entertainment protocol will be affected, regular usage will still work fine.

Araforn commented 4 years ago

Try to understand the udp protocol used by hyperion. In WS2812B we have the entertainment UDP service that accept raw RGB data. There are 4 bytes on every frame / virtual light, first (or the last i don't remember exactly) is the virtual light id, remaining 3 the virtual light RGB data. If Hyperion use something similar then is easy to accommodate. If you change this on the sketch the strip only entertainment protocol will be affected, regular usage will still work fine.

Thanks a lot for your reply. Much appreciated. I didn't think of adding the functionality to the entertainment protocol only. This would be very interesting.

I'll look into it today.

Araforn commented 4 years ago

Try to understand the udp protocol used by hyperion. In WS2812B we have the entertainment UDP service that accept raw RGB data. There are 4 bytes on every frame / virtual light, first (or the last i don't remember exactly) is the virtual light id, remaining 3 the virtual light RGB data. If Hyperion use something similar then is easy to accommodate. If you change this on the sketch the strip only entertainment protocol will be affected, regular usage will still work fine.

I've found the UDP protocols Hyperion uses here: https://hyperion-project.org/wiki/UDP-Device

Extract below. PROTOCOL

Simple UDP packets are sent.

Packet Format protocol 0: 3 bytes per LED as R, G, B

Packet Format protocol 2: 0: update number & 0xf; 1: fragment of this update 2: 1st led# of this update - high byte 3: 1st led# of this update - low byte 4..n 3 bytes per LED as R, G, B

Packet Format protocol 3: (simple TPM2.net implementation) 0: 0x9C 1: 0xDA 2: number of databytes (leds 3) - high byte 3: number of databytes (leds 3) - low byte 4: fragment number (1-255) 5: number of fragments (1-255) 6..n: 3 bytes per LED as R, G, B n+1: 0x36

From your knowledge is this something that I can start to build into diyHue?.

Thanks again for the help.

Hyperion - Forum
UDP Device
BACKGROUND
mariusmotea commented 4 years ago

I think you need to start with protocol 0. If i understand correctly if you have a 10 led strip there will be 3 x 10 bytes used so a total of 30 bytes. You need a loop with every 3 bytes (in the current sketch is every 4 bytes) and instead to apply the rgb data to virtual light you need to apply it directly to the led. I will try to give you an example:

  uint8_t packetSize = Udp.parsePacket();
  if (packetSize) {
    if (!entertainmentRun) {
      entertainmentRun = true;
    }
    lastEPMillis = millis();
    Udp.read(packetBuffer, packetSize);
    for (uint8_t i = 0; i < packetSize / 3; i++) {
        strip->SetPixelColor(i, RgbColor(packetBuffer[i * 3], packetBuffer[i * 3 + 1], packetBuffer[i * 3 + 2]));
    }
    strip->Show();
Araforn commented 4 years ago

Great.

Thanks a lot. I will start with this.

Just to confirm. I will replace the below highlighted code with your example above or everthing in the entertainment function?.

image

I have never used Hue Entertainment so to make "Entertainment Run = True" I run it in the app?.

Thanks for your help. Its much appreciated.

mariusmotea commented 4 years ago

Not only the highlighted code, look at the bottom where you have the strip->Show(); line.

currently the code is this:

  1. receive bytes
  2. apply to virtual lights
  3. apply virtual lights to leds

You will have only steps 1 and 3 in your formula. Also the code is much more complicated because of transition leds calculation witch in your case are not used.

Araforn commented 4 years ago

Edit -

So I have played with it this evening and have loaded the example code you provided. I have a strip with 108 LED's. With the example loaded onto the Node MCU only the first 20 light up. The ones that light up are correctly grabbing the section of the screen so the hyperion udp transmission is working but only on the first 20 LED's.

It looks like the loop is not setup to read the number of leds sent by the Hyperian UDP packet?.

Also when I turn the Hyperian Stream off and try to control the Lightstrip within the Hue App, it momentarily turns on and then off again. I'm not sure if the entertainment timeout function is doing this or the fact that the UDP packet is just not set up correctly and driving all the LEDs to off when there is no signal.

Seems so close because hyperian is working somewhat (first 20 LEDs) and the Hue app can control the lightstrip (albeit momentarily) which is the perfect scenario for me If I can just get it to work.

mariusmotea commented 4 years ago

I think you need to increase the buffer.

byte mac[6], packetBuffer[46];

increase it to packetBuffer[324]

Araforn commented 4 years ago

Thanks for the reply but this didn't work unfortunately. I'll try and analyse the packet and see what I'm missing.

ryancasler commented 4 years ago

What I have done is to set up an WemosD1 mini with DIYHue and then my Arduino for my Hyperion setup and then I have a mechanical relay which controls which of the two data lines feed into my LED strip. So, when Hyperiod is off, it is set to DIYHue and when the TV is on, the data line is set to Hyperion. The only thing that is required when you do this is that if you switch back to DIYHue and the DIYHue light was on before switching, the LEDs will not display the light settings in DIYHue until something changes. So, I have my system set so that when Hyperion turns off, if the DIYHue light is on, it dims by 1% and then brightens by 1% to get the lights to come back to the DIYHue current lights state. I'm doing this with 5 different strips, one with Hyperion and 4 with McLighting.

This ended up saving me SOOO many headaches. When I tried to wrap things together into one sketch it quickly turned out to be a lot more than I could handle. Yes, this is more expensive but not by that much. And it works! Also, upgrading the sketch later is a lot quicker. If a new DIYHue sketch comes out that I want to use, I can pull it and use it off the shelf without having to re-adapt it to my custom setup.

Araforn commented 4 years ago

What I have done is to set up an WemosD1 mini with DIYHue and then my Arduino for my Hyperion setup and then I have a mechanical relay which controls which of the two data lines feed into my LED strip. So, when Hyperiod is off, it is set to DIYHue and when the TV is on, the data line is set to Hyperion. The only thing that is required when you do this is that if you switch back to DIYHue and the DIYHue light was on before switching, the LEDs will not display the light settings in DIYHue until something changes. So, I have my system set so that when Hyperion turns off, if the DIYHue light is on, it dims by 1% and then brightens by 1% to get the lights to come back to the DIYHue current lights state. I'm doing this with 5 different strips, one with Hyperion and 4 with McLighting.

This ended up saving me SOOO many headaches. When I tried to wrap things together into one sketch it quickly turned out to be a lot more than I could handle. Yes, this is more expensive but not by that much. And it works! Also, upgrading the sketch later is a lot quicker. If a new DIYHue sketch comes out that I want to use, I can pull it and use it off the shelf without having to re-adapt it to my custom setup.

Thanks a lot for your reply. That sounds like a solid setup however I now have this working..... Almost.

I had to create some more variables and modify the for loop but now I have the screen grabbing perfectly whilst still having the strip available as a hue light.

I'm just coming across one issue where Hyperion is still sending a UDP stream even when the grabber is no longer getting information. I just need to write some logic to detect when the grabber is longer getting a signal and it will be complete.

I'll post the update here when I am finished.

Araforn commented 4 years ago

So I can now see this issue with a small bit of debug.

When Hyperion does not receive any picture it is continually sending data to the NodeMCU. If it continually sends data then It will never exit and allow a return to diyHue control.

See below modified code that works for the entire strip and see also the serial output showing that black (no colour) is being sent continually.

image

This is a hyperion issue/behaviour only but I may have to add some logic to detect if black is sent continually over time then close the UDP port. However If i do this im not checking for any new colour (new picture data) so as i write this, that wont work either.

The best way is to have no data sent when there is no picture.

90% there!!.

mariusmotea commented 4 years ago

You don't need to close the port, Hyperion will not detect anything because is UDP protocol. Just add an extra for loop to test if buffer is fully with zeros and if true don't do nothing. I also believe Hyperion need to fix this because esp8266 has power efficiency mechanisms and while it receive any data over wifi the power consumption is maximum and the chip hot witch affect the esp life.

cyclemat commented 4 years ago

Little tip Look for wled its an esp8266 or esp32 connect the esp to you Hyperion instance via USB and over wifi you can sync it to hue https://github.com/Aircoookie/WLED/releases

GitHub
Aircoookie/WLED
Control WS2812B RGB LEDs with an ESP8266 over WiFi! - Aircoookie/WLED
juanesf commented 4 years ago

Some time ago I tried to merge wled with diyHue, I was testing with hyperion and it works although not in the right way ...

https://github.com/Aircoookie/WLED/issues/40

juanesf commented 4 years ago

This was the last functional sketch I could do ...

https://github.com/diyhue/Lights/tree/master/Arduino/wled00

GitHub
diyhue/Lights
DIY lights with support for diyHue. Contribute to diyhue/Lights development by creating an account on GitHub.
Araforn commented 4 years ago

Thanks for your replies guys.

I've had time with this again and have now made the changes in the code to manage when no colour is constantly being sent. I now have noticed another issue where blue is constantly being sent when none of the devices are active on the HDMI switch but the TV is still on.

I can write another condition but I really need to understand if this can be fixed in Hyperion. I've created the following post on the Hyperion forum:

https://hyperion-project.org/threads/disable-udp-activity-when-there-is-no-signal.10409/

Ill post back if I find any more info.

Hyperion - Forum
REQUEST - Disable UDP Activity when there is no signal
Hi All, So I have been finalizing my Hyperion project and I'm really happy with the results except for the following. I'm using the typical HDMI...
sascha777 commented 4 years ago

Hi all, I am new to DiyHue. Just found this discussion as this is a really great idea! I have a Hyperion setup running and would love to add the Hue functionally to it.

@Araforn, I saw the discussion about flickering in the analog video grabbers which sounds very familiar to me; I also have this blue background. As there wasn‘t a solution available when I set up the Hyperion system I worked around this issue with my OpenHAB home automation by sending a constant black via SSH (which probably wouldn‘t be a good solution here) when turning off the TV.

While the Hyperion team work on this would you mind to share your solution with the work around for the black screen? I would love to give that a try.

Araforn commented 4 years ago

Hi all, I am new to DiyHue. Just found this discussion as this is a really great idea! I have a Hyperion setup running and would love to add the Hue functionally to it. @Araforn, I saw the discussion about flickering in the analog video grabbers which sounds very familiar to me; I also have this blue background. As there wasn‘t a solution available when I set up the Hyperion system I worked around this issue with my OpenHAB home automation by sending a constant black via SSH (which probably wouldn‘t be a good solution here) when turning off the TV. While the Hyperion team work on this would you mind to share your solution with the work around for the black screen? I would love to give that a try.

By sending a constant black you would effectively disable the diyHue functionlaity which is what im trying to avoid. The problem lies within the grabber type. In my case (and most peoples cases) we have the Analogue USB grabber that will produce a blue (no signal screen) when no connected HDMI device is active.

I have trialed the newer version of Hyperion which is Hyperion NG and even with the signal detection settings in this, there is no reliable solution to handle the blue screen. I have handled a black screen scenario in the diyHue sketch by adding in condition for a black screen (tv and hdmi converter powered off).

The blue screen however does not produce a stable RGB output and is very difficult to handle in this way. My solution which is now working is to add another condition before allowing the UDP stream to control the lights. Im doing this using MQTT.

The condition below:

if (packetsize)

is changed to:

if (packetsize && Enable_Hyperion)

By subscribing to a given topic any MQTT can enable or disable Hyperion. Im using Home Assistant to check the state of my Harmony remote activity and then writing true or false to the new condition "Enable Hyperion".

Since I know certain activities in Harmony will produce the blue screen I choose to disable Hyperion. Ill post up the full example later if anyone is interested?.

sascha777 commented 4 years ago

I worked around this issue with my OpenHAB home automation by sending a constant black via SSH (which probably wouldn‘t be a good solution here) when turning off the TV.

By sending a constant black you would effectively disable the diyHue functionlaity which is what im trying to avoid.

I think that was misleading. I don't send a constant black to the ESP but to my PI via hyperion-remote. That makes the Hyperion engine stop analyzing the video input and makes it send a dedicated color. I use 'black' as 'off' command to avoid a blue background when turning off the TV. This is quite similar to your Enable_Hyperion approach.

Anyway both approaches can only be used if an external command is set either to use Hyperion OR diyHue.

Fully agree that the best solution would be Hyperion NG figuring out if a video input is given or not. For my scenario I still would be interested in testing you sketch until another solution is available.

sascha777 commented 4 years ago

@Araforn I got all my DiyLights working 😃 and would love to combine with Hyperion now.
Are you going to share your sketch?

juanesf commented 4 years ago

https://github.com/hyperion-project/hyperion.ng/issues/769

juanesf commented 4 years ago

https://github.com/diyhue/diyHue/pull/413

juanesf commented 3 years ago

https://github.com/diyhue/diyHue/pull/531