Multi Endpoint RGB lights

This weekend I finally found some time for some updates and completed the multi endpoint with 4 RGB lights. I was hoping to drive more lights with a single JN5168, but it seems 4 RGB’s is the absolute limit. Since the JN5168 only has 5 PWM outputs, an external PWM controller was required. After having a hard time to with the Adafruit TLC59711 I succeeded with the Adafruit PCA9685. Also, updated the download page and pushed the repo to GitHub 🙂

Here is a short video showing the connection to the Hue and controlling the lights. Sometimes the App doesn’t update the state of the lights as fast as with single lights, I think this is because the JN5168 is pretty busy driving the lights.

The image below shows how all the parts are connected, it’s pretty simple.

Multi endpoint RGB schematic

Some more pictures

This slideshow requires JavaScript.

 

Author: Peter

Comments

  1. Could this be used to create a hue-compatible switched or dimmable outlet similar to the old Phillips LivingWhites plug or current Sylvania model 72922 smart plug?

    If a single inexpensive control board could run something like a Arduino relay shield via multi-endpoint, it could easily integrate into the output side of a multi toggle switch housing. Even including the 5168, relays, and PCBs, it would likely cost between $10-15 per circuit for a quad toggle switch. That’s almost as inexpensive as the cheapest RF relay outlets on Amazon, with full Hue integration, and works with small candelabra and fluorescent fixtures where standard Hue bulbs won’t.

  2. Hi

    I am using MeshBee for testing right now. If I use your code, would I need to add ZLL master key to connect it Philips Hue, or is it already included in the code?
    If you need to add it do you know where in the code?

    Thanks

    MM

      1. Thanks, if I am going to use NXP ZLL demo code, than I would need it right?
        Could tell me where this key needs to be added it, is it in common/source/ecb_decrypt.c
        this variable:
        // The Key input to the AES Program
        uint8 Key[16];

        Or somewhere else?

        Thanks for help

        MM

        I like your work nice hacking skills …

  3. What’s on Git, does not compile:

    c:/NXP/bstudio_nxp/zll/Custom_ZLL_Lights/Light_ColorLight/Source/zps_gen.c:1015:5: error: ‘zps_msgMcpsDcfm’ undeclared here (not in a function)

    First off there’s an NXP2 dir in the includes, besides NXP, and the above mentioned message does not exist.

    Do you have a coding version that DOES work?

  4. Hi,
    I’m developing a ZigBee board to control all lights from my home. I would like to switch on/off lights usign cheap Xiaomi Aqara ZigBee switches.
    Peter develop a software that use basically the same hardware, but using only 4 EndPoints and this project need 16 + 1.
    I’m really lost in ZigBee SDK, and I need some help. I can send one or more PCBs to someone that develops me with it.
    The board is not finished and I can make some changes, if anybody have an idea…
    Next projects will be control blinds, heater, AC..

    ZigBee 16 channels Dimmable Light

    General Description:
    – NXP JN516x: ZigBee module
    – PCA9685: 16 channels PWM controller [16 EndPoints]
    – INA260: Power meter [1 EndPoint]
    – PCB size: 190 x 59mm
    – Holes in corners and to use DIN rail Support

    Power IN: DC 6 to 30V (16A Terminal Block)
    16 x OUT channels (3 Pins plugable terminal block):
    1. Power [Same DC input] (Protection: PTC fuse 3A)
    2. PWM at 5V (Protection: 1206 resistor)
    3. GND

    1 x Automotive Fuse (before INA260) or if INA260 is not mounted
    1 x DC-DC: 5V (For PWM output with PTC fuse 3A and Diode protection)
    1 x LDO: 3.3V (For JN516x, no protection)

    2 x 8 channels DIP switch
    1 x reset switch

    2 x Configurable LEDs [DO0, DO1]
    1 x Power (3.3v) LED

    1 x UART to USB (CP210x) diode array protection
    1 x INA260: I2C Voltage, current and power sensor

    1 x Input Button at ACD1 [Configurable button]
    1 x Potenciometer at ACD2

    Improvement:
    1 x Isolate all 3.3V (JN516x, switches, UART-to-USB) [Expensive]
    1 x Input voltage up to 36V [DC-DC]

    ScreenShot: https://imgur.com/a/YkGdv

    Thank you

    1. Hi Jordi, You cannot control 16 lights with a single JN5168 the max number of endpoints I found is memory related and limits to 4x RGB or 5x Monochrome. Maybe someone more gifted could optimize the code and get some more endpoints out of it, but I don’t think 16 endpoints is viable. This post shows my setup in the early stages, currently I am using 2 JN5168’s to control 10 lights and am planning to add a few more. Having said this, I am very interested in dedicated boards for my setup maybe we can help each other out?

      Peter

      1. Sure you can control more than 16 devices. At least 127 to be more exact, and even 1024 if an 8 bit adress is used (didn’t look it up). Using i2c. You would ofcourse then delegate the actual driving of the lights, to slave chips.

        The JN5168/5169 is relatively expensive, so one JN5168 with a couple of i2c slave devices, would do the job nice, at the lowest possible cost.

        BTW the code in your git does not compile.

          1. I don’t see why this wouldn’t work. Ram has nothing to do with it, no endpoint requires RAM. In practice this would just work, if done right.

          2. @peter: I don’t see anything on that page explaining why it wouldn’t work. You CAN control 127 i2c devices from the JN5168. You don’t need ram, as the actual led driving is done by the slave. All the JN5168 has to do, is to forward the appropiate data to the slave. Again, you don’t do any signal processing on the JN5168 then, no dimming, or whatsover. You just pass on whatever it receives, to the correct clien. Nothing more. This is not only in theory possible, but also in practice.

          3. @peter: zigbee stack on JN5168/9 ofcourse. The rest on the slave chip. The JN5168 can then just be regarded as a simple portal/routing device. The actual states, and dimming and so forth, is done int he client. This is why this will just work. You’re driving the leds from the JN5169, which is why you need to store config and so forth on it. This is not needed when using slave devices.

            Don’t get me wrong. I love your work and kudos for it. Not trying to be a smartass or anything. If I had the hardware lying around here, I’d show it to you.

          4. I thought about using the JN5168 as radio and offloading all the work to a raspberry pie, would be great! Any insights on how this could be done, wouldn’t mind to collaborate on a project!

          5. In that case, if you want to use a pi, you don’t need the JN5169 at all. You can get a Zigbee device for pi for about 10 dollar. But then, if you do that, you might just as well ditch the hue hub alltogether, and use for instance deconz, which would effectively make your pi the hub. And it supports all philips devices, as well as ikea and others.

            This one is coming my way, but I want to keep the hub, so just using that one for zigbee sniffing to see what the switches actually report as.

      2. This is a pretty old thread now, I’m just getting into this and don’t need huge amounts of endpoints so not really that important to me.

        The chip has 32k ram on it, so I would think that would be plenty, it would see unlikely that the data for each endpoint would be that huge we’d be busting limits.

        I notice in the JenOS docs that it mentions the stacksize and heapsize can be changed by the variables defined in the Makefile. If you compile with OTA set it ups these a bit by default

        STACK_SIZE ?= 6000
        MINIMUM_HEAP_SIZE ?= 2000

        Compared to the defaults of 5k and 1k

        I would guess you could try upping these values a bit to get more memory available for these items. Disabling OTA (if you are using it) should enable these larger values to be used without problem I would think.

    2. Hello Peter,

      Thank you for this amazing project. I can report that the bin files provided by you are working like a charm. Both with a hue hub or an Ikea tradfri hub. The only thing I’m wondering about is, if there is a mechanism to unlearn a device without clearing the eeprom with the programmer. When I switched from the tradfri hub to the hue hub, the device was not found until I cleared the eeprom content. I do know that resetting a hue bulb can only be done by the app with the serial number of the device or some other software tricks, while a tradfri bulb can be resetted by cycling it on and off a few times in a row. Would be interesting if there is a way to reset the device included in the default nxp framework.

      Best regards,
      Tom

  5. Hi Peter,
    When you say “Monochrome” is PWM or on/off?
    Please accept my google+ invitation. We can chat and share information faster,.

    Jordi

  6. I don’t see why this wouldn’t work. Ram has nothing to do with it, no endpoint requires RAM. In practice this would just work, if done right.

    1. I’m very lost in NXP SDK.
      I undestant that every EndPoint need an instance of LightDevice, more lights more memory needed.
      Peter, do you think that it could be possible control 8 on/off lights in the same module?
      Henri, do you any idea how to use less memory?

      Thank you

      1. Hey Jordi. The error in your statement is here:

        “I undestant that every EndPoint need an instance of LightDevice, more lights more memory needed.”

        This is not correct. Sure you need endpoints but they don’t need an instance of lightdevice. This can be routed to the slaves.

        For the sake of it, I just configured a stack with 32 endpoints and flashed that onto my JN5169, and it works without issues.

        Offcourse, it would require coding on the slave part. As that is where you’ll be keeping endpoint config state and so forth.

        1. Please share your efforts, it would be awesome to control that many lights with a single JN5169.
          What hardware are you using for the slaves? And how do you handle the routing?

          1. Hey Peter,

            Im a software engineer with lots of experience in embedded. I don’t actually have a setup here that controls that many devices, as I’m working on a different project (see my below question about reporting as an original bulb).

            The part I have proven, is that you can have 32 endpoints on a single JN5169. Haven’t tried more, sure there’ll be a limit somewhere.

            Instead of instances for every endpoint, you can have a single instance, routing all endpoints.

            I’d be happy to contribute to the concept of more than 5 endpoints (using a i2c slave dimmerchip) but then someone would have to provide me the hardware for it. Not going to invest in that myself.

            Note that it would require more programming on the slave part.

          2. Maybe you can share how we can use the JN5168 as a router for the slaves and what kind of hardware would be required for the actual slaves?

          3. Basically you make a project with one light of the type by choice. Then instead of having this register and work like your code does, you use it as a funnel to channel the i2c datasets through. So the slaves drive the registering by passing on the data to the JN5169. Simple spoken they tell the JN5169 ‘register a light with these settings’. So you re-use the same instance for all lights.

            Hardware wise you can follow the AN/Datasheet from the chosen chips. It’s not that hard, from what I could see, Jordi already has this covered. Most work would have to be done on the slave code.

            How exactly the data is routed (As in: in which format) between JN5169 and slaves, is a matter of just gathering what data is needed and come up with a makeshift protocol for it.

            Again, I totally understand where you are coming from, it’s not my intention to be a smartass.

  7. BTW, have you ever tried having the bulb report itself as an original Philips bulb?

    I’m asking this because I’m in the process of hacking a KAKU magnetic door switch into a hue compatible device, which can only be done if it reports as one of the 3 original philips switch devices (TAP/Dimmer/Motionsensor). I’m waiting for my zigbee sniffer to arrive to finish this, but was wondering if you had also tried this already. BTW the dimmerswitch also uses HA besides ZLL.

  8. Hi,
    These days I will study NXP SDK and try to undestand how it works.
    @Henri: Your opinion is replace PCA9685 by a uC with I2C and several PWM and move some source to this new uC?
    Components price will be very similar, but will be necesari two firmware.
    In the same way that Peter created a RGBLightDevice with 3 PWM output, it could be possible create a 16ChannelsLightDevice, each channel “registered” to an EndPoint?

    1. No, you can keep the PCA9685. This IS an uC with I2C and several PCM, and programmable. And they cost only like EUR 2-3, so they are way cheaper. So what I’m suggesting is one JN516x to use as Zigbee stack (expensive) and then several cheap PCA9685 to do the actual controlling of the lights.

      This wil show up as separate endpoints per light, so not one endpoint with x lights, but x lights.

  9. PCA9685 is an I2C (slave) PWM expander, it can be configurate sending I2C command in order to change his PWM outputs. But it is not programable, you can not put an executable code inside.
    I think that when you use “programable” is what I say “configurable”?

    You write about PCA9532. It is very similar to PCA9685, but not used PWM outputs can be configurarte as GPIO.

    1. You are correct, and I stand corrected. I just glanced the datasheets quickly.

      However, there are solutions wich do this. Also you can use a separate uC, and these DONT cost as much as the JN5169. The whole goal is cost-based, if the JN516x had cost like 1 euro, no-one would ponder this.

      At consumer quantities the JN516x will cost somewhat like EUR 20. A capable enough uC to drive, for instance, the PCA9685, does not have to cost more than say roughly 5-10 euro. Which makes it feasable. Also you only need one for an array of PWM expanders.

      So. One JN516x (~EUR 20), one uC (EUR 10 if we leave some headroom), and several PCA9685 or similar, in the quantity desired, would do the job nicely.

      In any case, as long as one offloads the actual state/dinning/configuration to ‘something else’, the JN5169 is more than capable to handle large quantities of lights. Way more than 4 or 5.

      On a smaller scale, I think I could get up to 7-8 on the JN5169 using PeeVee’s code as basis, by ditching stuff which is not needed, and optimizing/rewriting code. Maybe even more.

  10. I do not like the idea of use a extra uC, a lot of job. I will try to optimize code in order to get more lights in one JN5168. If I cannot get enought lights I will try to do your idea.

    JN5168 —-(I2C or UART)—> uC (several PWM) —-(I2C or UART) —–> PCA9685

    Master Board:
    JN5168 + uC (16 PWM)

    Slave Board
    PCA9685 (16 PWM) or PCA9532 (8 PWM + 8 switch)

    1. @jorid: with all due respect, but I think you need to do more research yourself, and not try to get others to do it for you. There are solutions out there for what you are looking for. Personally, if I were to design such a board/thing, i’d go for a cheaper ‘zigbee radio device’, a good CPU, and PWM IC’s and hook it all up using i2c. The JN5168 is very expensive. and that what it has to offer extra, won’t be used in a setup above, say, 5-10 lights, since then you’ll simply HAVE to offload to other solutions. Take for instance a pi zero with the above mentioned USB zigbee device (based on CC2531) , and you have something that is still cheaper than the JN5168, and much more capable. And way easier to develop for.

      1. My initial idea was made a simple modification of Peter’s software., but it is not possible.
        Now I’m playing with NXP ZigBee SDK, if I cannot get a solution I will have to change all project. Like you wrote:
        Use a cheap ZigBee like (CC2531) and a big uC with a lot of PWM

        I bought some modules at http://www.meshreen.com at samples it cost about $10 and volume for less than $5.

        Thank you for your help

  11. @Peter: Last days I was playing with SDK demo samples. I modified tsHA_MainsPowerOutletDevice in order to has several EndPoints and clusterInstances.
    But I cannot get it.
    I think that he problem can be in zcl.c:
    // create endpoint record array
    vZCL_HeapAlloc(psZCL_Common->psZCL_EndPointRecord, tsZCL_EndPointRecord, (sizeof(tsZCL_EndPointRecord))*u8NumberOfEndpoints, TRUE, “EP_Record”);

    When array is created u8NumberOfEndpoints is 0 and this method alloc 2 endpoints.

    I will continue forcing u8NumberOfEndpoints.

  12. Hi Peter,
    I love your stuff! And the fact that you share your work with everybody ^^.
    I got myself a mesh bee and and uartsbee v5 to start and emulate those expensive Hues.
    – Do you find auto detection of the lights reliable? I only got one of the binaries detected at all; most of the time it just says “no new lights found”. Is there any way to get this more reliable?
    – I also tried to run from source. The ZLL demo projects compile fine, but your current code doesn’t seem to compile. I got the same error message as @Henri: c:/NXP/bstudio_nxp/zll/Custom_ZLL_Lights/Light_ColorLight/Source/zps_gen.c:1015:5: error: ‘zps_msgMcpsDcfm’ undeclared here (not in a function)

    Could you help? Thanks in advance and keep up the awesome work!

    1. The git code is built on an older version. You need to change the OS config diagram, as explained here:
      https://community.nxp.com/message/970340

      Then it will compile.

      Also you can just download the NXP zigbee light link application note “JN-AN-1171-ZigBee-LightLink-Demo”, and just change the file ./Common_Light/Source/zpr_light_node.c, line 154, comment out the s_au8ZllLnkKeyArray[16] value there and replace by:

      static const uint8 s_au8ZllLnkKeyArray[16] = {0x81, 0x42, 0x86, 0x86, 0x5D, 0xC1, 0xC8, 0xB2,
      0xC8, 0xCB, 0xC5, 0x2E, 0x5D, 0x65, 0xD1, 0xB8};

      That’s all needed to get the application note to compile and bind to a hue network as light.

      1. @Henri Zikken

        Many thanks for the instruction to change the Common_Light/Source/zpr_light_node.c file to contain the proper key for connecting to the Hue bridge.

        Building the DimmableLIght demo code results in a BIN for my JN5169 board that is recognised by my Hue bridge. The regular search in the Hue App did not reveal the lamp, but using Touchlink (iOS HueLights App) discovered the lamp OK. The Hue App also listed the lamp, and the lamp can now be controlled by the App.

        I have been searching for many hours, your post solved my misery, thanks for that.

        Bedankt.

      2. The link for changing the OS config diagram contains a seemingly complicated change, so I looked further.

        I found a file that is already updated in this github:
        https://github.com/someone42/ZLL_Lights/tree/72c697e59572225fdc072ea05143facd7aaf7222/Common_Light/Source

        I replaced the App_ZLL_Light_JN516x.oscfgdiag file, with the file from this github:https://github.com/someone42/ZLL_Lights/tree/72c697e59572225fdc072ea05143facd7aaf7222/Common_Light/Source

        After this change the build runs without the ‘zps_msgMcpsDcfm’ error, and the builds complete fully and creates the BIN files. Nice!

        Thanks to @someone42. His github is really informative if you want to change/extend the excellent work from @peeveeone.

  13. Hi

    Can I ask you how many and what changes do you have to make to NXP ZigBee Light Link demo to drive LED from pins on Meshbee.
    I’ve uploaded demo code (On/off light and Colour light) with trust link key changed to the one you set and I was able to connect to Philips Hue, but it seems that no pins are set to drive the LEDs.
    Could you help me to look in the right direction?

    Thanks

    MM

  14. Hi PV,
    I followed your toutorial an made a test setup running. With the Light_ColorLight_JN5168_ME_4_INVERTED.bin.
    Now I try to build up an other setup with transistor firing a 12V RGB LED string.
    Thatfore i qould have to use REGULAR firmware, but when I use it,
    the Hue-App is not able to discover the lights.
    Do you have an idea what the problem could be?
    Thanks!
    Bob

  15. Great achievement ! Inspired by this, I was successful in porting an existing CC2500 library, which allows control of the Philips GEN1 livingcolor lights, to the JN5168 and merge it into your code. I am now able to control my old GEN1 livingcolor lights with the hue app! at this point i have 4 lights working using hardcoded addresses.. need to see that i add a learning mechanism that stores light data still..and maybe see if i can up the number of lights that can be controlled. Thanks !

  16. To drive a 12V RGB LED light, would you need a driver additionally? Would the adafruit circuit be able to handle this?

  17. Hi PV1 and all,
    Inspired by your projects, I searched the web and found a cheep module based on JN5168 called –
    E75-2G4M20S. It costs only $6.5 and I built two prototypes: NXP 16 keys remote control and light end device.
    Programmed both with NXP zigbee light link application note “JN-AN-1171-ZigBee-LightLink-Demo
    Controller_ColorSceneController_JN5168.bin and Light_DimmableLight_JN5168_DR1175.bin.
    Programing and communication with the prototypes is working fine.
    When I power up the remote controller I get on the PuTTY console:
    “APP: Watchdog timer has reset device!” every 15 seconds which is the default time for the watchdog timer.
    I get nothing from the light end device on the PuTTY console.
    I will appreciate any ideas that will help me with my problem.

  18. Hi Peter,
    great job!
    Could You explain please which DIO lines of JN5168 are the SCL and SDA lines of I2C interface please?

    Best Regards and Happy New Year!

    Michal

  19. hi peter! amazing work! under what license do you publish your code? are deriatives allowed, and if so to what extent?

    cheers,

    markus

  20. Hi, your work is really awesome!
    I wondered, if you have interest in porting your project to xBee modules? This would open up an easyer way of use with the Digi XCTU software.

    mannaris

  21. Good Job!!

    im thinking of making a hue based light wall.. so its basicly gonn be a few rgb adressable strips..

    aka .. each led is one pixel ..

    not sure how to do it exactly yet .. might be 2 devices .. one with a few diffrent settings for animations and 3 channel rgb 255 diffrent ..

    what henri said further up is the basics .. with one main board and control the led strip..

  22. I have been following this up for a while; all other sources on the internet regarding JN5168 are revolving around your work.

    I am not a programmer and have little experience with Arduino only, pulled the trigger on a MeshBee and later NXP cheap versions from aliexpress, working with the NXP beyond studio was a nightmare for me. I am not a windows user and used VMware, and the software is hard to understand for me.

    I couldn’t do anything other than flushing the MeshBee with your bin files, and the 5 Light controls discovered by Hue bridge and later via Alexa. I can turn on and off and dim five small LEDs.

    I went this route as I wanted to interface an RF remote for my lighting and curtains system with a MeshBee, as well as some floor lighting, in the sense of MeshBee>trigger some relays connected to push buttons on the remote>light control, I know that there are a ton of other ways using ESP32 and ESP8266. However, I hate to give these small hackable devices my WIFI password; and decided that a Zigbee device should be “theoretically” much secure, and my tests are working fine.

    Here come my troubles, the bin files are designed for PWM control, I can load an Arduino Nano with PWM input and then connect relays and such, this nano can be connected to the MeshBee to achieve what I wanted.

    I have two questions:

    Did you make any progress further with this project? Any other source you would love to share?
    Is there is a way to change the bin file to achieve what I explained above without having a second Arduino to translate the PWM into other relays? Maybe change device types from lamps to another type within NXP, or a side program loaded into the same MeshBee? I will appreciate your input.

    Thanks once again for all this write-ups

    1. Hi Mody,

      I was in the same route as you. I want to control WS2812 led strips (to extend the Ambient light on my Philips TV in the closets. I tried to understand the source code but it’s too far over my head. I manage to compile it but I really can’t find the way how to make it my own.

      Eventually I decoded the I2C signal from the Light_ColorLight_JN5168_ME_4_REGULAR.bin firmware. This didn’t came easily also, because the ESP8266 device I want to use apparently does not support a I2C slave flawless. I used an Arduino Due what I had laying around. Since it uses 3.3V also I did not have to level shift the data lines. If you use an 5V 8bit Arduino, make sure you bi-directional level shifter (I have not test my code with an 8 bit Arduino)

      I’ve posted some example code how to decode the I2C signal. It adds the 4 RGB lights to an array and publish them on the serial port. Let me know if it’s useful for your project:
      https://github.com/satoer/I2C-JN5168-Philips-Hue-decoder-from-PeeVeeOne-

      @Peter (PV1): I don’t know if you are still active on this fantastic project, but it really would help if you also can create an binary with a simple serial output with a 115200 baud rate. This way we can read the JN5168 in a ESP8266 / 32. I’ve tried to understand the code, but it’s just too complicated for me.

      1. Hi Satoer,

        Thanks for the writeup and the code; unfortunately, your post and code went over my head, and since the NXP goes over your head, then probably I will not get further than what I reached already.

        I can signal the PWM out of MeshBee to Arduino PWM read, and from there I can do what I want, this setup requires 2 boards (which is not a significant problem for me), yet some issues cant be solved, one example is the following:

        I wanted the MeshBee to behave as a colour temperature dimmable LED (cool/warm), not RGB, and my problem goes like this:

        1) How to edit the bin file? then;
        2) Which syntax to be edited? then;
        3) Edited to what? My understanding is, there should be a device list ID Library available somewhere, and I then replace the device ID to show up as a colour temperature changing LED rather than a dimmable only single LED.

        I am not an engineer, and this is where I am stuck, any help?

      2. HI, I made some progress with NXP software, was able to compile my own files which didn’t work 🙂

        But at least I can have the build function working to be able to build bin files myself,.

        Reading around page 9 of the below pdf link open a totally different possibilities, may be time to jump in depth into this with the hope to learn something.

        http://read.pudn.com/downloads790/ebook/3120425/JN-AN-1166-Smart-Lamp-Drivers/Doc/JN-AN-1166-Smart-Lamp-Drivers.pdf

  23. Hi, Peter. I was looking for your email to contact you, but couldn’t find one so I’m reaching out here. I have several questions about the lights and just wanted to see if you had time to connect. Thank you!

  24. Hi, I am trying to do replay attack on Philips hue. I have hue bridge v2 (square) and hue white-color and white ambiance bulbs. I am using Api-Mote v4 device with killer bee to dump and replay the packets.
    But so far I haven’t been successful. I simply replayed the captured file.same thing I did with Xbee S1 and S2 module previously which was successful.
    I have the Philips hue latest version firmware updated. If you could help me in any way to do successful replay attack or point out why my replay packets are not being received/accepted would be a great help.

Leave a Reply to MM Cancel reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.