SourceAnalytix преобразует накопительные показания счетчиков или регулярно обновляемые значения потребления электроэнергии в статистику потребления, доставки, затрат и доходов. Он поддерживает фиксированные цены, плановые изменения цен, динамические тарифы из штатов ioBroker и тарифы, управляемые селектором.
Для работы адаптера требуется Admin версии 7.6.20 или новее , js-controller версии 6.0.11 или новее и Node.js версии 22 или новее .
Что такое Sentry.io и какая информация передается на серверы этой компании?
Этот адаптер использует библиотеки Sentry для автоматического сообщения разработчикам об исключениях и ошибках в коде. Более подробную информацию, а также инструкции по отключению отправки сообщений об ошибках см. в документации Sentry-Plugin ! Система отчетности Sentry используется начиная с js-controller 3.0.
При сбое адаптера или возникновении другой ошибки в коде сообщение об ошибке, которое также отображается в журнале ioBroker, отправляется в Sentry. Если вы разрешили ioBroker GmbH собирать диагностические данные, в них будет включен идентификатор вашей установки. Это анонимный идентификатор, не содержащий личной информации, такой как ваше имя или адрес электронной почты. Он позволяет группировать ошибки и показывать, сколько установок затронуто.
Функции
- Итоги за текущий день, неделю, месяц, квартал и год
- Дополнительные значения за предыдущий период, а также данные за текущий год по дням недели, неделям, месяцам и кварталам.
- Дополнительные архивные статистические данные за неделю, месяц и квартал отображаются ниже каждого календарного года (по желанию).
- Расчеты потребления и поставок
- Расчеты затрат и доходов с возможностью выбора ежемесячной базовой цены.
- Фиксированные, плановые, установленные государством и регулируемые поставщиками цены за единицу товара
- История цен с указанием времени, сохраняющая уже рассчитанные затраты.
- Автоматическое преобразование между совместимыми единицами измерения энергии, объема, массы и длины в метрической системе.
- Интегрирование показаний мощности по фактическим интервалам их обновления, с возможностью игнорирования отрицательных показаний.
- Восстановление пропущенных переносов календаря после перезапуска по запросу или путем ежечасной проверки.
- Обработка сброса показаний счетчиков, замена счетчиков и небольшие обратные колебания.
- Одно компактное, автоматически обновляемое JSON-состояние статистики для каждого активного источника.
Настраивать
1. Настройте экземпляр адаптера.
Вкладка «Общие настройки» определяет, какие подробные статистические данные будут создаваться. Отключение параметра удаляет соответствующие необязательные состояния, сохраняя при этом обычные итоговые данные за текущий период и данные за существующие архивные годы.

| Параметр | Результат |
|---|---|
| Статистика за год: недели / месяцы / кварталы | Ниже приведены полные значения товаров в магазинах. <source>.<year> для исторического сравнения. |
| Текущий год: будний день | Сохраняет значения текущей недели по дням недели. |
| Текущий год: Недели / Месяцы / Кварталы | Ниже приведены значения, хранящиеся в памяти за каждый период. <source>.currentYear. |
| Текущий год: Предыдущий период | Сохраняет информацию о прошедшем дне, неделе, месяце, квартале и году, а также значения дней недели за предыдущую неделю. |
| Округление: десятичные дроби для значений потребления. | Исходные значения десятичных знаков скопированы в новые настроенные источники. 3 по умолчанию. |
| Округление: десятичные дроби для значений себестоимости. | Исходные значения десятичных знаков скопированы в новые настроенные источники. 2 по умолчанию. |
Оба варианта округления приемлемы. -1 Для хранения точного вычисленного значения без округления. Каждый источник хранит свои собственные значения Decimals для значений потребления и Decimals для значений затрат . Новые источники предварительно заполняются на основе указанных выше настроек экземпляра. Существующие источники без этих полей получают свои ранее действовавшие значения экземпляра один раз во время миграции, поэтому последующие изменения настроек экземпляра по умолчанию не влияют на их результаты. Округление влияет только на значения, записываемые в состояния; внутренние вычисления, кумулятивное чтение и сохраненная память всегда сохраняют полную точность, поэтому точность со временем не теряется.
SourceAnalytix запоминает последние успешно обработанные календарные периоды. Если адаптер или ioBroker не запущен в полночь, пропущенные изменения дня, недели, месяца, квартала и года обрабатываются один раз при следующем запуске.
Перезапуск также может быть инициирован без перезапуска экземпляра, что полезно, если обнаруживается, что экземпляр не работает вскоре после полуночи:
- Набор
sourceanalytix.<instance>.info.recoverPeriodsкtrueКнопка сбрасывается после завершения выполнения задания. - Или отправьте сообщение из скрипта:
sendTo('sourceanalytix.<instance>', 'recoverPeriods', {}, result => log(result.recovered))В ответе указано количество источников, для которых была обработана операция переноса.
Ежечасная проверка выполняет аналогичное восстановление самостоятельно, поэтому пропущенное переключение во время работы адаптера — после приостановки работы хоста или коррекции системного времени — исправляется автоматически. Каждый маршрут является идемпотентным: источники, периоды которых уже актуальны, пропускаются.
2. Создайте определения цен.
Откройте определения цен и добавьте категории, которые должны использовать исходные государства.

| Поле | Описание |
|---|---|
| Категория | Уникальный идентификатор, отображаемый в поле «Выберите определение цены» в исходном штате. |
| Описание | Текстовое описание тарифа. |
| Тип затрат | Выбирает costs /consumed или earnings /delivered Категории результатов. |
| Единица | Целевая единица потребления и знаменатель цены за единицу. |
| Источник цен | Фиксированная цена, числовое значение состояния ioBroker или выбор тарифа. |
| Цена за единицу | Цена за единицу товара для фиксированного тарифа или базовая цена для неактивного/выборочного тарифа. |
| Цена состояния | Полный идентификатор числового состояния цены или состояния выбора тарифа. |
| Действующая тарифная цена | Цена, используемая во время работы селектора. |
| Значение активного селектора | Дополнительное значение, которое активирует альтернативный тариф. |
| Действительно с | Дополнительная дата, с которой начинает действовать тариф, включая его ежемесячную базовую цену. |
| Цена в месяц | Ежемесячная базовая цена применяется только к источникам, для которых включена опция «Включая базовый тариф» . |
Фиксированные и плановые цены
Выберите «Фиксированная цена» и введите «Цена за единицу» . При изменении тарифа установите значение «Действительно с» до даты вступления в силу новой цены. Предыдущая цена сохраняется в истории и не применяется задним числом.
Динамическое состояние цены
Выберите значение «Штат» и укажите штат, в котором отображается текущая числовая цена за единицу. SourceAnalytix подписывается на этот штат и записывает каждое изменение с меткой времени штата. Принимаются как числа, так и числовые строки с десятичными разделителями — точкой или запятой.
Значение состояния должно представлять собой валюту системы для выбранной целевой единицы, например, валюта/кВтч, если в определении цены используется kWh Перед использованием преобразуйте значения, такие как центы за кВт⋅ч, в адаптере источника или в скрипте.
Выбор тарифа
Выберите тарифный план для дневного/ночного режима, ретрансляции, связи или других тарифов с двумя ценами:
- Цена за единицу — это цена в неактивном состоянии/базовая цена.
- Действующая тарифная цена используется, пока активен селектор.
- Без значения активного селектора ,
trueНенулевые числа и общие строки, содержащие истинные значения, активируют альтернативный тариф. - При использовании значения активного селектора , только точное совпадение строкового представления активирует альтернативный тариф.
Текущая цена для записи
Каждая категория раскрывает sourceanalytix.<instance>.priceDefinitions.<category>.currentPrice Скрипты и визуализации могут записывать числовое значение в это состояние, чтобы немедленно применить новую цену. Это значение также добавляется к истории цен с отметкой времени.
Расчет исторических цен
Цены зависят от времени. Новая цена вступает в силу только с момента ее изменения и никогда не заменяет затраты, уже накопленные за предыдущее потребление.
Для кумулятивного счетчика SourceAnalytix знает разницу в потреблении между двумя показаниями. Если в течение этого интервала произошло одно или несколько изменений цены, разница распределяется пропорционально по прошедшим временным сегментам, и каждая доля оплачивается по цене, действующей для этого сегмента. Изменение цены, произошедшее точно в момент времени более позднего показания счетчика, применяется к следующему интервалу.
Точный накопитель затрат и история цен сохраняются после перезагрузки адаптера. Явный перерасчет старых исторических данных в настоящее время не реализован.
Ежемесячная базовая цена
Включите параметр «Включить базовый тариф» для источника, чтобы добавить настроенную ежемесячную цену. Параметр «Действителен с» также определяет первый месяц для этой платы. Полная базовая цена бронируется один раз при первом вступлении тарифа в силу, а затем в начале каждого последующего календарного месяца. Изменение цены в течение месяца применяется к следующему ежемесячному бронированию, в то время как цены предыдущих месяцев остаются без изменений. Существующие тарифы без даты действия сохраняют предыдущее поведение, начиная с начала текущего календарного года.
В дневные и недельные итоги включается полная сумма месячной платы только в том случае, если дата бронирования приходится на этот период. В месячные, квартальные и годовые итоги содержатся полные суммы, забронированные в соответствующие календарные периоды.
3. Активировать исходное состояние
SourceAnalytix настраивается через пользовательские параметры ioBroker для каждого состояния источника. Откройте «Объекты» , щелкните значок гаечного ключа/конфигурации нужного состояния и разверните экземпляр SourceAnalytix.


| Параметр | Описание |
|---|---|
| Включено | Активирует этот источник для выбранного экземпляра SourceAnalytix. |
| Имя | Необязательное отображаемое имя для создаваемого устройства. |
| Идентификатор выходного сигнала | Технический идентификатор устройства указан ниже. sourceanalytix.<instance> Он инициализируется обратно совместимым идентификатором, полученным из исходного кода, и может быть сокращен. |
| Выберите определение цены | Обязательная категория из ценовых определений адаптера. |
| Выберите модуль | Исходный модуль. Оставьте включенным автоматическое определение, если исходный объект имеет корректно поддерживаемый модуль. |
| Рассчитайте затраты | Создает и обновляет состояния затрат или прибыли. |
| Включая базовую ставку | Добавляет ежемесячную базовую цену, указанную в определении цены. |
| Рассчитайте потребление | Создает и обновляет состояния потребления или доставки. |
| Средние значения мощности между обновлениями | Дополнительный режим расчета состояний мощности; см. Состояния мощности . |
| Игнорируйте отрицательные значения степени. | Учитывает отрицательные показания мощности как 0 W; см. Состояния мощности . |
| Сохраняйте значения счетчиков | Сохраняет показания счетчиков в включенных периодических коллекциях. |
| Обнаружение сброса значения устройства | Продолжает подсчет суммарного значения после сброса или замены счетчика. |
| Порог | Наибольшая обратная флуктуация игнорируется как дрожание измерения, выраженное в целевой единице. |
Для существующих и вновь активированных источников начальный идентификатор выходных данных определяется на основе идентификатора состояния источника путем замены точек двойными подчеркиваниями. Он может быть изменен на более короткий уникальный идентификатор, содержащий буквы, цифры, подчеркивания и дефисы. SourceAnalytix копирует и проверяет все сгенерированное дерево объектов перед удалением старого дерева. Существующие скрипты, визуализации, псевдонимы и внешние запросы истории, которые ссылаются на старый идентификатор, должны быть обновлены вручную. Настройки адаптера истории копируются, поэтому ведение журнала продолжается под новым идентификатором, но значения, записанные до изменения, остаются под старыми идентификаторами состояний. Членство в комнатах и функциях не копируется.
Исходные значения и единицы измерения
Совокупные состояния источников
Используйте накопительную сумму, которая обычно только увеличивается, например, Tasmota. ENERGY_Total или общее потребление интеллектуального счетчика. Не используйте такие значения, как ENERGY_Today Этот параметр намеренно сбрасывается ежедневно. Если итоговая сумма недоступна, создайте её в адаптере или скрипте вышестоящего сервера.
Для кумулятивных источников потребление рассчитывается следующим образом:
current cumulative reading - reading at the beginning of the period
При первом включении SourceAnalytix инициализирует пустые или нулевые значения начала дня, недели, месяца, квартала и года текущими нормализованными показаниями счетчика. Это предотвращает отображение существующего общего значения счетчика за весь период в качестве нового потребления. Значения остаются редактируемыми и не перезаписываются при последующих включениях.

Введите начальные значения вручную в целевой единице измерения , выбранной при определении цены. Каждое значение должно представлять собой показания счетчика на начало периода, а не потребление за этот период.
властные государства
Значения мощности, такие как W или kW Данные интегрируются по фактическому времени между обновлениями состояния для производства энергии. Первое показание устанавливает базовый уровень и не определяет потребление.
По умолчанию предыдущее значение мощности считается действительным на протяжении всего интервала. Включите усреднение значений мощности между обновлениями для датчиков, которые регулярно передают данные и изменяются постепенно; в этом случае SourceAnalytix будет использовать среднее значение предыдущего и текущего значений. Оставьте эту функцию отключенной для устройств, которые резко переключаются при обновлении, отмечающем событие переключения.
Некоторые инверторы показывают сильно отрицательное значение мощности в выключенном состоянии, которое в противном случае было бы учтено как отрицательная энергия и уменьшило бы накопленную выработку. Включите параметр «Игнорировать отрицательные значения мощности» , чтобы учитывать такие показания как отрицательную энергию. 0 W Показания фиксируются, а не отбрасываются, поэтому интервал продолжает увеличиваться; отбрасывание этих показаний позволило бы сохранить последнее положительное значение в качестве базового и интегрировать его по всему времени простоя.
Поддерживаемые модули
SourceAnalytix автоматически преобразует значения только между совместимыми величинами:
| Количество | Поддерживаемые модули |
|---|---|
| Власть | GW, MW, kW, W, mW |
| Энергия | GWh, MWh, kWh, Wh, mWh |
| Кубический объем | km³, m³, dm³, cm³, mm³ |
| объем жидкости | hl, l, dl, cl, ml |
| Масса | t, kg, g |
| метрическая длина | km, m, dm, cm, mm, µm, nm |
Литры и кубические метры можно переводить друг в друга. Несовместимые преобразования, такие как килограммы в кВт·ч или метры в литры, отбрасываются, а не приводят к вводящим в заблуждение результатам.
Сгенерированные состояния
Для каждого источника SourceAnalytix создает cumulativeReading и включенные деревья результатов:
| Путь | Содержание |
|---|---|
<source>.currentYear.consumed | Текущие объемы потребления по категориям затрат. |
<source>.currentYear.delivered | Текущие объемы поставок по категориям доходов. |
<source>.currentYear.costs | Текущие итоговые затраты. |
<source>.currentYear.earnings | Текущие показатели прибыли. |
<source>.currentYear.meterReadings | Дополнительные параметры измерения показаний счетчика по включенным периодам. |
<source>.<year> | Дополнительная возможность просмотра архивных статистических данных за неделю, месяц и квартал. |
<source>.statisticsJson | Краткая статистика за текущий год для VIS, скриптов и других адаптеров. |
В базовом текущем и необязательном предыдущем состояниях используются такие названия, как... 01_currentDay, 02_currentWeek, 03_currentMonth, 04_currentQuarter, 05_currentYear и их previous эквиваленты.
Предыдущие значения записываются с указанием времени периода, к которому они относятся. 23:59:59 в последний день, а не в момент перехода на следующий период. Поэтому адаптеры истории регистрируют завершенный день, неделю, месяц, квартал или год в пределах этого периода, что и ожидают такие средства визуализации, как Flot.
Статистика в формате JSON
Каждый активный источник автоматически предоставляет доступ только для чтения. statisticsJson государство с ролью json Дополнительные настройки не требуются. Он содержит те же вычисленные значения, что и отдельные штаты, и не выполняет отдельного расчета.
{
"schemaVersion": 1,
"year": 2026,
"source": {
"id": "smartmeter.0.total",
"name": "Electricity meter",
"unit": "kWh"
},
"quantity": {
"type": "consumed",
"current": {
"day": 4.21,
"week": 28.65,
"month": 114.32,
"quarter": 301.77,
"year": 894.15
},
"previous": null,
"periods": {
"weekdays": null,
"previousWeekdays": null,
"weeks": {},
"months": {},
"quarters": {}
}
},
"financial": {
"type": "costs",
"currency": "EUR",
"current": {
"day": 1.24,
"week": 8.47,
"month": 34.19,
"quarter": 89.51,
"year": 261.42
},
"previous": null,
"periods": {
"weekdays": null,
"previousWeekdays": null,
"weeks": {},
"months": {},
"quarters": {}
}
},
"meterReadings": null
}
quantity представляет собой либо consumed или delivered ценности. financial представляет собой либо costs или earnings. meterReadings Эта запись заполняется при включении сохранения значений счетчика. Отключенные вычисления и сбор данных за периоды отображаются следующим образом: null Таким образом, схема остается предсказуемой.
Использование в будние дни 1 с понедельника по 7 для воскресенья. Условные обозначения недель и месяцев заполняются нулями, а для четвертей используются нули. 1 через 4 Включаются только данные за текущий год и необязательные значения за предыдущий период, что предотвращает бесконечное расширение состояния. Временная метка состояния ioBroker указывает, когда JSON был последний раз изменен.
Состояние восстанавливается на основе существующей статистики при запуске адаптера, и его записи объединяются в процессе обычных вычислений. Если источник отключен или удален, последнее значение JSON сохраняется вместе с остальной вычисленной историей и больше не обновляется.
Сброс и корректировка показаний счетчиков
При включенной функции обнаружения сброса, снижение, превышающее пороговое значение, запускает подтверждение сброса. SourceAnalytix сохраняет последнее принятое значение до тех пор, пока другое показание не останется в нижнем диапазоне и не подтвердит сброс или замену. Затем он сохраняет смещение и продолжает накопительное измерение, не теряя данные о предыдущем потреблении. Если следующее показание возвращается в пределах порогового значения последнего принятого показания, кандидат отбрасывается как временно недействительное показание. Показание, которое оказывается значительно ниже последнего принятого показания, чем пороговое значение , подтверждает сброс, поэтому выберите пороговое значение, которое охватывает, насколько сильно счетчик может откатиться назад после временного сбоя. Небольшое обратное изменение рассматривается как дрожание и игнорируется. Пороговое значение 0 Каждое снижение рассматривается как возможная перезагрузка, требующая подтверждения.
Если функция обнаружения сброса отключена, принимаются уменьшающиеся показания источника, что может снизить вычисленные итоговые значения. Этот режим предназначен только для источников, для которых такое поведение является ожидаемым.
Исправить уже неправильную версию cumulativeReading:
- Остановите экземпляр SourceAnalytix.
- Откройте раздел «Объекты» и включите экспертный режим.
- Правильный
<source>.cumulativeReading. - Откройте пользовательские настройки SourceAnalytix для исходного состояния и исправьте значения начала периода, которые могут быть затронуты, в том же целевом подразделении.
- Снова запустите адаптер и проверьте результаты за текущий период.

Изменение текущей цены за единицу товара не приводит к перерасчету исторических затрат. В настоящее время нет возможности инициировать перерасчет исторических данных пользователем.
Поиск неисправностей
Исходный код не инициализирован.
- Убедитесь, что пользовательская конфигурация включена для правильного экземпляра SourceAnalytix.
- Выберите существующее определение цены. Определение цены необходимо, даже если включено только потребление.
- Убедитесь, что источник сигнала может быть обнаружен объектом, или выберите его вручную.
- Убедитесь, что исходные и целевые единицы измерения представляют собой совместимые величины.
- Просмотрите журнал адаптера, чтобы узнать точное состояние отклонения или значение конфигурации.
Показатель потребления начинает отсчитываться с момента снятия показаний счетчика за весь срок его службы.
Обычно это указывает на старые или введенные вручную значения начала периода. Установите начальные значения дня, недели, месяца, квартала и года на соответствующие исторические показания счетчика. Для сегодняшнего значения это обычно:
current cumulative reading - consumption since the beginning of today
Динамические цены отображаются некорректно.
- Убедитесь, что в состоянии цены используется валюта за целевую единицу, а не центы, если только значение не было конвертировано.
- Проверьте метку времени состояния цены и показания исходного счетчика.
- Помните, что разница в показаниях счетчика, отражающая изменения цен, делится на прошедшее время, поскольку более точного профиля потребления не существует.
- Осмотреть
priceDefinitions.<category>.currentPriceпо действующей цене.
Известные ограничения
- Автоматический перерасчет исторических данных намеренно отключен, и явная функция перерасчета пока недоступна.
- Настраиваемые пользователем скользящие периоды не реализованы.
- Счетчики без единиц измерения, единицы времени и цифровые единицы измерения не поддерживаются.
Кредиты
История этого адаптера восходит к публикации на форуме ioBroker в 2016 году:
Впоследствии он был усовершенствован. @hadering и опубликовано как homematic_verbrauchszaehler .
Поддержите меня
Если вам нравится мое творчество, пожалуйста, рассмотрите возможность личного пожертвования.
Это персональная ссылка для пожертвований DutchmanNL и не имеет отношения к проекту ioBroker.
Changelog
WORK IN PROGRESS
- Prevent a temporary low meter reading followed by a near-return from being counted as a confirmed reset and duplicating consumption; rejected resets are now logged as a warning (#1227).
- Keep an existing output tree and restore its effective ID in the source settings when an output-ID change is invalid, unavailable or cannot be migrated; a source without an existing tree is not activated instead of silently starting a new one (#1228).
- Never delete pre-existing target objects when an output migration fails before SourceAnalytix writes to the target (#1228).
- Add migration, restart recovery, settings write-back and concurrent-disable regression tests for custom output IDs (#1229).
0.6.0 (2026-09-26)
- (DutchmanNL) Maintenance: raise Node.js to 22, modernise CI and release tooling, update dependencies, resolve repository checker findings
- (DutchmanNL) The adapter now requires Admin 7.8.23 or newer.
- (DutchmanNL) Tests now also run on Node.js 26 (#1222).
- (softwarecrash) Price definition and unit selection work again with Admin 8, and settings with a missing price definition, unit or output ID can no longer be saved (#1202).
- (softwarecrash) Each source has an editable output ID, pre-filled with its existing ID so nothing changes for current installations. Changing it copies and verifies the complete object tree before the old tree is removed, and reserved, invalid or already used IDs are rejected (#617, #1200).
- (softwarecrash) A meter decrease larger than the threshold is only accepted as a reset or replacement once the following reading confirms it; a reading back within the threshold of the last accepted value discards it (#1199).
- (softwarecrash) Fixed a crash when a source was reconfigured or disabled while a calculation was running (#1198).
- (softwarecrash) Each source stores its own rounding settings, taken once from the instance defaults, so later changes to the defaults no longer affect existing sources (#1200).
0.5.6 (2026-08-02)
- The monthly basic price is booked as a full charge when the tariff first becomes valid and at the beginning of every following calendar month, instead of being spread over the days of a month (#1193).
- Valid from now also defines the first month the monthly basic price is charged, while tariffs without a validity date keep starting at the beginning of the current calendar year (#1193).
- Monthly basic prices are recorded in their own
basicPriceHistorystate, so a price change during a month only applies to the next monthly booking and already booked months stay unchanged (#1193). - Valid from is available for every price source, not only for fixed prices, and a selected date becomes effective at local midnight (#1193).
0.5.5 (2026-08-01)
- Previous day, week, month, quarter and year values are written with the timestamp of the period they belong to (23:59:59 on its last day), so history adapters and Flot plot them in the correct period (#497).
- The number of decimals for consumption and cost values is configurable globally and per source, including an option to store the exact value without rounding (#934).
- A missed calendar rollover can be processed without restarting the instance, through the new
info.recoverPeriodsbutton or arecoverPeriodsmessage, and an hourly check recovers a rollover the scheduler missed while the adapter kept running (#905). - The midnight scheduler can no longer raise an unhandled rejection, and its cron job and timers are stopped when the instance shuts down (#904).
0.5.4 (2026-08-01)
- Each active source automatically exposes a compact
statisticsJsonstate containing its current-year quantity, financial and optional meter-reading statistics (#361, #967). - Monthly basic prices are no longer imported into the variable-cost accumulator and added a second time after a restart (#1188).
0.5.3 (2026-07-28)
- Power states can optionally ignore negative readings, so inverters which report a negative power while switched off no longer reduce the accumulated yield (#466).
License
MIT License
Copyright (c) 2022-2026 DrozmotiX Services B.V.
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.
