0

I am trying to implement this same method in C# but can't find an equivalent for the javascript const patch = {..}

I also don't really understand what is going on here - why does the patch have a property 'rundiagnostics' which seems to be the method name, and why are the twin reported properties being updated.

I am wanting to process a long running command and reflect the result in the commands response. It is not entirely clear how IoT Central handles the long running commands so any additional explanation would be welcome. Maybe a sequence diagram or two (??).

Link to docs here

client.onDeviceMethod('rundiagnostics', commandHandler);

// ...

const commandHandler = async (request, response) => {
  switch (request.methodName) {
  case 'rundiagnostics': {
    console.log('Starting long-running diagnostics run ' + request.payload);
    await sendCommandResponse(request, response, 202, 'Diagnostics run started');

    // Long-running operation here
    // ...

    const patch = {
      rundiagnostics: {
        value: 'Diagnostics run complete at ' + new Date().toLocaleString()
      }
    };

    deviceTwin.properties.reported.update(patch, function (err) {
      if (err) throw err;
      console.log('Properties have been reported for component');
    });
    break;
  }
  default:
    await sendCommandResponse(request, response, 404, 'unknown method');
    break;
  }
};
Matthijs van der Veer
  • 3,865
  • 2
  • 12
  • 22
Duncan Groenewald
  • 8,496
  • 6
  • 41
  • 76

2 Answers2

0

You define your patch as a string like this:

    var patch =
        @"{
            tags: {
                location: {
                    region: 'US',
                    plant: 'Redmond43'
                }
            }
        }";

And probably you need to change your whole script to C# equivalent.

See https://learn.microsoft.com/en-us/azure/iot-hub/device-twins-dotnet for detailed C# example.

Orifjon
  • 915
  • 8
  • 25
  • Thanks that solved the patch equivalent but can you explain the logic behind patching reported results and the use of the property "rundiagnostics" given that is apparently a command. Does IoTCentral automatically match that to the original command request response or will that create a new Twin property ? – Duncan Groenewald Aug 23 '23 at 05:48
0

I also don't really understand what is going on here - why does the patch have a property 'rundiagnostics' which seems to be the method name, and why are the twin reported properties being updated.

IoT Hub (that IoT Central uses) has no support for long-running tasks natively. They way that it's implemented is by using a Direct Method to contact the device. The device needs to respond within 300 seconds (this is an IoT Hub limit, IoT Central might limit it even more, I don't remember). To get around this limitation for long running tasks, IoT Central allows the device to respond with 202 accepted instead. The reported property update is done with the same name as the method so that IoT Central understands that it's related to the Direct Method that was called. So in essence the reported property update signals IoT Central that the work is done.

As for the patch, you could go with a string, but the C# DeviceClient does not support a string in deviceClient.UpdateReportedPropertiesAsync(). The RegistryManager in the other answer does, but that's not what you need on the device side. You need to turn the string into a TwinCollection, or just use an object:

var patch = new
{
    rundiagnostics = new
    {
        value = $"Diagnostics run complete at {DateTime.Now}"
    }
};

var twinCollection= new TwinCollection(JObject.FromObject(patch), null);
Matthijs van der Veer
  • 3,865
  • 2
  • 12
  • 22
  • Oh, so I assume I can set the timeout - I only need 30 seconds. So this IoT Central workaround - does that result in the Command response itself being updated with the result ? Or does it add some new property to the device twin ? In any event I really want the data return to be graphed so I think it might be best to send a Telemetry message back - but perhaps also complete the command. – Duncan Groenewald Aug 23 '23 at 11:54
  • In your case, the standard command functionality can be used as it has a timeout of [30 seconds](https://learn.microsoft.com/en-us/azure/iot-central/core/howto-use-commands?WT.mc_id=IoT-MVP-5004034#standard-commands). Completing the command and sending telemetry is perfect. Definitely make sure to complete the command, or IoT Central will assume there's an issue with the command. – Matthijs van der Veer Aug 23 '23 at 12:07
  • By completing the command I assume you mean that, in addition to sending the Ack 202 immediately, I need to send the 200 response code once the job has finished running. Assuming the job may run longer than the timeout period. – Duncan Groenewald Aug 23 '23 at 13:21
  • Minor aside but any way to set the default y-axis type for a dashboard graph? – Duncan Groenewald Aug 23 '23 at 13:23
  • 1
    You can only respond to a direct method once. So if you're going to reply with telemetry later, just send the 200 right away. – Matthijs van der Veer Aug 25 '23 at 07:23