This workflow uses IoT Hub twins to signal Device Update intent for simulator devices.

Prerequisites

  • IoT Hub Standard tier (S1 or higher)
  • Azure CLI with azure-iot extension
  • IOTHUB_NAME environment variable set, or pass -HubName
  • Simulator running from csharp_simulator

1. Generate devices.json (if needed)

.\3_Simulator\generate_devices_json.ps1

2. Start simulator

.\3_Simulator\run_10_devices.ps1

3. Set ADU target version intent

All devices (device1..device10):

.\4_ADU\adu_set_target_version.ps1 -TargetVersion 1.1.0

Single device:

.\4_ADU\adu_set_target_version.ps1 -TargetVersion 1.1.0 -DeviceId device1

4. Check ADU status

.\4_ADU\adu_get_status.ps1

Expected behavior:

  • desiredTargetVersion set to target release
  • restartRequested becomes True for affected devices
  • simulator reports state then exits to allow external update workflow

5. Clear/rollback ADU intent

All devices:

.\4_ADU\adu_clear_target_version.ps1

Single device:

.\4_ADU\adu_clear_target_version.ps1 -DeviceId device1

6. Restart simulator after external update workflow

.\3_Simulator\run_10_devices.ps1

Notes

  • This simulator does not install packages by itself.
  • It only signals update intent and restart handoff through twin properties.

Addendum: Practical Update Sequence

Question:

  • To do a device update do you update code, set new version, and run the simulator again?
  • Do devices need stopping first?

Answer:

  1. Update the simulator code.
  2. Bump app version in csharp_simulator/Program.cs (AppInfo.Version) to your new version.
  3. Set the new desired target version:
.\4_ADU\adu_set_target_version.ps1 -TargetVersion 1.1.1
  1. Restart simulator processes so they pick up the new build.

Recommended restart flow:

.\3_Simulator\stop_10_devices.ps1
.\3_Simulator\run_10_devices.ps1

Notes:

  • In this simulator pattern, ADU twin intent does not install binaries.
  • New code is only picked up when simulator processes are started again.
  • If devices already exited after restartRequested=True, stop may find nothing, which is fine.

Quick Copy/Paste Checklist

# 1) Build/publish new simulator code and bump AppInfo.Version in csharp_simulator/Program.cs

# 2) Set desired ADU target version (match AppInfo.Version)
.\4_ADU\adu_set_target_version.ps1 -TargetVersion 1.1.1

# 3) Optional: confirm restart requested/status
.\4_ADU\adu_get_status.ps1

# 4) Restart simulator processes
.\3_Simulator\stop_10_devices.ps1
.\3_Simulator\run_10_devices.ps1

# 5) Verify running state after restart
.\4_ADU\adu_get_status.ps1

Addendum 2: What Is Preserved Between ADU Restarts?

Preserved across restart

  • IoT Hub twin desired properties in cloud, including desired.sim settings.
  • IoT Hub twin desired ADU intent, including desired.du.targetVersion.
  • Device identities in IoT Hub.

Reset on restart

  • In-memory simulator runtime state such as:
    • sendCount
    • storedText
    • storedNumber
    • telemetryEnabled

What happens on next startup

  1. Simulator starts with default in-memory state.
  2. It reconnects and loads twin desired properties.
  3. It reapplies desired simulator config from twin.
  4. It compares desired.du.targetVersion with AppInfo.Version.

If target version still differs from app version, the simulator sets restart requested again and exits (expected behavior). If target version matches app version, it continues running normally.

Addendum 3: How Desired vs Reported Twin Properties Are Set

In this workflow:

  • Desired properties are set from the cloud/service side (Azure CLI/scripts).
  • Reported properties (actual runtime state) are set by the simulator app.

Desired (set from scripts)

ADU desired target version is written with:

.\4_ADU\adu_set_target_version.ps1 -TargetVersion 1.1.1

which runs az iot hub device-twin update against:

  • properties.desired.du.targetVersion

Desired values represent what you want the device to do/configure.

Reported (set by simulator)

When the simulator runs, it reports current state back to IoT Hub under:

  • properties.reported.sim.*
  • properties.reported.app.*
  • properties.reported.du.*

This includes values like current simulator settings, app version, restart requested flag, and last state timestamps.

Practical model

  1. Cloud writes desired.
  2. Device applies/observes desired.
  3. Device publishes reported actual state.

adu_get_status.ps1 shows both desired and reported values side-by-side so you can confirm whether device state has converged to the requested state.

Example Twin Shape (One Device)

{
	"deviceId": "device1",
	"properties": {
		"desired": {
			"sim": {
				"intervalSeconds": 3,
				"randomEvery": 10,
				"tempMin": 15,
				"tempMax": 40,
				"baseTemp": 23
			},
			"du": {
				"targetVersion": "1.1.1"
			}
		},
		"reported": {
			"app": {
				"name": "csharp-simulator",
				"version": "1.1.1"
			},
			"sim": {
				"intervalSeconds": 3,
				"randomEvery": 10,
				"telemetryEnabled": true,
				"sendCount": 42,
				"lastState": "connected",
				"lastUpdateUtc": "2026-07-11T06:00:00.0000000Z"
			},
			"du": {
				"targetVersion": "1.1.1",
				"restartRequested": false,
				"note": "Device Update package installation is external to this app."
			}
		}
	}
}

 TopicSubtopic
  Next: > IoT Hub
<  Prev:   IoT Hub
   
 This Category Links 
Category:IoT Index:IoT