I am trying to fetch device twin properties within an IoT Edge module, and while I am already connected with a module client (aka IoTHubModuleClient), I've found a method called get_twin() in the documentation that says that we can grab device or module twin properties. However, I am getting "empty" properties, here's the result:
{'desired': {'$version': 1}, 'reported': {'$version': 1}}
Which is not what I configured in the azure portal in device twin section. But using the IotHubDeviceClient with a device connection string (that's why I don't want to use that client), I am able to get the right device twin properties.
The code is pretty basic:
client = IoTHubModuleClient.create_from_edge_environment()
twin_properties = await client.get_twin()
logger.debug(f'Twin properties: {twin_properties}')
That is correct Mehdi, when you use the IoTHubModuleClient's get_twin method you are getting the module twin properties, you can add/modify/delete module twin properties independently of device twin properties.
Please take a look of this article
Related
Years ago I built a temperature sensor that would push (http post) readings to a server / dashboard system I had written. In lieu of expanding requirements, I've decided to switch to Home Assistant as my backend. Though it is possible to send the data to HA, the documentation is spotty. Namely I'm looking for the full JSON for the post body (an OpenAPI spec would be nice) and more details around how sensors function, and things "like can I set a unique_id so that they are editable in HA?", etc.
So far I've been working off the little bits of information around the API, some examples, and inferences from other documents for the python api (internal server code).
REST API
https://developers.home-assistant.io/docs/api/rest/
Sensor post info from HTTP integration
https://www.home-assistant.io/integrations/http/#sensor
General Sensor Docs
https://www.home-assistant.io/integrations/sensor#device-class
Perhaps what you're looking for is value_json?
Here's how I'm fetching value out of a simple webserver which returns this basic json object { key: value }, although one difference is that I'm polling and using GET.
rest:
- resource: http://192.168.0.122/status
sensor:
- name: "Data from my server"
value_template: "{{ value_json.key }}"
Tip: Go to Developer Tools -> Template for a sandbox-like environment where you can rapidly prototype your value_template
I am attempting to route device telemetry data for a device connected to Azure IoTHub.
I have defined the custom endpoint in message routing to a storage account with the Encoding format set to JSON and routing query set to true.
This has successfully sent the data to the storage account but the telemetry data in the message body is in base 64 shown below
{"EnqueuedTimeUtc":"2022-07-13T13:03:28.4770000Z","Properties":{},"SystemProperties":{"connectionDeviceId":"SensorTile","connectionAuthMethod":"{\"scope\":\"device\",\"type\":\"sas\",\"issuer\":\"iothub\",\"acceptingIpFilterRule\":null}","connectionDeviceGenerationId":"6*********971","enqueuedTime":"2022-07-13T13:03:28.4770000Z"},"Body":"eyJBY2NlbGVyb21ldGVyIjp7IlkiOi0xNSwiWCI6MTAsIloiOjEwMzZ9LCJ0cyI6IjIwMjItMDctMTNUMTU6MDM6MjguNDAwKzAyMDAiLCJpZCI6IlNlbnNvclRpbGUifQ=="}
Reading the documentation
"When using JSON encoding, you must set the contentType to application/json and contentEncoding to UTF-8 in the message system properties. Both of these values are case-insensitive. If the content encoding is not set, then IoT Hub will write the messages in base 64 encoded format."
I understand it is possible to translate the data to a UTF-8 format by setting the systemProperties contentType to application/json and contentEncoding to UTF-8 but I am unsure where and how to actually do this or can I use another service such as Stream Analytics/Fuctions/EventHub to achive this?
Also is it possible to filter messages via route query so that only telemetry data is routed ignoring the rest?
Any help is greatly appreciated
The content type and content encoding need to be set when sending the message. That means the device is in charge of setting the properties. Here's a few examples in different languages.
C#
using var eventMessage = new Message(Encoding.UTF8.GetBytes(messagePayload))
{
ContentEncoding = Encoding.UTF8.ToString(),
ContentType = "application/json",
};
C
IOTHUB_MESSAGE_HANDLE message_handle = IoTHubMessage_CreateFromString(message);
(void)IoTHubMessage_SetContentTypeSystemProperty(message_handle, "application%2fjson");
(void)IoTHubMessage_SetContentEncodingSystemProperty(message_handle, "utf-8");
Java
Message msg = new Message(msgStr);
msg.setContentType("application/json");
msg.setProperty("temperatureAlert", temperature > 28 ? "true" : "false");
Setting content type and content encoding is the responsibility of the IoT device that is sending messages to the IoT hub. Setting these values depends on the language-specific device SDK used by the IoT device.
Without these settings, the message routing queries based on the message body won't work as mentioned in this link. Also to filter messages based on the telemetry data, you don't need filtering queries. You can create a route with 'Data source' - 'Device Telemetry Messages' so that only device telemetry data will be routed. Please find the attached screenshot for reference:
I've been trying to use the R-R interval's sensor in the Microsoft band SDK, but I can't find anything related to the sensor either on the internet and the documantation.
Could you explain me how to use it and/or give an example code?
The SDK documentation provides a sample for the Heart Rate sensor data and the logic is the same for RR interval. Go to section 5, page 17: https://developer.microsoftband.com/Content/docs/Microsoft%20Band%20SDK.pdf
Below are snippets if you are using the Android SDK.
First, create the event listener:
BandRRIntervalEventListener rrIntervalListener = new BandRRIntervalEventListener() {
#Override
public void onBandRRIntervalChanged(BandRRIntervalEvent event) {
// add your logic
}
};
Then register the listener (handle your BandException):
bandClient.getSensorManager().registerRRIntervalEventListener(rrIntervalEventListener);
When you are done, unregister your listener (handle your BandException):
bandClient.getSensorManager().unregisterRRIntervalEventListener(rrIntervalEventListener);
Don't forget to get user consent first, this is very important and the SDK documentation explains how to do that as well.
You will find an example with exactly that in the BandRRIntervalApp folder in the Band Android SDK and samples package. This includes subscribing to the sensor, displaying the value and getting user consent if necessary.
Using external hardware triggering of a UVC compliant USB3.0 camera, I want to acquire still images utilizing Directshow in our Visual C++ code. Using an API supplied by the camera manufacturer we can set the camera in External Trigger Mode . With the camera in Master Mode (“Free Running Mode” with no external triggering) we get the proper event notification code in our DirectShow VC++ program. However, we don’t get the proper event notification code when triggering the camera externally in External Trigger Mode, as described below.
To get the event notification code of the event interface IMediaEventEx *pEvent of the running filter graph we call
hr = pEvent->WaitForCompletion(INFINITE, &evCode);
or
while (hr = pEvent->GetEvent(&evCode, ¶m1, ¶m2, 0), SUCCEEDED(hr))
{
hr = pEvent->FreeEventParams(evCode, param1, param2);
if ((evCode == EC_COMPLETE))
{
break;
}
}
In Master Mode (no external trigger) we obtain the event notification code EC_COMPLETE for evCode (i.e. all data has been rendered) and to grab the image data from the camera we can call
hr = pSGrabber->GetCurrentBuffer(&cbBufSize, NULL);
and
hr = pSGrabber->GetCurrentBuffer(&cbBufSize, (long*)pBuffer);
Here pSGrabber is the ISampleGrabber interface for the Sample Grabber Filter.
However, in External Trigger Mode for evCode we only get the event notification code EC_ACTIVATE and therefore we cannot grab any image data. It can also be noted that via the IAMVideoControl interface for the still Pin we set the flag for external trigger
hr = pAMVidControl->SetMode(pPinStill, VideoControlFlag_ExternalTriggerEnable);
where IPin *pPinStill is the pointer to the still Pin.
We know that the external trigger pulses we use are adequate for triggering the camera, because with a commercial piece of software we succeed with triggering the camera externally. Therefore, I believe the problem is related to DirectShow programming. Does anyone have experience with grabbing image data in DirectShow when using external triggering of a camera? Or point to some source of information?
Thank you very much.
I have an app that connects to a bluetooth LE peripheral. Is it possible to change the peripheral's name from the app. In other words I want to rewrite the peripherals localized name from the central device. I can get the name through the advertised data and only connect to the peripheral if it have a certain name. but I would like the user to be able to change the peripheral's name so only they can connect to that specific peripheral from the app.
I'm not sure if my peripheral allows it or not. How would I check and How would I write the new name??
I have used the following code to get the service device information and then to get the manufacturers name
if([service.UUID isEqual:[CBUUID UUIDWithString:#"180A"]]) {
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(#"discovered characteristic %#", characteristic.UUID);
if([characteristic.UUID isEqual:[CBUUID UUIDWithString:#"2A29"]]) {
NSLog(#"Found Notified Characteristic %#", characteristic);
self.mycharacteristic2 = characteristic;
[self.testPeripheral setNotifyValue:YES forCharacteristic:characteristic];
[self.testPeripheral readValueForCharacteristic:mycharacteristic2];
NSLog(#"value:%#",mycharacteristic2.value);
}
} NSLog(#"services%#",service);}
however if I substitute 2A00 (which is supposed to be the UUID for the device Name) I get nothing.
I have also tried to use 1800 for generic access and 1801 for generic information but I don't get any response for the device name 2A00.
I do get a log that 1801 is Device information but no information for 2A00 which is supposed to be Device Name. Does anyone know how to access the Device Name characteristic UUID?
You need to check the properties property of the characteristic. You'd be looking for CBCharacteristicPropertyWrite.
Also, are you absolutely sure the peripheral supports 2A00? Try using the app LightBlue to browse all the available services and chacteristics.