Created a test DTDL model class with one of the writable property as false and another writable property as true as defined in this model
Even though writable property is false, this below code is executed without any issues. How can I make only readable properties in DTDL?
BasicDigitalTwin twinData = new BasicDigitalTwin();
twinData.Id = "123Test";
twinData.Metadata.ModelId = "dtmi:DigitalTwins:test;2";
twinData.CustomProperties.Add("testprop1", "test1");
twinData.CustomProperties.Add("testprop2", "test2");
twinData.CustomProperties.Add("testprop3", "test3");
await client.CreateDigitalTwinAsync(twinData.Id, JsonSerializer.Serialize(twinData));
Writable properties only play a role in the Device Twin in IoT Hub, and not in Azure Digital Twins. This document tries to shed some light on it, but I can understand the confusion.
The Digital Twin Definition Language (DTDL), is used to describe digital twins in Azure Digital Twins (ADT), but also the capability model for IoT Plug and Play. While writable properties are part of the DTDL language, it's not playing a role in ADT.
Related
I have location added to a space that sits 2 levels above sensor but I am finding no way with the current client reference operation to get the location as I want to enrich the telemetry with space location information.
I have used the following
getSpaceMetadata
getSpaceExtendedProperty(spaceId, propertyName) //As it is not extended property
I need the functionality similar to this
https://urlofdigitaltwin/management/api/v1.0/spaces/633a40d6-790d-4bd5-92c5-1cc8b1a86141/?includes=location
Please let me know if there is a way I can always do it inside some other azure service by going and reading these separately.
space with location
device
sensor
-matcher
-udf
Thanks for the great question! Azure Digital Twins is undergoing continuous improvement. I hope you'll find the documentation significantly improved.
Assuming you have extracted the location ID from the sensor or device, you can find the associated parentSpaceId:
{
"id": "aa000aaa-a0a0-0000-a0aa-00000a000aa0",
"name": "Example Room",
"typeId": 14,
"parentSpaceId": "1b1b1111-b1b1-1111-111b-1b1b11b11111",
"subtypeId": 13,
"statusId": 12
}
From there you can call the top-level space directly. You can combine that operation with several API query parameters such as traverse, minLevel, and maxLevel which should allow you to fetch everything you need in one call.
Two new resources that describe those API operations are now available:
https://learn.microsoft.com/azure/digital-twins/how-to-navigate-apis
https://learn.microsoft.com/azure/digital-twins/how-to-query-common-apis
Thanks!
I have created an IoT Hub Edge device. In the beginning, the default $edgeAgent and $edgeHub modules went in. That's fine. Then I added a "barkModule" (note the lower-case B at the start) -- just a test module to play with D2C event messages and DirectMethod calls to the module.
Later on, I removed that module and added a new one, this time with BarkModule (capital B). Been rocking this way for about a week.
I did this bit of code to get a list of a devices module twins (_deviceTwins is the twins of all the devices on the hub, this is basically just getting all the modules for the device) :
foreach (var _device in _deviceTwins) {
var moduleList = await registryManager.GetModulesOnDeviceAsync(_device.DeviceId);
DeviceList.Add(new DeviceAndModules { DeviceTwin = _device, Modules = moduleList.ToList() });
};
In its module twin list -- I'm getting an entry for both BarkModule and barkModule. Even though my device just has $edgeAgent, $edgeHub and BarkModule modules.
I even went digging in $edgeAgent's module twin, and there's a ton of meta-data event history stuff (seriously, this is absurdly large) -- but there's NO reference to the lowercase-b "barkModule" anywhere.
How is it maintaining this information? Why is this showing up still? Is there a way I can remove this?
This shows the modules:
This shows there's only three:
I am using the UEFI EDK2 to create a BIOS. I have modified the FDF to move a driver (both UEFI and legacy versions) from the main firmware volume into a separate firmware volume (FV) that I created strictly to hold the driver.
Before I moved the driver from the main FV, I would see the legacy OROM sign-on during POST. However, since I have moved the driver to the new FV, I no longer see the legacy OROM sign-on. It would seem the legacy OROM is no longer being loaded.
It seems that EDK2 "automatically" loads only certain FVs and then dispatches their drivers, but I can't figure out how these particular FVs are identified in EDK2.
I have searched the EDK2 code for several hours trying to find out where/how the FV HOB is created/initialized, but I cannot find this code. I'm guessing I need to add the new FV's GUID to some list or data structure, but I'm really guessing at this point.
Any pointers would be greatly appreciated.
I found the location in the BIOS where the firmware volume HOBs are created (in a proprietary file). I added code there to create a FV HOB for my new firmware volume.
After that, I had to install a PPI that could process the new firmware volume. Here is the PPI creation code:
static EFI_PEI_FIRMWARE_VOLUME_INFO_PPI mNewFvPpiInfo = {
EFI_FIRMWARE_FILESYSTEM2_GUID,
(VOID*) <Starting address of new FV in the ROM>,
<size of the new FV in the ROM>,
NULL,
NULL
};
static EFI_PEI_PPI_DESCTRIPTOR mNewFvPpi = {
(EFI_PEI_PPI_DESCTRIPTOR_PPI | EFI_PEI_PPI_DESCTRIPTOR_TERMINATE_LIST),
&gEfiPeiFirmwareVolumeInfoPpiGuid,
&mNewFvPpiInfo
};
Here is the code that installs the PPI (placed after the new FV HOB is added to the FV HOB list):
(*ppPeiServices)->InstallPpi(ppPeiServices, &mNewPvPpi);
I have this line of code in my Delphi app:
sh := CoShellWindows.Create;
When run through a Citrix session, this raises an exception "Not enough storage is available to complete this operation."
Can someone confirm my suspicion that I can't access this through Citrix? I'm running in Seamless mode if that makes any difference. Maybe there's something I need to change on the published icon to make it work?
I am guessing that there is no "Shell" in Citrix to create.
Thanks
EDIT
The CoShellWindows is simply a class which creates an object which implements the IShellWindows interface. This interface is then used to iterate through it's items looking for an instance of Internet Explorer (or more specifically, an item which implements the IWebBrowser2 interface).
There are a few other use case scenarios using the CoShellWindows, but all ultimately are used to interact with the IWebBrowser2 interface (Internet Explorer 8). My requirement is to obtain this IWebBrowser2 object.
The call, behind the scenes is calling the Windows API CoCreateInstance with the following parameters:
rclsid = {9BA05972-F6A8-11CF-A442-00A0C90A8F39} (CLSID of
IShellWindows)
pUnkOuter = null (nil)
dwClsContext = CLSCTX_ALL (I've tried various combinations of these
flags)
riid = {85CB6900-4D95-11CF-960C-0080C7F4EE85} (IID of IShellWindows)
ppv = a variable declared as type IShellWindows
eg:CoCreateInstance(CLASS_ShellWindows, nil, CLSCTX_ALL, IID_IShellWindows, sh)
Your exception "Not enough storage is available to complete this operation." should really read "Shell does not exist so no instance can be created"
Basically you are correct in your assumption that there is no shell to create in Citrix.
What are you using the shell for? as if you provide more information we may well be able to offer a full work around.
I'm using CreateService to install a windows service on Windows XPE. I'd like to set things up so that only the Administrator can start/stop/pause/resume the service.
Right now I'm using the following to install the service:
schService = CreateService(schSCManager,
ServiceName,
ServiceDisplayName, // service name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
binaryPathName, // service's binary (this program)
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // no dependencies
NULL, // LocalSystem account
NULL); // no password
And the service ends up with security such that members of the PowerUsers group can start and stop the service. I've figured out that I can use sc sdshow to examine the security descriptor, and I've worked out an SDDL line that would do the right thing for us.
I've also learned that our Win XPE install doesn't have the sc.exe binary on it, so we can't really use that to setup this particular system.
So, what I need to know is: What are the APIs I need to use, to set the security descriptor on this service around the time I do the CreateService call. I'm completely unfamiliar with the Windows security APIs, so I just don't know where to start.
UPDATE: The answer is SetServiceObjectSecurity (below). Next question: What's the best way to setup the SecurityDescriptor? Is it best to get the default descriptor, then modify it? Or should I just create a completely new descriptor?
I'm not really familiar with Windows XP Embedded, but normally you would achieve what you are after using the SetServiceObjectSecurity function. Use the handle you get from CreateService and build a security descriptor that matches what you want.