I have an app that subscribes and publishes to topics on aws IoT. I am wondering what the difference between the two classes "device" and "thingShadow" are. This library gives examples of both and they both seem to have similar functionalities.
The device class is used to subscribe to and publish messages on MQTT topics for telemetry and messaging purposes.
The thingShadow class is a wrapper around the device class, which provides additional methods such as .register, .update or delete which are designed to interact with a device shadow. This class also emits specific events associated with a shadow lifecycle such as status, delta or foreignStateChange.
[...] the thingShadow class allows devices to update, be notified of changes to, get the current state of, or delete Thing Shadows from AWS IoT.
So basically, if you're using device shadows use the thingShadow class, otherwise you can use the device class.
EDIT:
To expand a bit more on the basic principles of AWS IoT, you have two communication scheme between devices:
Since AWS IoT implements a standard MQTT interface, you can use topics to communicate with your devices using a pattern called publish-subscribe. Your apps can subscribe to a topic and wait for a device to publish a message on it. Similarly, your app can publish a message on a device topic and have the device receive it.
AWS IoT implements a second communication interface called the device shadow, which allows you to address a device even when it is disconnected, and keep a synchronized state between your app and the device itself. The AWS documentation explains it in clear terms.
A thing shadow (sometimes referred to as a device shadow) is a JSON
document that is used to store and retrieve current state information
for a thing (device, app, and so on). The Thing Shadows service
maintains a thing shadow for each thing you connect to AWS IoT. You
can use thing shadows to get and set the state of a thing over MQTT or
HTTP, regardless of whether the thing is connected to the Internet.
Each thing shadow is uniquely identified by its name.
The two interfaces can be addressed in the SDK using the device class for subscribing and publishing on MQTT topics, and the thing shadow class to retrieve, update or delete a device thing shadow document.
Related
I have a need to poll for a close-to-real time reading from a serial device (using ESP32) from a web application. I am currently doing this using Particle Photons and the Particle Cloud API, and am wondering if there is a way to achieve similar using Google Cloud IoT.
From reading the documentation, it seems a common way to do this is via PubSub and then to publish to BigQuery via DataFlow or Firebase via Cloud Functions. However, to reduce pricing overhead, I am hoping to only trigger a data exchange(s) when the device receives an external request.
It looks like there is a way to send commands to the IoT device - am I on the right track with this? I can't seem to find the documentation here, but after receiving a command it would use PubSub to publish to a Topic, which can trigger a Cloud Function to update Firebase?
Lastly, it also looks like there is a way to do a GET request to the device's DeviceState, but this can only be updated once per second (which might also work, though it sounds like they generally discourage using state for this purpose).
If there is another low-latency, low-cost way to allow a client to poll for a real-time value from the IoT device that I've missed, please let me know. Thank you!
Espressif has integrated Google's Cloud IoT Device SDK which creates an authenticated bidirectional MQTT pipe between the device and IoT Core. As you've already discovered, you can send anything from the cloud to the device (it's called a "command" but it's just an MQTT payload so you can put almost anything you want in it) and vice versa (it's called "telemetry" but again it's just an MQTT payload). Once incoming messages from devices reach the cloud, pubsub can route them wherever you want. I don't know if I'd call it real-time, but latencies in a good WiFi network tend to be under a second.
I'm trying to play with AWS IoT to communicate with multiple identical devices.
So far, so good, all my devices are connected to it, and the only difference between them could be a single device ID (like a mac address or a serial number)
Now I'd like to send a message to a single specific device using its device ID and I don't know if there is a good way to do that?
I could make each device to subscribe to a topic like /<DEVICE_ID>, however it doesn't seem like a good practice especially if I have thousands of devices.
Plus, AWS discourages it as stated in the AWS IoT documentation:
Note
We do not recommend using personally identifiable information in your
topics.
Is there a good way to handle this use case? Or is AWS IoT only useful to manage multiple devices at once?
Here is the best practice for creating an MQTT topic.
https://www.hivemq.com/blog/mqtt-essentials-part-5-mqtt-topics-best-practices/
Talking about your specific case
Each device needs to have a unique identity to send a command to a particular device. In this case, you need to have device_id into your MQTT topic.
You can use the following pattern to send a message for a destination device
protocol_prefix / type_of_message / dest_id / message_id
hexaiot/controldevice/d12345/x123
Use wild card character at the time of device subscription to subscribe to the topic
Upon using the Google Cloud IoT Core platform, it seems to be built around the idea of sending configurations down to the device and receiving states back from it.
Google's own documentation suggests using that approach instead of building around sending commands down (as a config) and getting responses back (as a state).
However in the very end of the documentation they show an example of exactly that.
I am struggling to understand how does one support both approaches? I can see the benefit of how it was designed but I am also struggling to understand how would one be able to talk to the device using such an idiom of values and results as the config.
Has anybody implemented a command/response flow? Is it possible to subscribe to the state topic to retrieve the state of the device in my own application?
Edit based on clarifying comment below:
We've got a beta feature we're calling "Commands" which will do the reboot you're talking about. So the combination of config messages (for persistent configuration that you want to send a device on startup/connect to IoT Core) and Commands for fire and forget like a reboot message can do what your'e talking about. Current state is a bit trickier, in that you could either have a callback mechanism where you send a command to ask, and listen on the events/ channel for a response, or have the device report state (/state/ MQTT topic) and just ask IoT Core's admin SDK rather than the device.
Commands just went open beta, you should have access to it now. If you're using the gcloud SDK from command line, you'll need to do a gcloud components update and then gcloud beta iot devices --help will show the commands group. If you're using the console, when you drill down to a single device, you should now see "Send Command" next to "Update Configuration" on the top bar.
Old Answer: As a stab at answering, it sounds like rather than using the state topic, you could/should just use the standard /events/ topic and subscribe to the Pub/Sub topic the devices go into instead?
It really depends on the volume and number of devices we're talking about in terms of keeping that state machine in sync.
Without knowing what specifically you're implementing, I'd probably do something like send configs down, respond from device on the /events/ topic, and have a Cloud Function that tracks the Pub/Sub topic and updates something like a Firestore instance with the state of the devices, rather than using the /state/ topic. Especially if you're doing something in response directly to the state reporting of the device.
Send command to device
To send a command to a device, you will need to use the sendCommandToDevice API call.
Receive command from device
To receive a command from a device, subscribe to the /devices/<your-device-d>/commands/# topic.
Full examples will eventually be published to the Google Cloud IoT Core samples repos:
Java
NodeJS
Python
I am a newbie to AWS and cloud computing in general, so I apologize if this question is foolish.
I am currently working on developing an app for Amazon Echo that would allow it to remotely control a PC (i.e. change volume, pause a movie, etc.). My problem is that I do not know how to communicate between my Amazon Lambda service and my Windows Application.
Any ideas?
There are potentially some problems with the way you have posed the question -- how to communicate between a Lambda Function and a Windows machine could involve a number of different solutions, but what you are looking for (as far as I can tell) is a more specific -- yet simultaneously more generalizable -- solution.
Are you trying to actually make an Alexa skill that users could use, or just something for yourself? It makes a big difference, because for just yourself there are a number of hacky solutions you could implement, like port forwarding and dynamic DNS, which fail dramatically if you try to do them in the real world. You need another component -- some kind of real-time push messaging -- that bridges between an "agent" in your Windows app and requests emitted by your Lambda code.
Your actual problem to solve is not so much how to communicate between AWS Lambda and a Windows Application, but rather one of a need for understanding how a platform like Alexa needs to communicate with a "smart home" device, specifically an entertainment device.
It is a relatively complicated undertaking, because -- fundamentally -- there is no way of communicating directly between Lambda and an arbitrary device out on the Internet. Dynamic IP addresses, network address translation (NAT), firewalls, security considerations, and other factors make it impossible to reliably initiate a connection from a Lambda function (or indeed from any Internet connected device) to any other arbitrary destination device. Most devices (my phone, my Alexa-controlled light switch, my Windows laptop) are running behind a boundary that assumes requests are initiated behind the boundary. When I open web sites, stream video, etc., I initiate the request and the response returns on the channel (often a TCP connection) that I have created, from behind my boundary (e.g. the router in my cable modem) that doesn't allow external initiation of TCP connections. They are bidirectional once established, but must be initiated from inside.
Of course, you can statically "poke a hole" in your router configuration by forwarding a specific TCP port to a specific internal (usually private) IP address, which works as long as your Internet provider doesn't change your IP address, and your internal device doesn't get a new IP address... and there'a UPnP NAT Traversal, which seems like a good solution until you realize that it is also terrible (though for a "hobbyist" application, it could work).
While this is a long and complex topic, the short answer is that Alexa, via Lambda code, is only capable of initiating connections, and your device, wherever it may be, is only capable of initiating connections -- not receiving them... and thus you need some kind of "meet in the middle" solution: something that allows the device to maintain its "connection" to a central "service" that can coordinate the interactions on demand.
For example:
AWS IoT Core is a managed cloud platform that lets connected devices easily and securely interact with cloud applications and other devices. AWS IoT Core can support billions of devices and trillions of messages, and can process and route those messages to AWS endpoints and to other devices reliably and securely. With AWS IoT Core, your applications can keep track of and communicate with all your devices, all the time, even when they aren’t connected.
https://aws.amazon.com/iot-core/
The client initiates the connection (e.g. via a web socket) to the IoT platform, and maintains it, so that when a message arrives at IoT, the service knows how to deliver that message to the client when it's received. ("even when they aren't online" refers to the "device shadow" capability, which allows you to programmatically interact with a proxy for the device, e.g. knowing the last temperature setting of a thermostat, and asking the thermostat to change its set point when the connection is re-established at some future point).
Or, potentially something like this:
Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost.
Using FCM, you can notify a client app that new email or other data is available to sync.
https://firebase.google.com/docs/cloud-messaging/
Both of these potential solutions solve the problem by "knowing how to contact" arbitrary devices, wherever they may be... and I would suggest that this is the core of your actual need.
There are a lot of alternatives for such a "service," including roll-your-own websocket or HTML EventSource implementations with servers... the purpose of this is not product recommendations but rather to give you an idea of what you would need for such a scenario -- an intermediate platform that can be interacted with by the Lambda code, which also knows how to communicate with "agent" code running on the device... because both Lambda and the agent need to initiate the communication channels and thus additional components are required to bridge them together.
I am trying to send chunks of a data by using MQTT to aws IoT and by rule engine, the data will be streamed to a web app in real time (or near to real time )manner.
I am trying to find a way by which I can get some kind of acknowledgement. the role of acknowledgement is important for my use case as I am trying to send some kind of medical equipment data (lets say blood pressure data during operation).
thus, In a nut shell, I need a quickest way to transfer data(just like MQTT) between the device and AWS IoT which should have some kind acknowledgement mechanism.
Also I would like to add that ,'if suppose the device or web server could not get the message sent by MQTT due to some internet issues, then it will be lost right. I need to add some sort of mechanism by which the mqtt messages could be buffered and queued for some time so that once the device or web app comes online it can get the queued data. I also know that there is something called device shadow but we have thought using it differently. can you suggest about it ?'
I am sure that some of you have faced this problem and also found an alternate of MQTT in data transferring to AWS IoT.
Kindly share your thoughts.
Thanks.