{"id":16229084,"url":"https://github.com/ktibow/infinity-mirror","last_synced_at":"2025-07-20T13:33:26.956Z","repository":{"id":91870250,"uuid":"280520418","full_name":"KTibow/infinity-mirror","owner":"KTibow","description":"Code + tutorial for a smart infinity mirror","archived":false,"fork":false,"pushed_at":"2021-03-01T15:16:20.000Z","size":2018,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-19T06:36:12.400Z","etag":null,"topics":["arduino","esp32","heltec","infinity-mirror","light-strips","strip"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KTibow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"KTibow"}},"created_at":"2020-07-17T20:36:40.000Z","updated_at":"2021-03-01T15:16:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"99217a38-fc04-4862-8601-50708ade939b","html_url":"https://github.com/KTibow/infinity-mirror","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/KTibow/infinity-mirror","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTibow%2Finfinity-mirror","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTibow%2Finfinity-mirror/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTibow%2Finfinity-mirror/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTibow%2Finfinity-mirror/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KTibow","download_url":"https://codeload.github.com/KTibow/infinity-mirror/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KTibow%2Finfinity-mirror/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266135014,"owners_count":23881774,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","esp32","heltec","infinity-mirror","light-strips","strip"],"created_at":"2024-10-10T12:57:19.840Z","updated_at":"2025-07-20T13:33:26.934Z","avatar_url":"https://github.com/KTibow.png","language":"C","funding_links":["https://github.com/sponsors/KTibow"],"categories":[],"sub_categories":[],"readme":"# infinity-mirror\nExample code for a smart infinity mirror!\nOkay, so first of all, here's some credits:\n- Thanks to the people on the Arduino fourm! You've helped my a lot.\n- Thanks for HelTec's [OLED display API docs](https://github.com/HelTecAutomation/Heltec_ESP32/blob/master/src/oled/API.md), and the [rest of their library](https://github.com/HelTecAutomation/Heltec_ESP32/).\n- Thanks to [simple-weather-card](https://github.com/kalkih/simple-weather-card). Your icons gave me the inspiration for the patterns, and your source gave me a really good mapping.\n- Thanks to the [World Time API](https://worldtimeapi.org/) for the API.\n- Thanks to [Home Assistant](https://home-assistant.io/), of course!\n- Thanks to [Dave's Garage](https://www.youtube.com/channel/UCNzszbnvQeFzObW0ghk0Ckw) and [this post from him](https://www.youtube.com/post/Ugzhaf4slmPXC9Kkzo54AaABCQ).\n  \nAnd here's the fourm discussion: https://community.home-assistant.io/t/212410?u=ktibow\n  \n\u003cdetails\u003e\u003csummary\u003eOkay, now for some pictures:\u003c/summary\u003e\n  \n![Screenshot of full control in HA](/rsz_2020-07-17-140729_1920x1080_scrot.png)\n![Picture of screen](/IMG_20200717_141543.jpg)\n![Picture of infinity mirror](/IMG_20200717_141323.jpg)  \n\u003c/details\u003e\n\nNow let's go to the parts.\n1. (Only tested on) [HelTec Wifi Kit 32](https://heltec.org/project/wifi-kit-32/)\n2. [Any USB cable](https://www.amazon.com/USB-Cables/b?node=464394)\n3. [Any breadboard](https://www.amazon.com/breadboard/s?k=breadboard)\n4. [Any couple male-to-male jumper wires](http://adafru.it/759)\n5. (Only tested on) [LED strip](https://www.btf-lighting.com/products/ws2812b-led-pixel-strip-30-60-74-96-100-144-pixels-leds-m?variant=25586938511460)\n6. (Only tested on) [Infinity mirror to hack](https://www.amazon.com/dp/B07LF4YMCZ)\n\nOkay, let's do this.\n## Pry apart the infinity mirror\n### Bottom\n1. First, remove the battery base. Do that by pushing apart the bottom part, and while you do that, pull away the battery holder.\n2. Disconnect all of the wires. Just pull/chop them off.\n3. Push out the stuff. You might need to push on some stuff really hard in order to push out the switch and power plug.\n4. Make the hole between the base and top bigger for the light strip connector.\n\nNote: Don't put the battery base back on, not even later.\n### Middle\n1. Pry off the coverings. The mirror is made of 3 parts, the middle, and the two covers. Pry off the glue.\n2. Pull off one of the mirrors. Be very gentle, or you'll have a scratched-up mirror like I do.\n3. Detach the provided light strip. Just pull off the adhesive.\n## Cut and place the light strip\n1. Place the light strip around the mirror.\n2. Find which side is the input and output of the LED strip, and cut off any excess. It's okay to cut off the other connector, too.\n3. Count the number of LEDs in the strip.\n4. Peel off the adhesive backing and place the light strip. Make sure to put the connector through the hole you made earlier.\n5. Route the connector through the light switch hole.\n\nYahoo! You've done most of the hardware.\n## Set up the connections\n1. Find your WiFi Kit 32.\n2. Place it in the middle of your breadboard.\n3. If the header's aren't soldered on yet, solder them on now.\n4. Put one wire at pin 5. Put the other two at 5V and GND.\n5. Put the pin 5 wire to the middle, green wire of the connector.\n6. Put the 5V wire to the red wire of the connector, and the GND wire to the white wire of the connector.\n## Set up Home Assistant\n1. Add the Local IP integration using the GUI.\n2. Add these `input_number` helpers:\n- `input_number.mirror_brightness`\n  - Name: Mirror Brightness\n  - Icon: `mdi:mirror`\n  - Max value: `255`\n  - Leave everything else\n- `input_number.hue`\n  - Name: Hue\n  - Icon: `mdi:mirror`\n  - Max value: `255`\n  - Leave everything else\n- `input_number.saturation`\n  - Name: Saturation\n  - Icon: `mdi:mirror`\n  - Max value: `255`\n  - Leave everything else\n3. Add these `input_select` helpers:\n- `input_select.mirror_force_weather`\n  - Name: Mirror force weather\n  - Icon: `mdi:mirror`\n  - \u003cdetails\u003e\u003csummary\u003eOptions:\u003c/summary\u003e\n\n    - clear_night\n    - cloudy\n    - fog\n    - lightning\n    - storm\n    - storm_night\n    - mostly_cloudy\n    - mostly_cloudy_night\n    - heavy_rain\n    - rainy\n    - snowy\n    - mixed_rain\n    - sunny\n\u003c/details\u003e\n\n  - Leave everything else\n- `input_select.mirror_mode`\n  - Name: Mirror mode\n  - Icon: `mdi:mirror`\n  - \u003cdetails\u003e\u003csummary\u003eOptions:\u003c/summary\u003e\n\n    - Light\n    - Clock\n    - Weather\n    - Force weather\n    - Rainbow\n    - Random\n    - More patterns\n\u003c/details\u003e\n\n  - Leave everything else\n- `input_select.mirror_pattern`\n  - Name: Mirror pattern\n  - Icon: `mdi:mirror`\n  - \u003cdetails\u003e\u003csummary\u003eOptions:\u003c/summary\u003e\n\n    - Cyan and Magenta\n    - Cyan and Orange\n    - Cyan and Green\n    - Cyan and Purple\n    - Orange and Magenta\n    - Orange and Green\n    - Orange and Purple\n    - Green and Magenta\n    - Green and Purple\n    - Purple and Magenta\n\u003c/details\u003e\n\n  - Leave everything else\n4. Add these `input_text` helpers:\n- `input_text.mirror_status`\n  - Name: Mirror status\n  - Icon: `mdi:mirror`\n  - Maximum length: 10\n  - Leave everything else\n5. Add this stuff to your `configuration.yaml` (replace `weather.kbfi_hourly` with your weather sensor):\n```yaml\nlight:\n  - platform: template\n    lights:\n      infinity_mirror:\n        friendly_name: Infinity Mirror\n        value_template: '{{is_state(''input_text.mirror_status'', ''on'')}}'\n        level_template: '{{((states(''input_number.mirror_brightness'') | int - 10) / 68 * 100) | int}}'\n        color_template: '({{(states(''input_number.hue'') | int / 255 * 360) | int}}, {{(states(''input_number.saturation'') | int / 255 * 100) | int}})'\n        turn_on:\n          service: input_text.set_value\n          data:\n            entity_id: input_text.mirror_status\n            value: 'on'\n        turn_off:\n          service: input_text.set_value\n          data:\n            entity_id: input_text.mirror_status\n            value: 'off'\n        set_level:\n          service: input_number.set_value\n          data_template:\n            entity_id: input_number.mirror_brightness\n            value: '{{(brightness | int / 100 * 68 + 10) | int}}'\n        set_color:\n          - service: input_number.set_value\n            data_template:\n              value: \"{{(h | int / 360 * 255) | int}}\"\n              entity_id: input_number.hue\n          - service: input_number.set_value\n            data_template:\n              value: \"{{(s | int / 100 * 255) | int}}\"\n              entity_id: input_number.saturation\nsensor:\n  - platform: template\n    sensors:\n      mtms:\n        value_template: '{{states(''weather.kbfi_hourly'')}}|{{states(''input_text.mirror_status'')}}|{{states(''input_number.mirror_brightness'')}}|{{states(''input_number.hue'')}}|{{states(''input_number.saturation'')}}|{{states(''input_select.mirror_mode'')}}|{{states(''sun.sun'')}}|{{states(''input_select.mirror_pattern'')}}|{{states(''input_select.mirror_force_weather'')}}'\nshell_command:\n  update_mirror: '/usr/bin/curl -d \"info={{states(''sensor.mtms'')}}\" \"http://192.168.1.97/collect\"'\n```\n6. Restart Home Assistant\n7. UI control option #1 (requires `slider-entity-row`, `rgb-light-card`):\n```yaml\nentities:\n  - entity: light.infinity_mirror\n    full_row: true\n    toggle: true\n    type: 'custom:slider-entity-row'\n  - colors:\n      - hs_color:\n          - 315\n          - 85\n        icon_color: 'hsl(315, 100%, 75%)'\n      - hs_color:\n          - 0\n          - 77\n        icon_color: 'hsl(0, 100%, 75%)'\n      - hs_color:\n          - 40\n          - 85\n        icon_color: 'hsl(40, 100%, 75%)'\n      - hs_color:\n          - 99\n          - 85\n        icon_color: 'hsl(99, 100%, 75%)'\n      - hs_color:\n          - 140\n          - 85\n        icon_color: 'hsl(140, 100%, 75%)'\n      - hs_color:\n          - 180\n          - 80\n        icon_color: 'hsl(180, 100%, 75%)'\n      - hs_color:\n          - 215\n          - 80\n        icon_color: 'hsl(215, 100%, 75%)'\n      - hs_color:\n          - 270\n          - 80\n        icon_color: 'hsl(270, 100%, 75%)'\n    entity: light.infinity_mirror\n    justify: center\n    size: 35\n    type: 'custom:rgb-light-card'\nshow_header_toggle: false\ntype: entities\n```\n8. UI control option #2 with `light-entity-card`:\n```yaml\nentities:\n  - entity: light.infinity_mirror\n  - brightness: true\n    brightness_icon: weather-sunny\n    child_card: true\n    color_picker: true\n    color_temp: true\n    color_wheel: true\n    consolidate_entities: false\n    entity: light.infinity_mirror\n    full_width_sliders: false\n    hide_header: true\n    persist_features: false\n    shorten_cards: true\n    show_slider_percent: true\n    smooth_color_wheel: false\n    temperature_icon: thermometer\n    type: 'custom:light-entity-card'\n    white_icon: file-word-box\n    white_value: true\n  - entity: input_select.mirror_mode\n  - entity: input_select.mirror_pattern\n  - entity: input_select.mirror_force_weather\nshow_header_toggle: false\ntitle: Infinity mirror\ntype: entities\n```\n9. And add this automation too, so HA can tell the mirror when anything changes:\n```yaml\n- id: 'let_mirror_know_when_status_changes'\n  alias: Let mirror know when anything changes\n  description: ''\n  trigger:\n  - entity_id: sensor.mtms\n    platform: state\n  condition: []\n  action:\n  - data: {}\n    service: shell_command.update_mirror\n```\n## Set up your environment and upload\n1. Make sure the [Arduino IDE](https://www.arduino.cc/en/Main/Software) is installed, and set up for HelTec's board. [Here's HelTec's guide.](https://heltec-automation-docs.readthedocs.io/en/latest/esp32+arduino/quick_start.html#via-arduino-board-manager)\n2. Download [the zip](https://github.com/KTibow/infinity-mirror/archive/master.zip), unzip it, and open `mirror.ino` in `mirror`.\n3. Open `token.h` and change the stuff, and open `mirror.ino` and change the number of LEDS. You might also need to change your gateway, subnet, and DNS IP addresses in `setup.h`.\n4. Upload it!\n## You're done!\nLet me know if you have any problems [in an issue](https://github.com/KTibow/infinity-mirror/issues/new). BTW: You can upload via a custom OTA web server with [these instructions](https://github.com/KTibow/esp32-ota#upload-sketch), so you don't have to physically plug it in to your computer as long as it has power.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktibow%2Finfinity-mirror","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fktibow%2Finfinity-mirror","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fktibow%2Finfinity-mirror/lists"}