iothub
iothub copied to clipboard
Send a message from a device to the hub
I was trying to send a message from a device running a module (my go application) to the IoT hub.
On the device I have iotedge
installed in version 1.0.10.1
. At first I tried to build the sample, provided in the readme:
package main
import (
"context"
"log"
"os"
"github.com/amenzhinsky/iothub/iotdevice"
iotmqtt "github.com/amenzhinsky/iothub/iotdevice/transport/mqtt"
)
func main() {
c, err := iotdevice.NewFromConnectionString(
iotmqtt.New(), os.Getenv("IOTHUB_DEVICE_CONNECTION_STRING"),
)
if err != nil {
log.Fatal(err)
}
// connect to the iothub
if err = c.Connect(context.Background()); err != nil {
log.Fatal(err)
}
// send a device-to-cloud message
if err = c.SendEvent(context.Background(), []byte(`hello`)); err != nil {
log.Fatal(err)
}
}
Even though this works, it requires me to add the connection string to the environment variables of my container. On a container for a module I have the following environment variables set:
- IOTEDGE_APIVERSION
- IOTEDGE_AUTHSCHEME
- IOTEDGE_DEVICEID
- IOTEDGE_GATEWAYHOSTNAME
- IOTEDGE_IOTHUBHOSTNAME
- IOTEDGE_MODULEGENERATIONID
- IOTEDGE_MODULEID
- IOTEDGE_WORKLOADURI
- RuntimeLogLevel
- PATH
After looking a bit around in the code, I found the function NewModuleFromEnvironment()
which is reading most of those variables, so I adjusted the code and tried to run it:
package main
import (
"context"
"log"
"github.com/amenzhinsky/iothub/iotdevice"
iotmqtt "github.com/amenzhinsky/iothub/iotdevice/transport/mqtt"
)
func main() {
c, err := iotdevice.NewModuleFromEnvironment(
iotmqtt.New(),
false,
)
if err != nil {
log.Fatal(err)
}
// connect to the iothub
if err = c.Connect(context.Background()); err != nil {
log.Fatal(err)
}
// send a device-to-cloud message
if err = c.SendEvent(context.Background(), []byte(`hello`)); err != nil {
log.Fatal(err)
}
}
My application always exits with:
2020/11/12 15:15:02 Connect:
2020/11/12 15:15:02 not Authorized
And I'm unable to tell what part is missing. Other packages can send messages quite fine when only the selected settings are provided. Any idea how I can send a message from a Go module without providing the connection string to each and every module?
Same issue here. Did you find a solution yet?
All module required variables are listed here: https://github.com/amenzhinsky/iothub/blob/master/common/sas.go#L59
Can you make sure you have everything you need?
Not sure, probably something could change over a version.
@amenzhinsky thanks for responding.
I guess the problem is that the current implementation needs the device connection string to extract things like SharedAccessKey
.
If i look at the python SDK for Azure IoT Hub (https://github.com/Azure/azure-iot-sdk-python/blob/e7e8bbeed79063873ef9df3bf2040b2f92fb01a7/azure-iot-device/azure/iot/device/iothub/abstract_clients.py#L559) i see that there are two ways:
- (default) use with iot hsm object (https://github.com/Azure/azure-iot-sdk-python/blob/e7e8bbeed79063873ef9df3bf2040b2f92fb01a7/azure-iot-device/azure/iot/device/iothub/abstract_clients.py#L613) This way it seems to connect to talk to some Azure edge module (hub or agent) to make the credential exchange (https://github.com/Azure/azure-iot-sdk-python/blob/e7e8bbeed79063873ef9df3bf2040b2f92fb01a7/azure-iot-device/azure/iot/device/iothub/edge_hsm.py#L25)
- Use with device connection string (https://github.com/Azure/azure-iot-sdk-python/blob/e7e8bbeed79063873ef9df3bf2040b2f92fb01a7/azure-iot-device/azure/iot/device/iothub/abstract_clients.py#L572)
How things look, this library implements only way the second way (device connection string). This however is a problem, because i cannot put the device connection string in a generic deployment matching several devices. Do you have any suggestions?
Hi! I fixed my problem. I did use the iotmqtt.New() which didn't return a module mqtt client.
I use this now without providing the connection string. Works like a charm.
c, _ := iotdevice.NewModuleFromEnvironment(iotmqtt.NewModuleTransport(), true)
You're right transports API is a bit confusing, I think we need separate module and device transport interfaces or join them together.
i'm trying as suggested by @siredmar but still gettin not autorized
I'm trying to send a message but when it arrives its all jumbled. The internet says that I need to set these values in systemProperties
"iothub-content-type": "application/json",
"iothub-content-encoding": "utf-8",
Is this possible?
Also how to set "dt-subject": "<string goes here>"
Seems like common.Message needs to be modified.