Рубрики
Без рубрики

Создание без серверного решения IoT с функциями Python Azure и Signalr

Начните работать с функцией Python Azure, Azure Signalr для того, чтобы натолкнуть данные в режиме реального времени для веб-клиентов, развернуть одно страницу приложения и запустить без сервера на статических веб-сайтах Azure State. Теги с AzureFunctions, Python, Serverless, SignalR.

Следуй за мной на Twitter , Исходный код проекта , PowerPoint слайды , PDF -слайды

Обзор решения

Эта диаграмма решений обзор типичного решения IoT. Azure iot Хаб отвечает за интернет-масштаб, безопасную, двунаправленную связь с устройствами и бэкэнд-услугами.

Телеметрия может быть направлено Azure IoT Hub к различным услугам, а также к хранению в Apache Avro или формат JSON для таких целей, как аудит, интеграция или процессы машинного обучения.

Эта публикация принимает кусок этого сценария и о прямом обращении через Серверный Обработка телеметрии из Azure IoT-Hub, через функции Python Azure и Azure Signalr для приборной панели в реальном времени.

Azure Services

Следующие службы Azure используются в этом решении и доступны в бесплатных уровнях: Azure iot Хаб , Функции Azure , Azure Signalr , Azure Storage , Статические веб -сайты для хранения Azure

Вы можете подписаться на Бесплатная учетная запись Azure , если вы студент, то обязательно подпишитесь на Azure для студентов , кредитная карта не требуется.

Разработка функций Python Azure

Когда начать

Просмотрите Функции Azure Руководство для работников Python . Есть информация по следующим темам:

Компоненты решения (включены в этот репозиточный репо)

  1. Функция Python Azure. Эта функция Azure обрабатывает партии телеметрии, затем калибровку и проверку телеметрии и обновляет таблицу хранения Azure состояния устройства, а затем передает телеметрию в службу Azure SignalR для обновления веб-клиента в режиме реального времени.

  2. Azure Signalr .net Функция Core Azure (записанная в C# до доступного связывания сигнала Python). Эта функция Azure отвечает за передачу телеметрии в службу SignalR для отправки на панель панели веб -клиента SignalR.

  3. Веб -панель Анкет Это веб -приложение для одной страницы размещено на хранилище Azure в качестве статического веб -сайта. Так что это тоже без сервера.

Соображения дизайна

Оптимистичное параллелизм

Во -первых, полезно понять Масштабирование запуска концентратора событий и как дополнительные экземпляры функции могут быть начаты для обработки событий.

Я хотел сохранить счет в таблице состояний устройства, сколько раз, когда устройство отправлялось телеметрией. Решает решение Лазурное хранилище/Cosmosdb Оптимистическая параллелизм Анкет

Оптимистическое параллелизм (OCC) Предполагается, что несколько транзакций могут часто завершаться, не мешая друг другу. Во время работы транзакции используют ресурсы данных без получения блокировки на этих ресурсах. Перед фиксацией каждая транзакция проверяет, что никакая другая транзакция не изменила прочтения данных. OCC обычно используется в средах с низким содержанием данных.

Если есть несколько экземпляров функций обновления и есть столкновение, я внедрил экспоненциальный откат и добавил случайный коэффициент, позволяющий повторно.

Pseudo code: random(occBase, min(occCap, occBase * 2 ^ attempt))
def calcExponentialFallback(attempt):
    base = occBase * pow(2, attempt)
    return random.randint(occBase, min(occCap, base)) / 1000.0

Из моего ограниченного тестирования экспоненциальный откат был эффективным.

Телеметрия обработка

«Обновленная эвиштат» сначала проверяет, находится ли объект уже в таблице хранения. Если сущность существует, «etag» используется при вызове Merge_entity. Призыв к Merge_entity преуспевает, если ETAG соответствует ETAG сущности в хранении во время слияния.

def updateDeviceState(telemetry):
    mergeRetry = 0

    while mergeRetry < 10:
        mergeRetry += 1

        try:
            # get existing telemetry entity
            entity = table_service.get_entity(
                deviceStateTable, partitionKey, telemetry.get('deviceId', telemetry.get('DeviceId')))
            etag = entity.get('etag')
            count = entity.get('Count', 0)
        except:
            entity = {}
            etag = None
            count = 0

        count += 1

        updateEntity(telemetry, entity, count)
        calibrator.calibrateTelemetry(entity)

        if not validateTelemetry(entity):
            break

        try:
            if etag is not None:    # if etag found then record existed
                # try a merge - it will fail if etag doesn't match
                table_service.merge_entity(
                    deviceStateTable, entity, if_match=etag)
            else:
                table_service.insert_entity(deviceStateTable, entity)

            return entity

        except:
            interval = calcExponentialFallback(mergeRetry)
            logging.info("Optimistic Consistency Backoff interval {0}".format(interval))
            time.sleep(interval)

    else:
        logging.info('Failed to commit update for device {0}'.format(
            entity.get('DeviceId')))

Оптимизация калибровки телеметрии

Вы можете калибровать данные на устройстве или в облаке. Я предпочитаю калибровать облачную сторону. Данные калибровки могут быть загружены с помощью привязки данных функции Azure, но я предпочитаю ленивый загружать данные калибровки. Там может быть много калибровочных данных, поэтому не имеет смысла загружать все это сразу, когда функция запускается.

def getCalibrationData(deviceId):
    if deviceId not in calibrationDictionary:
        try:
            calibrationDictionary[deviceId] = table_service.get_entity(
                calibrationTable, partitionKey, deviceId)
        except:
            calibrationDictionary[deviceId] = None

    return calibrationDictionary[deviceId]

Проверка телеметрии

Решения IoT должны проверять телеметрию, чтобы гарантировать, что данные находятся в пределах разумных диапазонов, чтобы обеспечить неисправные датчики.

def validateTelemetry(telemetry):
    temperature = telemetry.get('Celsius')
    pressure = telemetry.get('hPa')
    humidity = telemetry.get('Humidity')

    if temperature is not None and not -40 <= temperature <= 80:
        return False
    if pressure is not None and not 600 <= pressure <= 1600:
        return False
    if humidity is not None and not 0 <= humidity <= 100:
        return False
    return True

Интеграция Azure Signalr

Нет сервисного Azure Signalr SDK. Чтобы отправить телеметрию из функции Azure Trigger Event Hub в веб -клиент панели инструментов, вам нужно вызвать функцию HTTP Azure, которая связана с службой SignalR. Эта функция SignalR Azure затем отправляет телеметрию через SignalR, как если бы данные поступали из приложения на стороне клиента.

Поток для интеграции Azure SignalR заключается в следующем:

  1. Веб -клиент звонит в отдых, чтобы ‘ договориться ‘, среди прочего, Signalr’ Hubname ‘возвращается клиенту.
  2. Затем веб -клиент звонит в отдохнув к ‘ GetDeviceState «Этот триггер HTTP получает состояние для всех устройств из таблицы состояний устройства. Данные возвращаются клиенту через SignalR через тот же ‘ Hubname «Это было возвращено от призывания к ‘ договориться
  3. Когда новая телеметрия прибывает через IoT Hub, « EnvironmenteVenttrigger «Спутники триггера, телеметрия обновляется в таблице состояний устройства, и вызов отдыха сделан для ‘ SendSignalRmessage ‘И телеметрия отправляется всем клиентам SignalR, слушающему на’ Hubname ‘ канал.

Настройка обзора

Эта лаборатория использует бесплатные услуги на Azure. Следующее необходимо настроить:

  1. Azure iot Hub и Azure IoT Device
  2. Azure Signalr обслуживание
  3. Развернуть функцию Python Azure
  4. Развернуть сигнал .NET .NET Основная функция Azure

Шаг 1: Следуйте руководству по симулятору Raspberry Pi, чтобы настроить Iot Iot Центр

В то время как в Python Azure функции находятся в предварительном просмотре, они доступны в ограниченных местах. На данный момент «westus» и «westeurope». Я рекомендую вам создать все ресурсы проекта в одном из этих мест.

Настройка симулятора Raspberry Pi

Шаг 2: Создайте Azure Resource Group

AZ Group Create

az group create -l westus -n enviromon-python

Шаг 3: Создайте сервис сигнала Azure

az signalr create -n  -g enviromon-python --sku Free_DS2 --unit-count 1
az signalr key list -n  -g enviromon-python

Шаг 4: Создайте учетную запись хранения

AZ Storage Account Create

az storage account create -n enviromonstorage -g enviromon-python -l westus --sku Standard_LRS --kind StorageV2

Шаг 5: клонировать проект

git clone https://github.com/gloveboxes/Go-Serverless-with-Python-Azure-Functions-and-SignalR.git

Шаг 6: развернуть сигнал .NET .NET Основная функция Azure

cd  Go-Serverless-with-Python-Azure-Functions-and-SignalR

cd dotnet-signalr-functions

cp local.settings.sample.json local.settings.json

code .

Шаг 7: Обновите local.settings.json

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "StorageConnectionString":"",
        "AzureSignalRConnectionString": ""
    },
    "Host": {
        "LocalHttpPort": 7071,
        "CORS": "http://127.0.0.1:5500,http://localhost:5500,https://azure-samples.github.io",
        "CORSCredentials": true
    }
}

Шаг 8: развернуть сигнал .NET .NET Основная функция Azure

  1. Откройте окно терминала в Visual Studio. В главном меню выберите View -> терминал
  2. Развернуть функцию Azure
func azure functionapp publish --publish-local-settings 
func azure functionapp list-functions 
Functions in mysignal-signalr:
    getdevicestate - [httpTrigger]
        Invoke url: https://mysignal-signalr.azurewebsites.net/api/getdevicestate

    negotiate - [httpTrigger]
        Invoke url: https://mysignal-signalr.azurewebsites.net/api/negotiate

    SendSignalrMessage - [httpTrigger]
        Invoke url: https://mysignal-signalr.azurewebsites.net/api/sendsignalrmessage?code=DpfBdeb9TV1FCXXXXXXXXXXXXX9Mo8P8FPGLia7LbAtZ5VMArieo20Q==

** Вам нужно скопировать и вставить SendSignalRmessage вызов URL где -то удобно.

Шаг 9: Откройте проект функций Python с помощью кода Visual Studio

Перейдите на каталог, в котором вы клонировали в проект, изменение в каталоге iothub-python-функций, а затем запустите код Visual Studio.

От терминала на Linux и MacOS, или PowerShell на Windows.

cd  Go-Serverless-with-Python-Azure-Functions-and-SignalR

cd iothub-python-functions

cp local.settings.sample.json local.settings.json

code .

Шаг 10: Обновите local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsStorage": "",
    "IoTHubConnectionString": "",
    "PartitionKey": "",
    "StorageConnectionString": "",
    "SignalrUrl": ""
  }
}

Шаг 11: Развернуть функцию Python Azure

  1. Откройте окно терминала в Visual Studio. В главном меню выберите View -> терминал
  2. Развернуть функцию Azure
func azure functionapp publish enviromon-python --publish-local-settings --build-native-deps  

Шаг 12: Включить статические сайты для хранения Azure

Проект Dashboard содержит статический проект веб -сайта.

Следуйте руководству для Статическое хостинг веб -сайта в Azure Storage Анкет

Страница, используемая для этого образца, является EnviroMon.html. Обязательно измените URL «Apibaseurl» на веб -странице JavaScript, чтобы указать ваш экземпляр функции SignalR Azure.

Скопируйте содержимое проекта приборной панели на статический сайт.

Шаг 13: Включите COR для сигнала .NET .NET Основная функция Azure

AZ functionApp cors добавляет

az functionapp cors add -g enviromon-python -n  --allowed-origins 

Шаг 14: Начните приборную панель

Из вашего веб -браузера перейдите к https://your-start-web-site/enviromon.html

Телеметрия из симулятора Raspberry Pi будет отображаться на приборной панели.

Оригинал: “https://dev.to/azure/building-a-serverless-iot-solution-with-python-azure-functions-and-signalr-4ljp”