Agent DVR

Connects ioBroker to AgentDVR: auto-discovers cameras, mirrors all device values as data points, delivers real-time triggers on new recordings, and generates a responsive HTML gallery with optional search and tag filtering.

Current Release
0.5.2
Developer
ipod86
License
MIT

agent-dvr adapter for ioBroker

Connects ioBroker to AgentDVR: auto-discovers all cameras, mirrors every device property as data points, provides buttons for all common commands (record, arm, PTZ, …), delivers push-triggered gallery updates on new recordings, generates a responsive HTML gallery widget per camera, and includes a built-in live dashboard with per-camera stream selection (MJPEG, MP4/FLV with audio, or go2rtc WebRTC).

Requirements

  • ioBroker with iobroker.web adapter
  • AgentDVR ≥ 7.8.0.0 — earlier versions have a regression in the streamFile.cgi endpoint (malformed chunked encoding, wrong MIME type) that prevents recording playback in the built-in dashboard. The developer has confirmed the fix is included in 7.8.0.0.

Features

  • Auto-discovery of all AgentDVR cameras on startup (microphones excluded)
  • All device properties mirrored as data points (flattened from the API)
  • Per-device control buttons: record, snapshot, detect, arm/disarm alerts, switch on/off, object detection, schedule on/off, detector on/off, sensitivity (min/max/gain), purge, …
  • System-level buttons: arm, disarm, all on/off, reload, storage management, restart, …
  • Profile selector — writable dropdown reflecting the current AgentDVR profile (Home / Away / Night / custom)
  • Snapshot as Base64snapshot_b64 state per camera, writable via button or auto-updated every poll cycle
  • PTZ control with hold-to-move switches
  • Stream URLs per camera (snapshot, photo, MJPEG, MP4)
  • Webhook endpoint for real-time updates — call it from an AgentDVR action to trigger an immediate full poll
  • HTML recording gallery widget per camera (widget_recordings) and single-camera live tile (widget_live) — pure HTML/CSS or full JS mode with search and tag filter
  • Overview widget combining all cameras in one HTML state
  • Built-in live dashboard at http://<iobroker>:<webport>/agent-dvr.0/ — no additional app needed:
    • Per-camera stream selection: MJPEG, MP4/FLV with audio, or go2rtc WebRTC/MSE
    • Camera filter button in the header (funnel icon) — opens a per-camera checkbox popover; badge shows how many cameras are hidden; state saved in localStorage
    • Real-time motion and alert indicators (yellow / orange tile border) via Socket.io
    • Fullscreen view with PTZ overlay, record, mute, and native browser fullscreen button; header auto-hides
    • Recordings tab with grid, timeline, and event log view, search, collapsible tag filter, and video player with prev/next navigation
    • Delete recording directly from the video player modal (requires AgentDVR v7.7.8.0+)
    • Recording display settings — ⚙ gear in the select/delete bar adjusts grid column width, max recordings shown and badge visibility (persisted in localStorage)
    • Camera colors are read from AgentDVR and applied to timeline bars and recording dots
    • PTZ presets — navigate to saved presets from the PTZ overlay (requires AgentDVR v7.7.8.0+)
    • Status bar shows camera count on the live view and recording/event count on the recordings view
    • Auto-reconnect for all stream types after network interruption or tab switch
    • Fully color-themeable via adapter config

Configuration

Tab: Connection

SettingDescriptionDefault
AgentDVR IPIP address of the AgentDVR server
PortAgentDVR HTTP port8090
UsernameOptional HTTP basic auth username
PasswordOptional HTTP basic auth password
Poll interval (s)How often to fetch data from AgentDVR (5–3600)30
HTTP timeout (ms)Timeout per API request (1000–30000)8000

Tab: Features

Controls

SettingDescriptionDefault
System control buttonsCreate arm/disarm/restart/… buttons and the profile selectortrue
PTZ control buttonsCreate per-camera PTZ hold-switches (left, right, up, down, diagonals, zoom, stop, center)true
Generate stream URLsCreate URL states (snapshot, MJPEG, MP4) per cameratrue
Snapshot as Base64Auto-fetch and store the current frame as Base64 on every pollfalse

Events

SettingDescriptionDefault
Event data pointsMirror recording metadata (latest event, count, tags, …) per cameratrue

Display

SettingDescriptionDefault
Overview widgetSingle HTML state combining all camera live tilestrue

Proxy

SettingDescriptionDefault
Media proxyRoute MJPEG streams, snapshots, recording thumbnails and videos through ioBrokerfalse

Debug

SettingDescriptionDefault
Store raw API JSONWrite the full getObjects response to system.raw_getObjectsfalse

Tab: Dashboard

Default view

SettingDescriptionDefault
Default viewWhich tab opens when the dashboard loads: Live or RecordingsLive
Show offline camerasDisplay camera tiles even when the camera is offlinetrue
Max. recordings totalMaximum number of recordings shown across all cameras in the dashboard (newest first). Independent of the widget limit.200

Camera grid

SettingDescriptionDefault
ColumnsNumber of grid columns (0 = auto-fit based on tile width)0
Buttons always visibleShow record/PTZ buttons permanently instead of on hover onlyfalse
Tag-badge positionCorner where the camera name badge appears on each tilebottom-right

Stream

SettingDescriptionDefault
Refresh interval (s)How often the dashboard re-fetches camera data (10–600)60
Auto-reconnect streamsAutomatically reconnect MJPEG, MP4/FLV and go2rtc streams after an error or tab switchtrue

Color theme — 7 color pickers to match your UI:

SettingDescription
BackgroundPage/grid background color
SurfaceCamera tile background
AccentHighlight / active element color
TextPrimary text color
BorderTile border color
Online indicatorColor of the online status dot
Offline indicatorColor of the offline status dot

Stream assignment

Here you assign a stream source to each camera individually. The dropdown shows all cameras discovered from AgentDVR (microphones are excluded).

OptionDescription
MJPEG (AgentDVR)Classic MJPEG stream served by AgentDVR — lowest latency, no audio
MP4 / FLV with audio (AgentDVR)FLV stream proxied through ioBroker using flv.js — includes audio, correct aspect ratio
stream name (go2rtc)WebRTC/MSE stream from go2rtc — smooth, low latency, audio support

The go2rtc stream names are fetched automatically from the go2rtc server when the admin UI is open. If the browser cannot reach go2rtc directly (e.g. mixed-content on HTTPS), the adapter fetches them on the server side as a fallback.

go2rtc URL (only visible when at least one camera uses a go2rtc stream)

SettingDescriptionExample
go2rtc URLBase URL of your go2rtc instancehttp://192.168.1.10:1984

Note: go2rtc must already have the streams configured. The adapter only reads the stream list and proxies the WebSocket — it does not configure go2rtc.

Tab: Widget (gallery widget per camera)

General

SettingDescriptionDefault
Enable widgetGenerate an HTML gallery widget per cameratrue
Widget modeNo JS — pure HTML/CSS, embed anywhere; JS — full interactivity with search and tag filterNo JS

Layout

SettingDescriptionDefault
Max. entriesMaximum number of recordings shown in the widget20
Min. column width (px)Minimum width of each thumbnail column150
Max. modal width (px)Maximum width of the video playback modal900

Tags

SettingDescriptionDefault
Show tagsDisplay recording tags on each thumbnailtrue
Tag-badge positionCorner where tags appear on the thumbnailbottom-left

Filter

SettingDescriptionDefault
Newest firstSort recordings with the latest at the toptrue
Show searchShow a text search field in JS modefalse
Compact modeDenser layout with smaller thumbnailsfalse
Default tagPre-select this tag filter when the widget loads
Thumbnail sizeSmall / Medium / LargeMedium

Player

SettingDescriptionDefault
Live aspect ratioAspect ratio for the live stream preview, e.g. 16/9
Player URLCustom URL for the video player used in the widget

Color theme — 5 color pickers + border radius:

SettingDescription
Card backgroundWidget card background
Tag backgroundTag chip background
Tag textTag chip text color
AccentHighlight color
Modal backgroundVideo modal background
Border radius (px)Rounded corner radius for cards

Tab: Advanced

SettingDescriptionDefault
Max. recursion depthHow many levels deep the API JSON is flattened into data points (1–10)6
Max. array entriesMaximum number of array elements mirrored per property (1–500)30
Dynamic tagsAutomatically create a tag data point for every unique recording tagfalse
Ignore tags (comma-separated)Recording tags to exclude from event data points
Tag filter (comma-separated)Only create event data points for recordings matching these tags

Live Dashboard

The adapter ships a built-in live dashboard at http://<iobroker>:<webport>/agent-dvr.0/. A second instance is reachable at /agent-dvr.1/, a third at /agent-dvr.2/, and so on.

Features:

  • Per-camera stream selection: MJPEG, MP4/FLV with audio (via flv.js), or go2rtc WebRTC/MSE
  • Camera filter button (funnel icon, header top-right) — opens a per-camera checkbox popover with an "All" toggle; badge shows the number of hidden cameras; state persisted in localStorage
  • Fullscreen view with PTZ overlay, record button, mute button, and native browser fullscreen (header auto-hides after 3 s of inactivity; reappears on mouse or touch)
  • Real-time motion (yellow border) and alert (orange border) indicators via Socket.io
  • Auto-reconnect: MJPEG and FLV reconnect after error; go2rtc reconnects after unexpected WebSocket close or 10 s stall
  • Recordings tab with grid, timeline, and event log view, search, collapsible tag filter, and video player with prev/next navigation
  • Tag filter splits AgentDVR's comma-separated tags into individual chips for per-tag filtering
  • Delete recording from the video player modal or select multiple with a long-press and bulk-delete (requires AgentDVR v7.7.8.0+)
  • Recording display settings — ⚙ gear button in the select/delete bar; slider for grid column width, max recordings override, and badge toggle — all saved in localStorage
  • New-recordings badge on the Recordings tab — shows how many recordings arrived since you last visited that tab; the baseline is stored in the browser's localStorage and is per-browser/per-device (not shared across different browsers or devices)
  • Camera colors are read from AgentDVR and applied to timeline bars and recording dots
  • PTZ presets — navigate to saved presets from the PTZ overlay; single selector data point per camera (requires AgentDVR v7.7.8.0+)
  • Status bar shows camera count, CPU/RAM usage and disk free space
  • Color theming via adapter config

go2rtc WebRTC Streams

go2rtc provides smooth, low-latency WebRTC/MSE streams with audio.

Setup:

  1. Install and run go2rtc, configure your camera streams in go2rtc's config.
  2. In the adapter config → Dashboard tab, assign the desired go2rtc stream name to each camera from the dropdown.
  3. Enter the go2rtc URL that appears below the table (e.g. http://192.168.1.10:1984).
  4. Save and restart. The adapter proxies WebSocket traffic through ioBroker to avoid browser cross-origin restrictions.

Media Proxy

The adapter can route all media through ioBroker so the browser never needs a direct connection to AgentDVR. Enable Media proxy on the Features tab.

What is proxiedProxy offProxy on
MJPEG live streamdirect AgentDVR URL/agent-dvr.0/api/mjpeg?oid=…
Snapshotdirect AgentDVR URL/agent-dvr.0/api/snap?oid=…
Recording thumbnailsdirect AgentDVR URL/agent-dvr.0/api/thumb?oid=…
Recording videosdirect AgentDVR URL/agent-dvr.0/api/media?oid=…
FLV live streamalways via ioBrokeralways via ioBroker
go2rtc WebSocketalways via ioBrokeralways via ioBroker

FLV and go2rtc always run through ioBroker regardless of the setting — the browser cannot make cross-origin requests to these endpoints directly.

When to enable

  • You access the dashboard from outside your home network where AgentDVR is not directly reachable from the browser
  • Only ioBroker is exposed externally (e.g. via reverse proxy or VPN to ioBroker only)

When to leave it off

  • Browser and AgentDVR are on the same network (local access)
  • Direct connection is faster — no extra hop, lower latency
  • Less load on the ioBroker server — streams do not pass through Node.js

The setting takes effect immediately after saving — no restart required.

Data points

<cam> stands for cam_<oid>_<name>, e.g. cam_8_Reolink.

System

Data pointTypeR/WDescription
system.onlinebooleanRConnection to AgentDVR established
system.lastUpdatestringRISO timestamp of last successful poll
system.lastPollnumberRUnix timestamp of last poll
system.cameraCountnumberRNumber of cameras discovered
system.disk_free_gbnumberRFree disk space in GB
system.settings.*variousRFlattened AgentDVR server settings
system.stats.*variousRCPU / RAM / disk stats
system.status.*variousRSystem status (armed, devices, version, …)
system.raw_getObjectsstringRRaw getObjects JSON (if enabled)

System controls (requires "System control buttons")

Data pointTypeR/WDescription
system.control.armbuttonWArm the system
system.control.disarmbuttonWDisarm the system
system.control.allOnbuttonWSwitch all devices on
system.control.allOffbuttonWSwitch all devices off
system.control.reloadConfigbuttonWReload AgentDVR configuration
system.control.reloadObjectsbuttonWReload objects
system.control.runStorageMgmtbuttonWRun storage management
system.control.blockExternalbuttonWBlock external access
system.control.unblockExternalbuttonWUnblock external access
system.control.restartbuttonWRestart AgentDVR
system.control.refreshbuttonWForce immediate poll
system.profile.selectornumberR/WActive profile index — dropdown (0 = Home, 1 = Away, …)
system.profile.liststringRAvailable profiles as JSON array

Per camera

Data pointTypeR/WDescription
<cam>.namestringRCamera name
<cam>.data.onlinebooleanRCamera is online
<cam>.data.connectedbooleanRStream is connected
<cam>.data.recordingbooleanRCurrently recording
<cam>.data.detectedbooleanRMotion/object detected
<cam>.data.detectorActivebooleanRMotion detector enabled
<cam>.data.alertsActivebooleanRAlerts enabled
<cam>.data.alertedbooleanRAlert currently active
<cam>.data.scheduleActivebooleanRSchedule enabled
<cam>.data.width / heightnumberRStream resolution
<cam>.data.*variousRAll further device properties from AgentDVR
<cam>.snapshot_b64stringRCurrent frame as data:image/jpeg;base64,… (role media.picture)
<cam>.control.recordbuttonWStart recording
<cam>.control.recordStopbuttonWStop recording
<cam>.control.recordRestartbuttonWRestart recording
<cam>.control.triggerRecordbuttonWTrigger recording (runs until timeout)
<cam>.control.snapshotbuttonWTell AgentDVR to save a snapshot to disk
<cam>.control.refreshSnapshotB64buttonWFetch current frame and write to snapshot_b64
<cam>.control.detectbuttonWTrigger motion detection
<cam>.control.alertOnbuttonWArm alerts
<cam>.control.alertOffbuttonWDisarm alerts
<cam>.control.switchOnbuttonWSwitch camera on
<cam>.control.switchOffbuttonWSwitch camera off
<cam>.control.objectDetectOnbuttonWEnable object detection (cameras only)
<cam>.control.objectDetectOffbuttonWDisable object detection (cameras only)
<cam>.control.scheduleOnbuttonWEnable the device schedule
<cam>.control.scheduleOffbuttonWDisable the device schedule
<cam>.control.detectorOnbuttonWEnable the motion detector
<cam>.control.detectorOffbuttonWDisable the motion detector
<cam>.control.sensitivityMinnumber 0–100R/WDetector sensitivity — minimum threshold (cameras only)
<cam>.control.sensitivityMaxnumber 0–100R/WDetector sensitivity — maximum threshold (cameras only)
<cam>.control.sensitivityGainnumber 0–100R/WDetector sensitivity — gain (cameras only)
<cam>.control.recOnAlertbuttonWEnable "record on alert"
<cam>.control.recOnDetectbuttonWEnable "record on detect"
<cam>.control.purgebuttonWDelete all recordings for this camera

PTZ (requires "PTZ control buttons")

Data pointTypeR/WDescription
<cam>.control.ptz.leftswitchR/WPan left (hold to keep moving)
<cam>.control.ptz.rightswitchR/WPan right
<cam>.control.ptz.upswitchR/WTilt up
<cam>.control.ptz.downswitchR/WTilt down
<cam>.control.ptz.upLeftswitchR/WDiagonal up-left
<cam>.control.ptz.upRightswitchR/WDiagonal up-right
<cam>.control.ptz.downLeftswitchR/WDiagonal down-left
<cam>.control.ptz.downRightswitchR/WDiagonal down-right
<cam>.control.ptz.zoomInswitchR/WZoom in
<cam>.control.ptz.zoomOutswitchR/WZoom out
<cam>.control.ptz.stopbuttonWStop PTZ movement
<cam>.control.ptz.centerbuttonWMove to center/home position
<cam>.control.ptz.presetnumberR/WPreset selector — write index to move to that preset; states enum lists preset names (requires AgentDVR v7.7.8.0+)

Stream URLs (requires "Generate stream URLs")

Data pointTypeR/WDescription
<cam>.urls.snapshotstringRURL to current JPEG snapshot (cameras only)
<cam>.urls.photostringRURL to photo endpoint (cameras only)
<cam>.urls.mjpegstringRURL to MJPEG live stream (cameras only)
<cam>.urls.mp4stringRURL to MP4 live stream (cameras only)
<mic>.urls.audio_mp3stringRURL to MP3 audio stream (microphones only)
<mic>.urls.audio_oggstringRURL to OGG audio stream (microphones only)

Events / Gallery (cameras only)

Data pointTypeR/WDescription
<cam>.events.*variousRLatest recording metadata — requires "Event data points"
<cam>.widget_recordingsstringRHTML recording gallery — requires "Gallery widget"
<cam>.widget_livestringRHTML single-camera live tile — requires "Gallery widget"; snapshot refreshes on each adapter poll

Webhook

The adapter exposes a webhook endpoint that triggers an immediate full poll of AgentDVR:

GET http://<iobroker>:<webport>/agent-dvr.0/webhook

Replace agent-dvr.0 with the actual instance number (agent-dvr.1, etc.) if you run multiple instances.

Configure this URL as an Action in AgentDVR (Camera → Edit → Alerts → Actions → URL) to get real-time updates whenever a recording finishes or an alert fires. The adapter will immediately re-fetch all camera data, recordings, and system stats — no need to wait for the next poll cycle.

Returns {"ok":true} on success.

Overview (requires "Overview widget")

Data pointTypeR/WDescription
widget_live_overviewstringRHTML tile grid of all cameras — snapshot refreshes on each adapter poll

Changelog

0.5.2 (2026-08-05)

  • (ipod86) feat: rename overview DP to widget_live_overview for consistent naming

0.5.1 (2026-08-05)

  • (ipod86) feat: per-instance URL routing — each adapter instance uses its own URL namespace (agent-dvr.0/, agent-dvr.1/, …)
  • (ipod86) feat: rename per-camera recording widget DP from widget to widget_recordings; add new widget_live DP with a single-camera live tile

0.5.0 (2026-08-03)

  • (ipod86) feat: replace live-view camera chip-bar with compact header filter button — funnel icon opens a popover with per-camera checkboxes and drag-to-reorder; order persisted in localStorage
  • (ipod86) feat: new-recordings badge on the Recordings tab — shows count of recordings since last visit; persisted per browser/device in localStorage
  • (ipod86) feat: recording display settings panel — ⚙ gear button in the select/delete bar; grid column width slider, max-recordings override, badge toggle (all persisted in localStorage)
  • (ipod86) feat: first-visit onboarding modals for live view (camera filter & sort) and recordings tab (gestures, gear panel, badge)
  • (ipod86) feat: webhook endpoint /agent-dvr.0/webhook triggers immediate full poll — configure as AgentDVR action for real-time updates
  • (ipod86) feat: PTZ presets — navigate to saved presets from PTZ overlay; single selector DP <cam>.control.ptz.preset per camera (requires AgentDVR v7.7.8.0+)
  • (ipod86) feat: add event log view to recordings panel (clock icon toggle) alongside grid and timeline
  • (ipod86) feat: delete recording from video modal (trash icon, two-click confirm, requires AgentDVR v7.7.8.0+)
  • (ipod86) feat: bulk-delete recordings — long-press a tile to enter select mode, checkbox each recording, delete all at once
  • (ipod86) feat: new dashMaxRec config setting — limits total recordings shown across all cameras in the dashboard (independent of widget limit, default 200)
  • (ipod86) feat: tag filter splits AgentDVR's comma-separated tags into individual chips for per-tag filtering
  • (ipod86) feat: read camera color from AgentDVR and use it for timeline bars and recording dots
  • (ipod86) feat: status bar shows CPU usage, RAM % and free, disk usage % and free alongside camera/recording counts
  • (ipod86) feat: reset colors to defaults button in Live Dashboard settings tab
  • (ipod86) refactor: remove per-camera pushTrigger data points in favour of the global webhook
  • (ipod86) fix: new-recordings badge now correctly visible (display:none CSS fallback fixed)
  • (ipod86) fix: record button moved to rightmost position in grid tiles and fullscreen panel
  • (ipod86) fix: camera filter button no longer changes appearance when cameras are hidden
  • (ipod86) fix: header z-index lifted so the camera filter popover renders above the main content area
  • (ipod86) fix: drive object pruning regex corrected; stale drive entries are now properly removed
  • (ipod86) fix: deleted recordings no longer reappear after the next adapter poll
  • (ipod86) fix: extend video format error message with AgentDVR auto-convert hint in all 11 languages
  • (ipod86) fix: FLV stream and grid tile layout scaling corrections
  • (ipod86) fix: Italian i18n string with apostrophe broke page JS (changed to escaped variant)
  • (ipod86) fix: detect AgentDVR "Command not found" response on delete and show proper error message

0.4.3 (2026-07-19)

  • (ipod86) fix: switch polling loop from setInterval to setTimeout to prevent concurrent poll runs
  • (ipod86) fix: httpTimeoutMs=0 now correctly clamps to 1000ms instead of falling back to default
  • (ipod86) fix: go2rtcEnabled config flag is now honored in fetchGo2rtcStreams
  • (ipod86) fix: remove unused isSupportedLang export from widget-i18n

0.4.2 (2026-07-12)

  • (ipod86) fix: FLV stream proxy now sends Authorization header (HTTP 401 with AgentDVR auth)
  • (ipod86) fix: dashboard camera online status was read from wrong state path (data.online → status.online)
  • (ipod86) fix: MP4/FLV stream label was hardcoded German — now translated in all 11 languages
  • (ipod86) fix: admin UI default values now match io-package.json (dashTagPosition, widgetAnzahl, widgetBorderRadius)
  • (ipod86) fix: go2rtcEnabled flag now respected when loading streams in admin UI
  • (ipod86) fix: enableStreamProxy missing from native defaults in io-package.json

0.4.1 (2026-07-12)

  • (ipod86) fix: overview tile links to ioBroker host; go2rtc URL shown only when enabled

0.4.0 (2026-07-12)

  • (ipod86) feat: optional MJPEG and snapshot stream proxy through ioBroker (browser needs only one connection to ioBroker, not directly to AgentDVR)

0.3.0 (2026-07-06)

  • (ipod86) feat: add scheduleOn/Off and detectorOn/Off control buttons for cameras and microphones
  • (ipod86) feat: add sensitivityMin, sensitivityMax, sensitivityGain level states for cameras (0–100)
  • (ipod86) feat: add audio_mp3 and audio_ogg URL states for microphones
  • (ipod86) fix: restrict objectDetectOn/Off and snapshot buttons to cameras (ot=2) only
  • (ipod86) feat: inline flv.js into dashboard HTML — no external file required
  • (ipod86) fix: preserve FLV stream aspect ratio after tab visibility change (all three player call sites)
  • (ipod86) feat: collapsible tag filter row on recordings and timeline pages
  • (ipod86) feat: native browser fullscreen button in live view modal with correct aspect ratio
  • (ipod86) feat: live view modal header auto-hides after 3 s of inactivity; reappears on mouse/touch
  • (ipod86) fix: add fsEnter, fsExit, filterByLabel, timelineView, closePanel i18n keys in all 10 languages

License

MIT License

Copyright (c) 2026 ipod86 david@graef.email

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.