Skip to content
Stand with Ukraine flag

Alarms calendar

  • Widget
  • 82 installs
  • v1.0.0
  • Jul 29, 2026
  • MIT license
  • v4.2+
Alarms calendar

Displays alarms from any device, asset or entity alias on a month calendar, colour-coded by severity, with acknowledged and cleared states visible at a glance. Click a day to drill into its timeline; click an alarm to read its details and acknowledge or clear it, or to fire a widget action of your choosing. Busy days collapse into a cluster link. Calendar navigation drives the timewindow, so browsing month to month fetches the right alarms. Fonts and colours are configurable, with no scripting required.

Widget Type
  • Alarm
Category
  • Cards & Info
  • Tables & Lists
  • Gauges & Indicators

Alarms calendar

Places alarms on a month grid by the time each one started, coloured by severity. Click a day to drill into its hour-by-hour timeline; click an alarm to read its details and acknowledge or clear it without leaving the dashboard.

Features

  • Month grid with alarms on the day they started, ordered by severity within each day
  • Two chip styles: soft (tinted fill with a coloured spine) or solid (full severity fill)
  • Unacknowledged, acknowledged and cleared states readable at a glance, with no extra icons
  • Point-in-time or duration-span rendering — a span alarm draws a bar from start to clear
  • Details popover with Acknowledge and Clear, or a custom widget action instead
  • Drill into any day, with a breadcrumb back to the month you came from
  • Crowded days collapse into +N more alarms, which opens that day
  • Legend showing only the severities actually present, plus an alarm counter
  • Calendar navigation drives the time window, so browsing months fetches the right alarms
  • Fonts and colours configurable from the settings form, with no scripting

Data keys

None. This is an alarm-type widget: it reads whole alarm objects from the alarm subscription rather than telemetry or attribute keys, so the data key list stays empty and any keys you add are ignored.

These alarm fields are read, and all of them come from the platform automatically:

FieldTypeUsed for
startTs (falls back to createdTime)numberPosition on the calendar
endTsnumberEnd of the bar in duration-span mode; shown as Last update
clearTs, ackTsnumberState, and the timestamps in the popover
cleared, acknowledged, statusboolean / boolean / stringState, whichever shape your version reports
typestringChip label
severitystringChip colour
originator, originatorName, originatorLabelentity id / string / stringPopover, optional chip prefix, and the entity passed to actions
assigneeobjectPopover
detailsobject or stringPopover

Alarms are positioned by start time — when the condition first became true, not when the platform processed it. The two differ when a device reports backdated telemetry, and the calendar shows the event time.

Setup

  1. Add the widget to a dashboard and pick an alarm source: a device, asset, or entity alias.
  2. Set the Filter — status, severity, type, assignee, propagated alarms. The widget uses it as configured and has no duplicate controls of its own; filtering happens server-side, so narrowing it reduces what is fetched, not just what is drawn.
  3. Give the widget its own time window if the dashboard hosts other widgets — see below.

Time window

An alarm subscription only returns alarms whose start time falls inside a time window, and that window knows nothing about which month you are looking at. So the calendar drives it: every month step, year step, month or year pick, drill-down, back, and Today pushes the visible range as the new window, and so does the initial load. Rapid clicks collapse into a single query.

Whether that range stays on the widget or moves the whole dashboard is the widget’s own use dashboard time window checkbox — the platform’s existing switch, which this widget deliberately does not override. On a shared dashboard, give the calendar its own time window so navigating it does not drag other widgets along.

The range covers every visible cell, so the greyed leading and trailing days of a month are populated too instead of looking falsely empty.

One consequence worth knowing: an alarm that started before the visible month will not appear even though it was active throughout it. This is most noticeable in duration-span mode, where you might expect a bar across the whole grid.

Severity colours

SeverityDefaultAppearance
Critical#d12730red
Major#ff8300orange
Minor#ffca3damber
Warning#abab00olive
Indeterminate#00838fteal

Each is configurable. In soft chip style the colour becomes a 13% tint for the fill plus a solid 3px spine; in solid style it fills the chip and the text switches between dark and white based on the background’s luminance, so a light severity like Minor stays readable.

State layers on top of severity, using the same colour rather than new ones:

StateChip
Unacknowledgedfull-strength spine
Acknowledgedspine faded to 40%
Clearedwhole chip dimmed, title struck through

Alarm details

Clicking an alarm opens a popover anchored to it, listing severity, type, originator, status, every timestamp the alarm carries, assignee, and the details payload as formatted JSON. It flips above the alarm when there is no room below and stays inside the widget, so it never spills over the rest of the dashboard. Close it with the ✕, a click outside, Esc, or by navigating the calendar.

The footer carries Acknowledge and Clear. Each button disappears once its state is reached, both disable while a request is in flight, and a failure is reported inline — for example Clear failed (403) — leaving the alarm untouched so you can retry. On success the chip in the grid restyles immediately rather than waiting for the next poll.

For read-only audiences, turn Allow acknowledge / clear from the details popover off; the popover then shows details only. Note the widget cannot see a user’s permissions, so the buttons are hidden by this setting rather than automatically.

Actions

Two action sources appear in the widget’s Actions tab. Attach any action type: navigate to a dashboard state, open a custom dialog, run custom JavaScript, or trigger a mobile action.

SourceFires onEntity passedExtra parameters
Alarm clickAn alarm chip, when Clicking an alarm is set to trigger the actionthe alarm’s originatoralarm, alarmId, alarmType, alarmSeverity, alarmStatus, alarmStartTs, alarmDetails
Day clickEmpty space in a day celldate, dateTs, allDay

Because the originator is passed as the entity, Navigate to new dashboard state works with no extra wiring — the target state receives the device or asset that raised the alarm. Inside a custom action the rest is on additionalParams, for example additionalParams.alarm.details.

Clicking an alarm chooses between the details popover and the action; they are deliberately exclusive, because a popover that flashed up before a navigation action took over would be noise. If no action is attached to a source, clicking does nothing — no error.

Configuration

Calendar

SettingDefaultDescription
First day of weekMondayMonday, Sunday, or Saturday
24-hour clockonOff switches times to AM/PM

Alarms

SettingDefaultDescription
Alarm renderingPoint in timePoint places the chip at the start; Duration span draws a bar from start to clear, or to now if still active
Prefix title with originator nameoffRenders Generator 03 · lowFuel instead of lowFuel
Clicking an alarmShow alarm detailsOpen the details popover, or fire the Alarm click widget action instead
Allow acknowledge / clear from the details popoveronOff leaves the popover read-only
Alarms shown per day before clustering3Overflow collapses into +N more alarms. Set to 0 to fit as many as the row height allows
Alarms page size1024Upper bound on alarms fetched per range

Style

SettingDefaultDescription
Alarm chip styleSoftSoft (tinted fill, coloured spine) or Solid (full severity fill)
Alarm textinheritedSize, weight, style, line height
Day number text / colour#5f6368Font and colour of the date in each cell
Weekday header text / colour#5f6368Font and colour of the Mon–Sun strip
Cell background#ffffffGrid cell fill
Grid line#e4e6eaGrid border colour
Show severity legendonLegend at the top right, listing only severities present
Show alarm counteronReads 12 alarms · 5 active

Accent states — the current day, hover highlights, focus rings, the now indicator, the cluster link — are not configurable on purpose: they derive from the platform’s primary colour so the widget matches the surrounding theme.

The widget declares no font family anywhere. It inherits whichever face the instance uses, which is Roboto on a stock install and the correct face on a white-labeled one. The only exception is the details JSON block, which asks for the generic monospace so keys and values line up.

Requirements

Community and Professional editions both work; nothing here uses PE-only features. Rendering is done by FullCalendar 6, loaded from a CDN and declared in the widget’s resources:

https://cdn.jsdelivr.net/npm/fullcalendar@6.1.21/index.global.min.js
https://cdn.jsdelivr.net/npm/@fullcalendar/core@6.1.21/locales-all.global.min.js

Browsers viewing the dashboard need to reach that CDN. If your network blocks it, upload the bundle as a ThingsBoard JavaScript resource and point the widget’s resources at your copy. When the library cannot load, the widget shows the URL and a retry button rather than spinning indefinitely.

Month names follow the dashboard language automatically. Weekday names need the second resource above; without it they fall back to English. Alarm types and severity labels are not translated — types render exactly as the platform reports them.

Share Your Widget with the Community

Built a custom widget? Export it as a JSON from ThingsBoard and publish it to the IoT Hub through a simple 4-step wizard (Upload, Listing, Readme, Review & Submit). Share it with thousands of ThingsBoard developers worldwide and get featured in the catalog.