Plan format¶
The plan is one JSON object stored in .storage/fns_floorplan. The editor reads and writes it; you can also read it with fns_floorplan/plan/get and replace it with fns_floorplan/plan/save (Websocket API).
- Coordinates are metres,
xto the right,zdown. revis the revision counter, managed by the integration; do not set it by hand.- Rooms and items of the first floor carry no
level.
Top level¶
| Key | Type | Default | Description |
|---|---|---|---|
rev |
integer | 0 | Revision, increased by every save |
levels |
list | one floor | Floors [{id, name}]. Without it the plan has one floor |
rooms |
list | [] |
Rooms |
openings |
list | [] |
Doors and windows |
furniture |
list | [] |
Furniture and lights |
sensors |
list | [] |
Binary sensors |
devices |
list | [] |
Appliances |
texts |
list | [] |
Text items |
labels |
object | {} |
{room_id: [x, z]}: manual position of a room label |
outdoor |
string | none | Id of the room whose temperature is shown as the outside temperature |
backgrounds |
object | {} |
Tracing image per floor {level_id: {url, left, top, width, opacity}}, editor only |
vacuum |
object | none | Legacy: entity, room_sensor; converted to a dock by the editor |
style |
object | {} |
Plan colours from the editor's Look tab, see Look |
Style¶
Plan colours from the editor's Look tab. Every key is optional and holds "#rrggbb"; an unset key keeps its default.
| Key | What it colours | Default |
|---|---|---|
wall_day / wall_night |
Walls (day / night) | theme primary colour |
floor_day / floor_night |
Floor (day / night) | white / dark blue |
text_day / text_night |
Room labels and text (day / night) | dark / light |
accent |
Accent of buttons and highlights | theme primary colour |
lamp |
A light that reports no colour of its own | the theme colour of an active light, paled |
open |
Open door or window, unlocked lock, pending alarm | the theme colour of an active binary sensor, else orange |
alarm |
Triggered alarm | the theme colour of a triggered alarm, else red |
blind |
Blinds | the theme colour of a closed cover, else the accent |
cold / hot |
Cold and warm temperature in room labels | blue / orange |
Levels¶
| Key | Type | Description |
|---|---|---|
id |
string | Id of the floor |
name |
string | Name shown in tabs |
Rooms, furniture, devices, sensors and texts take level with the floor id; without it they belong to the first floor. Openings follow their room.
Rooms¶
| Key | Type | Default | Description |
|---|---|---|---|
id |
string | Unique id | |
name |
string | Name | |
points |
list of [x, z] |
Corners of the polygon, at least 3 | |
level |
string | first floor | Floor id |
icon |
string | none | mdi: icon for the room panel header |
temperature |
entity | null | Temperature sensor |
humidity |
entity | null | Humidity sensor |
sheet_extra |
list of entities | [] |
Extra entities for the room panel; an entry may be a template that renders entity ids (Rooms) |
label_info |
list | temperature, humidity |
What the label shows: temperature, humidity, entity ids or templates |
label_name |
boolean | true |
false hides the name |
label_hidden |
boolean | false |
true hides the label |
label_rotation |
number | 0 | Label rotation in degrees |
label_size |
string | m |
Label size: xs, s, m, l, xl, xxl |
rules |
list | [] |
Rules |
Openings¶
| Key | Type | Default | Description |
|---|---|---|---|
id |
string | Unique id | |
room_id |
string | The room whose wall carries it | |
edge |
integer | Index of the wall: from points[edge] to the next point |
|
offset |
number | Centre of the opening, metres from the start of the wall | |
width |
number | Width in metres | |
type |
door / window |
||
style |
string | normal | passage = only an opening (doors) |
hinge |
left / right |
Seen from inside the room | |
swing |
in / out |
||
contact |
entity | null | Contact sensor. Without it a door is ajar at 45 degrees, a window closed |
lock |
entity | null | A lock entity shown at the door |
lock_size |
size | s |
Size of the lock badge |
blind |
entity | null | A cover entity drawn along the window |
blind_side |
in / out |
in |
out = outside the wall |
blind_invert |
boolean | false |
The cover reports 100 for closed |
tap_action, double_tap_action, hold_action |
action | contact details | Actions |
sheet_hide |
boolean | false |
Leave out of the room panel |
Furniture¶
Furniture, lights and the robot dock share this list.
| Key | Type | Default | Description |
|---|---|---|---|
id |
string | Unique id | |
type |
string | Furniture type (list), light type (lamp_ceiling, lamp_pendant, lamp_panel, lamp_spot, lamp_table, lamp_wall, led_strip), or robot_vacuum |
|
x, z |
number | Centre in metres | |
rotation |
number | 0 | Degrees; 0 = right, 90 = down |
w, d |
number | Width and depth in metres | |
level |
string | first floor | Floor id |
entity |
entity | null | Light entity (lights), media player (tv_wall), vacuum (dock) |
room_light |
number / false | share | Share of the room glow of a light, 1 = 100 %, false = almost none |
beam |
number | 40 | lamp_spot: cone width in degrees |
glow_side |
1 / -1 |
all around | led_strip: shine to one side |
color |
colour | Default colour of furniture (a rule wins) | |
icon, size, layer |
Common item fields | ||
group |
string | Group id (set by the Group button) | |
room_sensor, room_map, battery |
Dock: see Robot vacuum | ||
color_on, fx, progress, progress_total |
Dock: look while cleaning | ||
rules, tap_action, double_tap_action, hold_action, sheet_hide |
Sensors¶
| Key | Type | Description |
|---|---|---|
entity |
entity | A binary sensor; motion, occupancy, presence = ripples, moisture = red pulse |
x, z |
number | Position |
layer |
integer | Order among sensors and furniture in the editor |
level |
string | Floor id |
Devices¶
| Key | Type | Default | Description |
|---|---|---|---|
id |
string | Unique id | |
kind |
string | fan, purifier, dehumidifier, dishwasher, dryer, boiler, radiator, alarm, media, aquarium, camera, fridge, fireplace, lock, generic |
|
name |
string | Name (tooltip) | |
entity |
entity | The entity | |
x, z |
number | Position | |
level |
string | first floor | Floor id |
active |
list / {"above": n} |
by kind / domain | States that count as running |
text |
string | Text under the icon, always; may be a template | |
text_on |
string | Text while running; may be a template, {left:timer.x} = time left of that entity, {left} = of the countdown |
|
label_position |
string | bottom |
Label position: bottom (default), top, left, right |
label_vertical |
bool | false |
Turns the label by 90 degrees (reads bottom to top) |
color, color_on |
colour | state colour | Idle / running colour |
fx |
string | by kind | Ring animation |
pipe |
list | Radiator only (also furniture type: radiator, which flows by a rule's animate): corners [[x, z], …] of its heating pipe between the floor's boiler and the radiator ([] = straight). Flows while the boiler and the radiator both run, in the wave colour |
|
progress, progress_total |
entity / minutes | Countdown source | |
cover |
boolean | true |
media: false turns off the cover art |
battery |
entity | device battery | Vacuum devices |
icon, size, layer |
Common item fields | ||
rules, tap_action, double_tap_action, hold_action, sheet_hide |
Texts¶
| Key | Type | Default | Description |
|---|---|---|---|
id |
string | Unique id | |
entity |
entity | Its state is shown | |
text |
string | Fixed text or a {{ }} template |
|
x, z |
number | Position | |
rotation |
number | 0 | Degrees |
size |
size | m |
xs to xxl |
color |
colour | Text colour | |
background |
string | badge style | none = no background |
level |
string | first floor | Floor id |
rules, actions |
Common item fields¶
| Key | Type | Description |
|---|---|---|
icon |
string | Any mdi: icon; none for no icon |
size |
string | xs, s, m, l, xl, xxl |
layer |
integer | Stacking order within the kind |
sheet_hide |
boolean | Leave out of the room panel |
tap_action, double_tap_action, hold_action |
object | action: toggle, more-info, perform-action (perform_action, data), navigate (navigation_path), url (url_path), none |
Rules¶
An ordered list on rooms, furniture, devices, texts and lights. Per output field the first matching rule wins; see Rules.
| Key | Type | Description |
|---|---|---|
if |
list | Conditions (all must hold); a rule without if is the default |
color, glow, animate, wave, text, tint, opacity, hide, icon, background |
Outputs | |
fx, progress, progress_total |
Ring animation and countdown |
A condition is one of:
| Form | Description |
|---|---|
{entity, attribute?, state} |
state may be a list |
{entity, attribute?, state_not} |
Negation, may be a list |
{entity, attribute?, above} / below |
Numeric comparison |
{template: "{{ ... }}"} |
Jinja, true for true, on, yes, 1, non-zero numbers |
{any: [conditions]} |
OR |
Complete example¶
A small flat with three rooms.
{
"levels": [{"id": "0", "name": "Ground floor"}],
"outdoor": "balcony",
"rooms": [
{"id": "living_room", "name": "Living room", "icon": "mdi:sofa",
"points": [[0, 0], [5, 0], [5, 4], [0, 4]],
"temperature": "sensor.living_room_temperature", "humidity": "sensor.living_room_humidity",
"sheet_extra": ["media_player.tv"]},
{"id": "kitchen", "name": "Kitchen",
"points": [[5, 0], [8, 0], [8, 4], [5, 4]],
"temperature": "sensor.kitchen_temperature",
"rules": [{"if": [{"entity": "binary_sensor.kitchen_leak", "state": "on"}], "tint": "red", "opacity": 0.3}]},
{"id": "bedroom", "name": "Bedroom",
"points": [[0, 4], [5, 4], [5, 7], [0, 7]],
"temperature": "sensor.bedroom_temperature"}
],
"openings": [
{"id": "d_front", "room_id": "living_room", "edge": 3, "offset": 2.0, "width": 0.9, "type": "door",
"hinge": "left", "swing": "in", "contact": "binary_sensor.front_door", "lock": "lock.front_door"},
{"id": "d_kitchen", "room_id": "living_room", "edge": 1, "offset": 2.0, "width": 0.8, "type": "door",
"style": "passage"},
{"id": "d_bedroom", "room_id": "living_room", "edge": 2, "offset": 2.5, "width": 0.8, "type": "door",
"hinge": "right", "swing": "in"},
{"id": "w_living", "room_id": "living_room", "edge": 0, "offset": 2.5, "width": 1.6, "type": "window",
"contact": "binary_sensor.living_room_window", "blind": "cover.living_room_blind"}
],
"furniture": [
{"id": "f_sofa", "type": "sofa", "x": 2.5, "z": 3.1, "rotation": 0, "w": 2.0, "d": 0.9},
{"id": "f_tv", "type": "tv_wall", "x": 2.5, "z": 0.1, "rotation": 0, "w": 1.4, "d": 0.1, "entity": "media_player.tv"},
{"id": "f_bed", "type": "bed", "x": 2.5, "z": 5.6, "rotation": 0, "w": 1.8, "d": 2.0},
{"id": "l_living", "type": "lamp_ceiling", "x": 2.5, "z": 2.0, "entity": "light.living_room", "room_light": 1},
{"id": "l_strip", "type": "led_strip", "x": 2.5, "z": 3.9, "w": 3.0, "d": 0.05, "entity": "light.living_room_strip"},
{"id": "dock", "type": "robot_vacuum", "x": 0.4, "z": 3.4, "entity": "vacuum.robot",
"room_sensor": "sensor.robot_current_room", "room_map": {"Living room": "living_room"}}
],
"sensors": [
{"id": "s_motion", "entity": "binary_sensor.living_room_motion", "x": 4.6, "z": 0.4}
],
"devices": [
{"id": "dev_radiator", "kind": "radiator", "entity": "climate.living_room", "x": 4.7, "z": 2.0},
{"id": "dev_dishwasher", "kind": "dishwasher", "name": "Dishwasher", "entity": "sensor.dishwasher_state",
"x": 7.4, "z": 0.8, "active": ["run"], "text_on": "{{ states('sensor.dishwasher_remaining') }} min"}
],
"texts": [
{"id": "t_out", "text": "{{ states('sensor.outdoor_temperature') }} °C", "x": 6.5, "z": 5.0, "background": "none"}
],
"labels": {"kitchen": [6.5, 3.4]}
}