private static string generatePatchForTurbine(PowerValues powerValues)
        {
            UpdateOperationsUtility uou = new UpdateOperationsUtility();

            uou.AppendReplaceOp("/powerObserved", powerValues.powerObserved);
            uou.AppendReplaceOp("/powerPM", powerValues.powerPM);
            uou.AppendReplaceOp("/powerDM", powerValues.powerDM);

            return(uou.Serialize());
        }
        private static async Task processSensorData(string deviceId, JObject sensorData)
        {
            // extract sensor data
            var info = new WTPowerRequestInfo {
                PowerInputs = new List <WTInfo>()
            };

            info.PowerInputs.Add(new WTInfo {
                Blade1PitchPosition = (float)sensorData.GetValue("pitchAngle1"),
                Blade2PitchPosition = (float)sensorData.GetValue("pitchAngle2"),
                Blade3PitchPosition = (float)sensorData.GetValue("pitchAngle3"),
                OriginSysTime       = (string)sensorData.GetValue("originSysTime"),
                WindDir             = (float)sensorData.GetValue("windDirection"),
                WindSpeed           = (float)sensorData.GetValue("windSpeed"),
                YawPosition         = (float)sensorData.GetValue("yawPosition")
            });

            var tempValues = new TemperatureValues()
            {
                nacelle   = (float)sensorData.GetValue("nacelleTemp"),
                gearBox   = (float)sensorData.GetValue("gearboxTemp"),
                generator = (float)sensorData.GetValue("convTemp"),
            };

            // update sensor data on ADT
            string query = $"SELECT * FROM DigitalTwins T WHERE IS_OF_MODEL(T, 'dtmi:adt:chb:Sensor;1') AND T.deviceId = '{deviceId}'";
            DtIds  dtIds = await fetchDtIds(query);

            if (dtIds.sensor == null || dtIds.turbineObserved == null)
            {
                return;
            }
            client.UpdateDigitalTwin(dtIds.sensor, generatePatchForSensor(info.PowerInputs[0], tempValues));

            // update turbine data on ADT. We return index 0 since only a single
            // value should only be processed.
            var powerValues = new PowerValues()
            {
                powerObserved = (float)sensorData.GetValue("power"),
                powerDM       = (float)(await MlApi.GetPowerAsync(info.PowerInputs)).result[0],
                powerPM       = (float)(await PmAPI.GetPowerAsync(info.PowerInputs))[0]
            };

            client.UpdateDigitalTwin(dtIds.turbineObserved, generatePatchForTurbine(powerValues));
        }