as a Home Assistant dashboard panel.
This post might be outdated, please check the latest version on GitHub
This document is only intended for the model IGW-5000A2BKMP-I v2
with an Intel x86 CPU. For the model RG3205W
with a Qualcomm arm64 SoC, please refer to RG3205W/README.en.md. How to identify?

Contents
- 1 HELP NEEDED
- 2 Tech specs
- 3 Driver status
- 4 Linux installation
- 5 Configurations
- 6 Research notes
HELP NEEDED
I dumped the original Android-x86 firmware from flash, but it failed to boot after I wrote it back in.
Any contributions to the repository are very welcomed.
If you have any questions or want to help this project, please join our Telegram group chat.
TODO list
- Fix sound card driver
- Fix speakers (maybe ALSA configs)
- Fix microphones
- Fix camera driver
- Fix bluetooth driver
- Fix reset button
- Find a way to install Linux without disassembling nor soldering (maybe through easycwmp on port 7547)
Tech specs
CPU | Intel Atom x5-Z8350 (4C4T) @ 1.44 GHz |
RAM | Hynix 2 GB DDR3 ECC @ 1600 MHz |
Storage | Kingston TB2816 16 GB eMMC |
Screen | 8-inch 1280x800 with Goodix I2C touch screen |
Wi-Fi & Bluetooth | Realtek RTL8822BE |
Sound card | Realtek RT5672 |
Speakers | 2 x 5 W (SPL 87 dB @ 1 W | 1 m) |
Microphones | 4 omnidirectional microphones with dedicated DSP |
Camera | OMNIVISION OV2680 with 2 megapixels |
Dimensions | 21.2 x 23.5 x 12.2 cm (height x width x depth) |
Weight | 1.1 kg |
Driver status
As in the latest Arch Linux with 6.14.10-arch1-1 kernel, on June 10, 2025:
Device | Driver | Status |
---|---|---|
Touch screen | goodix_ts | OK |
Wi-Fi | rtw88_8822be | OK |
Bluetooth | rtw88_8822be | Not working |
Sound card | snd_soc_sst_cht_bsw_rt5672 | Speakers OK, microphones not working |
Camera | atomisp | Not working in kernel 5.15, unavailable in kernel 6.2+ |
Linux installation
Disassembling
Disassemble the device, it has 10 snap-fits under the back panel edges, be careful not to damage them; then 8 screws under the panel, and 4 screws hidden under the rubber strip at the bottom of the device.
Locate the unpopulated micro USB port on the left edge of the motherboard:

Solder a micro USB female connector and connect an OTG adapter cable; or just solder a cable with a standard USB-A female connector to it, then short the fourth pin (or the ID
pad nearby) to the fifth pin GND (or any ground pad on the motherboard), making the port function as OTG host.
Here is an example for soldering a USB-A female connector:

Flash a USB drive with your favorite Linux distro.
Considering the Movistar Home has only 2 GB of RAM, it is highly recommended to only use a window manager. If you want to use a full desktop environment, consider using a lightweight one like Xfce.
Connect a keyboard and the drive to a USB hub and connect it to Movistar Home. Power it up while pressing the F2 key, it will boot into the BIOS (UEFI) setup, navigate to the last tab (Save & Exit
), select your USB drive (should be something like UEFI: USB, Partition 1
) in the Boot Override
menu, press Enter key to boot it.

Install your Linux distro as usual, it might be necessary to include non-free drivers and firmwares.
❗ Important
It is recommended to set up the OpenSSH server before unsoldering the USB connector and reassembling the device, for possible future maintenance.
Configurations
The following configurations were made for Arch Linux with the Sway window manager (based on the Wayland compositor wlroots), some modifications may be needed for other distros, window managers or desktop environments.
Sway being a tiling window manager is not necessary for the use case of kiosk (displaying one browser tab only), I used it because of its high performance and the support of IPC commands (useful for e.g. backlight control). You can also try others like cage, a minimal compositor designed for kiosk mode.
If you prefer to use a full desktop environment, please refer to the legacy guide for Xfce.
Improve Wi-Fi stability
Create the file /etc/modprobe.d/99-movistar-home-panel.conf
with the following content:
# disable RTL8822BE power-saving
options rtw88_core disable_lps_deep=y
options rtw88_pci disable_msi=y disable_aspm=y
options rtw_core disable_lps_deep=y
options rtw_pci disable_msi=y disable_aspm=y
Then execute sudo mkinitcpio -P
to regenerate the initramfs.
Edit the file /etc/systemd/logind.conf
to change the values in section [Login]
as follows:
HandlePowerKey=ignore
HandlePowerKeyLongPress=poweroff
This will make the power button do nothing on a short press, and power off the device gracefully on a long press.
If you have configured a screen lock, you can also set HandlePowerKey=lock
to lock the screen.
Then execute sudo systemctl enable --now systemd-logind.service
.
Screen rotation and backlight control
Create the file /etc/mkinitcpio.conf.d/99-movistar-home-panel.conf
with the following content:
MODULES=(i915 pwm-lpss-platform)
Create the file /etc/udev/rules.d/10-movistar-home-panel-backlight.rules
with the following content:
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chgrp video $sys$devpath/brightness", RUN+="/bin/chmod g+w $sys$devpath/brightness"
Then execute sudo mkinitcpio -P
to regenerate the initramfs.
Make sure to add your user to the video
group with sudo usermod -aG video $USER
.
Edit the Sway config file (default is ~/.config/sway/config
) to add the following content:
# ...
# display
output DSI-1 {
power on
mode 800x1280
position 0 0
transform 90
scale 1.25
adaptive_sync on
background #000000 solid_color
}
# ...
If you prefer the full resolution of 1280x800, you can change the scale
to 1.0
.
Touch screen
Add the following content to your Sway config file:
# ...
# map touchscreen
input "1046:911:Goodix_Capacitive_TouchScreen" {
map_to_output DSI-1
}
# ...
Auto backlight dimming
Create the file ~/.config/systemd/user/sway-session.target
with the following content:
[Unit]
Description=SwayWM session
BindsTo=graphical-session.target
Wants=graphical-session-pre.target
After=graphical-session-pre.target
Install swayidle with sudo pacman -S swayidle
, then create the file ~/.config/systemd/user/swayidle.service
with the following content:
[Unit]
Description=Swayidle
BindsTo=sway-session.target
After=sway-session.target
[Service]
Type=simple
# default backlight to 100% on start-up
ExecStartPre=brightnessctl --quiet --device=intel_backlight set 100
# auto dim backlight to 15% after idling for 60 secs
ExecStart=swayidle -w \
timeout 3 ':' \
resume 'brightnessctl --quiet --device=intel_backlight set 100 && swaymsg "output DSI-1 power on"' \
timeout 60 'brightnessctl --quiet --device=intel_backlight set 15' \
resume 'brightnessctl --quiet --device=intel_backlight set 100'
Restart=on-failure
RestartSec=5
TimeoutStopSec=10
[Install]
WantedBy=sway-session.target
Then execute systemctl --user daemon-reload && systemctl --user enable --now sway-session.target swayidle.service
to make it run at startup.
The first rule (timeout 3 ':' ...
) is for reactivating the screen and resuming the backlight after touching the screen when the screen had been turned off.
Adjust the values in of second rule to your liking, the one above is for dimming it to 15% after idling for 60 seconds.
And better to disable the systemd-backlight service with sudo systemctl mask systemd-backlight@backlight\:intel_backlight.service
, to prevent it from interfering.
Virtual keyboard
I haven't found a good virtual keyboard for Sway (Wayland) yet. If you have any suggestions, please share!
You can use the ydotool utility to simulate key presses and type texts, over SSH.
Install it with sudo pacman -S ydotool
, then execute systemctl --user daemon-reload && systemctl --user enable --now ydotool.service
to make it run at startup.
Check its readme on GitHub for usage and examples.
Hide mouse cursor
Edit the Sway config file and add the following content:
# ...
# hide cursor
seat seat0 {
hide_cursor 100
}
# ...
Sound
ℹ️ Note
WORK IN PROGRESS
The contents of this section (especially the files) might be changing frequently, as we are still working on it.
ℹ️ Note
Currently only the speakers are fixed, the microphones are still not working yet.
The built-in speaker amplifier is not enabled correctly by the driver for sound card RT5672, we need to set the GPIO 5 and 7 on gpiochip1 to logical HIGH.
Technical details
The amplifier IC Realtek ALC1304 is compatible with the TI TPA313xD2.
The GPIO 5 on gpiochip1 controls the logic level on the amp's pin 29 (SDZ
), by setting it to HIGH, the pin will be pulled to HIGH, enabling the amplifier.
Pin 29
SDZ
: Shutdown logic input for audio amp (LOW = outputs Hi-Z, HIGH = outputs enabled).
The GPIO 7 on gpiochip1 controls the amp's pin 7 (MUTE
), by setting it to HIGH, the pin will be pulled to LOW, enabling the output.
Pin 7
MUTE
: Mute signal for fast disable/enable of outputs: HIGH = outputs OFF (high-Z), LOW = outputs ON.
Execute sudo pacman -S alsa-utils alsa-ucm-conf libgpiod
to install the necessary stuff, then create the file /etc/systemd/system/fix-sound.service
with the following content:
[Unit]
Description=Fix sound
[Service]
Type=simple
ExecStart=gpioset -c 1 5=1 7=1
[Install]
WantedBy=multi-user.target
Execute sudo systemctl daemon-reload && sudo systemctl enable --now fix-sound.service
to make it run at startup.
Edit the Sway config file and add the following content:
# ...
# fix sound
exec alsaucm --card cht-bsw-rt5672 set _verb HiFi set _enadev Headphones
# ...
Improve performance and reduce eMMC wearing
CPU frequency
Add the kernel parameter cpufreq.default_governor=performance
to the boot loader configuration file:
- for systemd-boot, edit
/boot/loader/entries/arch.conf
and add it to the end of theoptions
line. - for GRUB, edit
/etc/default/grub
and add it to the end of theGRUB_CMDLINE_LINUX_DEFAULT
line (inside quotes). - for other boot loaders, refer to their documentation.
Then execute sudo mkinitcpio -P
to regenerate the initramfs, and sudo grub-mkconfig -o /boot/grub/grub.cfg
for GRUB.
Create the file /etc/systemd/system/set-energy-perf-bias.service
with the following content:
[Unit]
Description=Set ENERGY_PERF_BIAS
[Service]
Type=oneshot
ExecStart=sh -c 'for f in /sys/devices/system/cpu/cpu*/power/energy_perf_bias; do echo 0 > "$f"; done'
[Install]
WantedBy=multi-user.target
Execute sudo systemctl daemon-reload && sudo systemctl enable --now set-energy-perf-bias.service
to make it run at startup.
Logging
Edit the file /etc/systemd/journald.conf
to change the values in section [Journal]
as follows:
Storage=volatile
Compress=yes
SystemMaxUse=10M
ForwardToSyslog=no
ForwardToKMsg=no
ForwardToConsole=no
MaxLevelStore=notice
MaxLevelSyslog=notice
MaxLevelKMsg=notice
MaxLevelConsole=info
Home Assistant dashboard
Create the file ~/.config/systemd/user/hass-dashboard.service
with the following content:
[Unit]
Description=HASS dashboard
BindsTo=sway-session.target
After=sway-session.target
[Service]
Environment=HASS_DASHBOARD_URL=https://your.hass.url
Type=simple
ExecStart=chromium \
--ozone-platform=wayland \
--no-default-browser-check \
--no-first-run \
--disable-crash-reporter \
--disable-breakpad \
--disable-search-engine-choice-screen \
--webview-disable-safebrowsing-support \
--process-per-site \
--disk-cache-dir="/tmp/chromium-cache" \
--kiosk \
--hide-scrollbars \
--autoplay-policy=no-user-gesture-required \
"${HASS_DASHBOARD_URL}"
Restart=on-failure
RestartSec=5
TimeoutStopSec=10
CPUAccounting=yes
BlockIOAccounting=yes
MemoryAccounting=yes
MemoryHigh=1.2G
MemoryMax=1.2G
MemorySwapMax=0
[Install]
WantedBy=sway-session.target
Then execute systemctl --user daemon-reload && systemctl --user enable --now hass-dashboard.service
to make it run at startup.
If you prefer Firefox, replace the ExecStart
line with:
ExecStart=firefox -kiosk -url "${HASS_DASHBOARD_URL}"
Based on my testing, Chromium consumes less memory, is more responsive and stable than Firefox on this device, and has support for hardware acceleration (useful for viewing camera streams). You can also try ungoogled-chromium.
Control backlight from Home Assistant
Execute the command python3 -m venv ~/panel-controller
to create a Python virtual environment, then execute sudo pacman -S gtk4 gtk4-layer-shell && ~/panel-controller/bin/pip install Flask==3.1.1 i3ipc==2.2.1 PyGObject==3.52.3 apscheduler==3.11.0
to install the required dependencies.
Then create the file ~/panel-controller/app.py
with the following content:
Python script app.py
import logging
import os
import threading
from colorsys import hsv_to_rgb
from ctypes import CDLL
CDLL('libgtk4-layer-shell.so')
from functools import wraps
import gpiod
from apscheduler.schedulers.background import BackgroundScheduler
from flask import Flask, request
from i3ipc import Connection as SwayIPC
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Gtk4LayerShell', '1.0')
from gi.repository import Gtk, GLib
from gi.repository import Gtk4LayerShell as LayerShell
APP_ID = 'io.zry.panel-controller'
def auth_required(f):
"""Authentication decorator for endpoints"""
@wraps(f)
def decorator(*args, **kwargs):
token = server.config.get('TOKEN', '')
if token != '' and request.headers.get('Authorization', '') != f'Bearer {token}':
return 'Unauthorized', 401
return f(*args, **kwargs)
return decorator
# HTTP API server
server = Flask(__name__)
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
@server.route('/display/state', methods=['GET'])
@auth_required
def get_display_state():
"""GET endpoint to get display state over Sway IPC"""
try:
ipc = SwayIPC()
outputs = ipc.get_outputs()
for o in outputs:
if o.name == 'DSI-1':
if o.dpms:
return 'ON', 200
else:
return 'OFF', 200
raise ValueError('Output not found')
except Exception as e:
return f'Failed to get display state: {e}', 500
@server.route('/display/state', methods=['POST'])
@auth_required
def set_display_state():
"""POST endpoint to set display state"""
try:
state = request.get_data(as_text=True).strip().upper()
if not state:
raise ValueError('Invalid state: empty')
if state not in ['ON', 'OFF']:
raise ValueError('Invalid state: must be "ON" or "OFF"')
try:
ipc = SwayIPC()
if state == 'ON':
result = ipc.command('output DSI-1 power on')
else:
result = ipc.command('output DSI-1 power off')
if result and result[0].success:
return state, 200
else:
error_msg = result[0].error if result and result[0].error else 'Unknown error'
raise Exception(f'IPC command error: {error_msg}')
except Exception as e:
return f'Failed to set display state: {e}', 500
except Exception as e:
return str(e), 400
class ScreensaverWindow(Gtk.Window):
def __init__(self, app, **kwargs):
super().__init__(**kwargs)
self.app = app
self.set_default_size(1280, 800)
LayerShell.init_for_window(self)
LayerShell.set_layer(self, LayerShell.Layer.OVERLAY)
LayerShell.set_anchor(self, LayerShell.Edge.LEFT, True)
LayerShell.set_anchor(self, LayerShell.Edge.TOP, True)
self.hue = 0
self.drawing_area = Gtk.DrawingArea()
self.drawing_area.set_draw_func(self.on_draw)
self.set_child(self.drawing_area)
click = Gtk.GestureClick.new()
click.connect('pressed', lambda *args: self.close()) # close on click
self.add_controller(click)
GLib.timeout_add(15, self.update_color)
def on_draw(self, area, ctx, width, height):
r, g, b = hsv_to_rgb(self.hue / 360.0, 1.0, 1.0)
ctx.set_source_rgb(r, g, b)
ctx.paint()
def update_color(self):
self.hue += 1
if self.hue > 360:
self.close()
return False
self.drawing_area.queue_draw()
return True
class ScreensaverApp(Gtk.Application):
def __init__(self, enabled: bool = True):
super().__init__(application_id=APP_ID)
self.connect('activate', self.on_activate)
self.enabled = enabled
self.scheduler = None
self.current_window = None
def show_screensaver_window(self):
def show_window():
if self.current_window:
self.current_window.close()
self.current_window = ScreensaverWindow(self, application=self)
self.current_window.present()
GLib.idle_add(show_window)
def on_activate(self, app):
self.scheduler = BackgroundScheduler()
if self.enabled:
self.scheduler.add_job(
func=self.show_screensaver_window,
trigger='cron',
hour='*',
)
self.scheduler.start()
self.hold()
def run_api_server(host: str, port: int, token: str):
"""Run the Flask API server"""
server.config['TOKEN'] = token
server.run(host=host, port=port, debug=False, use_reloader=False)
if __name__ == '__main__':
host = os.getenv('HOST', '0.0.0.0')
port = os.getenv('PORT', 8080)
token = os.getenv('TOKEN', '')
# start API server in a separate thread
server_thread = threading.Thread(target=run_api_server, args=(host, port, token,), daemon=True)
server_thread.start()
print(f'HTTP API server started on http://{host}:{port}')
# start GTK application in the main thread
screensaver_enabled = os.getenv('SCREENSAVER_ENABLED', '1') == '1'
gtk_app = ScreensaverApp(screensaver_enabled)
gtk_app.run(None)
Create the file ~/.config/systemd/user/panel-controller.service
with the following content:
[Unit]
Description=Panel controller
BindsTo=sway-session.target
After=sway.service
[Service]
Environment=TOKEN=aa83720a-0bc1-4d5b-82fc-bf27a6682aa4
Type=simple
ExecStart=%h/panel-controller/bin/python %h/panel-controller/app.py
Restart=on-failure
RestartSec=5
TimeoutStopSec=10
[Install]
WantedBy=sway-session.target
Then execute systemctl --user daemon-reload && systemctl --user enable --now panel-controller.service
to make it run at startup.
Create a RESTful Switch in your Home Assistant's YAML config like:
switch:
- platform: rest
name: Panel Display
unique_id: panel_display
resource: http://panel:8080/display/state # replace `panel` with your panel's hostname or IP address
body_on: 'ON'
body_off: 'OFF'
is_on_template: '{{ value == "ON" }}'
headers:
Authorization: Bearer aa83720a-0bc1-4d5b-82fc-bf27a6682aa4 # replace it with your secret token (after `Bearer `)
verify_ssl: false
icon: mdi:tablet-dashboard
Reload your Home Assistant instance, use Developer Tools to test the switch and sensor.
Then you can use it in Automations, e.g., turn it off when you go to sleep at night and turn it back on when you get up in the morning.
Since it will mostly be used to display a Home Assistant dashboard 24/7, it's very likely to get screen burn-in after some time, albeit having an LCD screen.
To prevent that, this Python script also periodically (every hour) flashes several colors in full screen to refresh all the pixels. You can disable this feature by adding an environment variable SCREENSAVER_ENABLED=0
in the service file like below:
# ...
[Service]
Environment=TOKEN=aa83720a-0bc1-4d5b-82fc-bf27a6682aa4
Environment=SCREENSAVER_ENABLED=0
Type=simple
# ...
Research notes
Background
Recently while I was lurking around on Wallapop, the Spanish Craiglist, one item caught my attention:

This is Movistar Home, a smart home hub from Spain's biggest ISP, Telefónica Movistar. It's basically a smart speaker with a touch screen and built-in AI assistant (called Aura), something like Amazon Echo Show and Google Nest Hub. But it's well-integrated with the other products in Movistar's ecosystem, including controlling TV, Wi-Fi, IoT devices (which I didn't find any detailed information). It can also play movies, TV series, music, and games on the device itself, but I doubt the user experience would be satisfying on that 8-inch screen.
I've always wanted to have a Home Assistant dashboard panel like everyone on /r/homeassistant with wall-mounted tablets, but I feel like something that sits on the desk would suit my use cases better, also I don't want to install something possibly permanent on the wall.
After searching around, I couldn't find any useful information about hacking this device. A video published on YouTube gave a glance of its virtual keyboard, which is obviously a Gboard on Android. And according to the official website it has a CPU from Intel, which should be one of the Atom series widely used in Android & Windows tablets, so it seems like it's basically a tablet running Android-x86, not something too bizarre.

Tempted by the cheap price, I bought one for only 15 euros from a nice dude, including that wireless handset.
Trying to break out
When I first powered it up, it asks me to connect to a Wi-Fi, but I couldn't find mine in the list, and it specifically said "Connect you to a Movistar Wi-Fi".

I tried to setup an AP with SSID and MAC address copied from the ones in the list, but it never showed up, even after reboot.
Since I couldn't find a way to continue, I had to dissasemble it:

The top green PCB has the four microphones, mute button and speaker volume buttons; the central blue PCB is the motherboard, with Wi-Fi & Bluetooth module in the upper right corner, speaker amplifier circuit in the bottom right corner, and CPU + RAM + eMMC + other stuff all inside an EMI shield under that big heat sink; the bottom green PCB has the reset button, 12V DC power jack and power button.
On the motherboard, there are two unpopulated 6-pin connector pads which I don't know what they are; a serial port (the 3 pads above the 6-pin connector on the left edge) with output of boot logs.
What really seemed useful was the unpopulated micro USB port pad on the left edge:

I soldered a cable with a standard USB female connector to it, and shorted the fourth pin (or the ID
pad above) to ground, which made the device as OTG host.
After that, I connected a USB keyboard and tried to escape from the kiosk mode, but the only useful finding was bringing up the browser with Win
+ B
, although it's unable to access any website since not connected to Wi-Fi.
Then I connected a USB hub with a USB ethernet adapter, now it's connected to the Internet:

I was able to download APKs but couldn't find a way to install them. I could read local files using the file://
protocol (e.g. file:///system/build.prop
) but when I try to open an APK file with file:///sdcard/download/xxx.apk
it only gives me a toast saying that such files can only be accessed with HTTP(S) protocol.
easycwmp
I scanned the open ports on the device, found a HTTP service of easycwmp
listening on port 7547, but it's protected with basic authentication. Later in the flash dump I found its credentials should be easycwmp/easycwmp
, but it won't boot into the original Android-x86 after I wrote the dump back. easycwmp is a TR-069 client, which usually should only appear in ISP-provided modems and routers, my guess here is that it's for the OS's OTA updates. That means it might be possible to take advantage of this service and flash custom firmware (Linux) without having to disassemble the device and solder USB cable. But unfortunately, I no longer have one with the original OS to do research on it.
So far nothing useful, so I decided to try to get into the BIOS setup which I believe it should have one since it's x86.
Into the BIOS
I tried pressing several different keys on startup, F12
got me a black screen with a text DNX FASTBOOT MODE...
, and F2
got me into the BIOS (well actually it's UEFI-only):

From there, I was able to boot Linux normally from a USB drive:

For Windows, it always gives me a BSOD with stop code ACPI_BIOS_ERROR
whatever version I try (Win7 & Win10 installer, WinPE and WindowsToGo). But anyway I don't think it's a good idea running Windows on that poor 2 GB RAM.

4 Comments
juan · 2022-05-02 at 18:09
Hola , he seguido el tutorial y me ha funcionado perfectamente
Seguire mirando de vez en cuando por si hay actualizaciones.
Ahora gracias a ti tambien tengo una dashboard para mi home assintant
Gracias.
zry98 · 2022-05-02 at 20:56
Una pregunta, la placa base del tuyo era la misma que la mía? He visto a otros con placas diferentes (fabricadas por una otra empresa en 2020).
juan · 2022-05-03 at 07:11
Es igual al tuyo . Tambien comprado por Wallapop ha alguien que lo tuvo bastante tiempo en la caja sin usar.
zry98 · 2022-05-03 at 13:53
Gracias!