framesmith 0.1.0

A Rust library for controlling Samsung Frame TVs over the local network
Documentation

framesmith

Control Samsung Frame TVs over your local network — no cloud, no Samsung account.

framesmith is an async Rust library for managing artwork, display settings, slideshows, and more on Samsung's The Frame TV lineup. It communicates directly with the TV using WebSocket and HTTP protocols over your LAN.

Features

  • Discover Frame TVs on your network via SSDP multicast
  • Upload, select, and delete artwork (JPEG and PNG)
  • Art Mode — enable/disable the Frame's signature display mode
  • Slideshows — cycle through artwork with configurable duration, shuffle, and category
  • Mattes & filters — apply decorative borders and photo filters
  • Display settings — brightness, color temperature, auto-brightness, rotation
  • Motion sensor — configure the idle timer and sensitivity
  • Remote control — simulate 40+ button presses (power, volume, navigation, HDMI input, etc.)
  • Authentication — persistent token-based auth with pluggable storage
  • No native TLS dependency — uses rustls under the hood

Quick Start

Add framesmith to your Cargo.toml:

[dependencies]
framesmith = "0.1.0"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

Connect and Upload Art

use std::net::Ipv4Addr;
use std::path::Path;
use framesmith::{FrameTv, FileAuthTokenStore, ArtImage};

#[tokio::main]
async fn main() -> Result<(), framesmith::Error> {
    let tv = FrameTv::connection_builder(Ipv4Addr::new(192, 168, 1, 100).into())
        .auth_token_store(FileAuthTokenStore::new(Path::new("tv_token.txt")))
        .connect()
        .await?;

    let image = ArtImage::builder()
        .load_jpeg(Path::new("artwork.jpg"))?
        .build()?;
    tv.upload_and_select_art_image(image).await?;
    tv.enable_artmode().await?;

    Ok(())
}

Discover TVs

use framesmith::discover;

let tvs = discover().await?;
for tv in &tvs {
    println!("{} at {} ({})", tv.name(), tv.ip(), tv.model());
}

Manage Art

// List all uploaded images
let images = tv.get_uploaded_art_images().await?;

// Get info for the currently displayed image
let current = tv.get_selected_art_image().await?;
println!("{}x{}", current.width(), current.height());

// Get info for a specific image by content ID
let info = tv.get_art_image_info("MY_F0001").await?;

// Select an image for display
tv.select_art_image_by_id("MY_F0001").await?;

// Delete images
tv.delete_uploaded_art_images(&["MY_F0001", "MY_F0002"]).await?;

// Download a thumbnail
let thumb = tv.get_art_image_thumbnail("MY_F0001").await?;
std::fs::write("thumb.jpg", thumb.as_bytes())?;

Center Small Images on a Canvas

use framesmith::{ArtImage, Canvas};

let image = ArtImage::builder()
    .load_png(Path::new("small.png"))?
    .center_image(3840, 2160, Canvas::black())
    .build()?;
tv.upload_art_image(image).await?;

Display Settings

use framesmith::{DisplayBrightness, DisplayColorTemp};

tv.set_display_brightness(DisplayBrightness::L7).await?;
tv.set_display_color_temp(DisplayColorTemp::Plus2).await?;
tv.enable_auto_brightness().await?;

Slideshows

use framesmith::{SlideshowConfig, SlideshowCategory};
use std::time::Duration;

tv.enable_slideshow(Some(SlideshowConfig {
    art_image_duration: Duration::from_secs(300),
    shuffle: true,
    category: SlideshowCategory::Favorites,
})).await?;

Remote Control

use framesmith::RemoteControlButton;

tv.press_remote_control_button(RemoteControlButton::PowerOff).await?;
tv.press_remote_control_button(RemoteControlButton::Hdmi1).await?;

Custom Auth Token Storage

The default FileAuthTokenStore saves tokens to a file, but you can implement the AuthTokenStore trait to store tokens however you like (database, keychain, environment variable, etc.).

Network Requirements

  • Your machine and the TV must be on the same local network (same subnet, or use SNAT masquerading for cross-VLAN setups)
  • The TV communicates over port 8001 (HTTP) and port 8002 (WSS)
  • The TV must be powered on or in Art Mode / standby with network standby enabled
  • On first connection, someone must physically approve the pairing prompt on the TV screen

Error Handling

All operations return Result<T, framesmith::Error>. Error variants include ConnectionFailed, Unauthorized, TvError, Timeout, IncorrectImageSize, and wrappers for WebSocket, HTTP, JSON, I/O, and image processing errors.

CLI

Looking for a command-line tool? See framesmith-cli.

License

MIT