In fact, not only about protocols, but rather about the logic of interaction between complex systems. This is not BigData, of course, but there is still something to break your head and spears.

At the very beginning of development, I threatened that I would talk about it on the air, so that any reader could participate in this entertaining process. And now, the time has come. Our prototype is almost ready, and we are now engaged in documentation for production and for developing a server and a mobile application. And they understood that the prototype is the simplest, and all the tasks that we solved in it are like that, kindergarten, pants with straps.
Do you ever think about how complex logic works when you send a tweet or post a photo? It is not visible, in 99.9% it is hidden from the user, and it is completely unnoticeable. I did not notice it either, until the moment when I had to design it myself.
')
Go!
Here you make a kettle. While it is controlled directly from the phone, like our prototype, everything is simple and logical:

There is a local network, there are clients, there is a device. There is no server, no accounts, no authorization. Beauty. We buy a kettle, bring it home, and connect it to the network. How do we connect?
First use
We proceed from two facts: at home, a user may not have WiFi at all, and if she does, we do not know her name and password. Therefore, in the process of setting up, the user must transfer the name and password to the teapot so that he can log in to the network.
You can do this in several ways: you can type the network name and password with buttons, you can transfer the phone screen blinks, or peep into
DTMF codes, or you can create a previously known WiFi network to which you need to connect and configure the kettle inside it using the application. After some discussion, we decided to use the last option. This is not a final decision, and readers, as future users, can influence it - after the article choose an option in the vote.
But for the time being I will proceed from the WiFi authorization option.

When you first turn on the device creates an open WiFi-network with a pre-specified name (so that it can be found), but with a random insert at the end (so that several simultaneously connected dummies do not interfere with each other), something like AVI-WifiKettle-6574.
The application connects to it, asks the user to create a network or connect to the current one, and the name with a password. And depending on the previous question, the kettle after the end of the configuration either creates a network or connects to the current one.
Everything is simple and clear. It is also quite simple to send a command from application to device:

The application connects to the kettle, sends the command. After checking the correctness of the command (the parser worked without errors, the device type and the language version match the target one), the teapot says that it received the command, and starts to execute it. After executing the command, the kettle reports that the command is executed, and the application can please the user with the message “Your kettle has boiled over”.
Complicate the task. Now we also have a server for remote management.
But not everything is so simple. We want remote control, right? For this we have to enter another element - the server. The scheme takes the following form:

Not very difficult to look like. But the complexity of the logic increases when adding a server by an order of magnitude.
Here, for example, how the first inclusion began to look from the side of the application:

Authorization appeared (we don’t want anyone to turn on our kettle), which means support for accounts. When enabled, the program should ask the user whether he wants to enter an existing account, or create a new one. To somehow distinguish the devices from each other, we enter the serial number of the device UUID-D (Device). It is generated by the program and transmitted to the device at the first connection. Further, from the device, the user will not be able to get the UUID-D, only to completely reset and set a new one. At the same time, without knowing the serial number of the device, you can not send him a command. As a result, the serial number knows only the application that connected to the device for the first time. The serial number is stored on the server in the user's account (if he created it), so that the loss does not threaten him. But here is a new problem - the device can be managed by several people who have different accounts. So, we need a method for transferring rights to a device to other people:

In order not to complicate the logic of work, we abandoned the system of separation of rights, and give equal rights to everyone who has a UUID-D device in their account. This means that as soon as the first application transfers the rights to devices to another account, it gains full control over the device and can transfer the rights to other accounts in the same way. This eliminates the need to look for
someone who deprived of virginity a teapot “master” kettle, if you want to give someone rights, but if an employee leaves work and has an untied UUID-D in his account, he will be able to faithfully boil an office kettle at night. And nothing can be done with this, except to reset the device and configure it again - at the same time it will receive a new UUID-D, and records with the old one will be erased from the accounts and the database. Determining that you can erase old entries is simple - when initializing, the MAC address of the device is sent to the server, and if it already exists in the database, then the device is initialized again and we don’t need the old entries.
About unique rooms
By the way, UUID is also a very interesting decision, when I found out about it, I was happy for a long time. :)
For example, you have a server on which someone creates accounts. Or add files. Or write. Or something else does not matter. How will you number the entities on the server? The first answer is in order. A person uploads a photo - it is called 00001. It loads the next one - it will already be called 00002, the third one - 00003. And so on. Since the photos are numbered by the server, there are no problems - he looks at the previous loaded photo, adds one to its number, and writes it down. All perfectly.
But your service is developing, and you need another server. But here's the problem - you need synchronization between servers. And if the files can still be synchronized relatively slowly, or not to synchronize at all, then the information on the last file name should
always be up to date. Otherwise, if two users on different servers upload pictures with a small gap, the information may not yet be updated on the second server, and the files get the same numbers. And in the end, instead of the kitten who uploaded Petya to send to his girlfriend, a photo of Vasya’s girl will be found. And Petya will try very hard to prove to the girl who received the postcard that this is “just a mistake on the server, it happens.” And Vasya will be distressed by finding a kitten, and not his girlfriend.

In addition, you need to provide another blocking when uploading the next photo - no matter how quickly you do not update the information, the situation is not excluded when two users
actually upload a photo at the same time. In short, to be so, you can not name the files in ascending order.
For example, you can generate a random number, large enough so that it does not coincide in the foreseeable future. It is also good, for actively changing data to generate it depending on the current time - then for the likely coincidence of the two files, not only do two random numbers have to match, so they also have to match in the same second! But the probability of this combination is very small, maybe because the kittens do not turn into photos of other girls :(
In short, "everything is already standardized before us!". There is a ready-made standard in this case, described in RFC 4122 - Universally Unique Identifier, but simply
the UUID , it looks like this: 65C4B640-3452-11E3-AA6E-0800200C9A66, and all of them can be 340000000000000000000000000000000000000 pieces, or in a simple 3.4 dodetsilliona .
But something I was distracted by dodecillion
tits . Here’s how the first powering up looks for a kettle:

Compared to simple device-application authorization, a lot of new things have also been added here: the device is assigned a UUID, it tries to connect to the server, and sends the UUID and MAC address of the WiFi module there (I already told you why).
Security
We came to an interesting decision, thinking about the contradiction “the device should be as simple as possible - the device should be protected”. To be more precise, it is more convenient to implement the security system with the help of accounts, but I would be the first to spit in the face of someone who would say that in order to use the kettle, you need to create an account. As a result, the account is created, but the user does not participate in this - you could see it in the pictures above. During initialization, we create an account with a random name and password, and in the application we save it as a key for authorization. The user may not be aware of this, so the problem of creating an account has been resolved.
Yes, I already hear the objections from the audience - but what about those for whom the account is
convenient ? A person may have several devices in his account, several phones, or he often updates, after which the application must be reinstalled. There are de facto accounts, but it is difficult to use them - try to remember that you have login A811BF51-98B8-4604-9A8C-D72D8E40D846, and the password is 7960E625-912D-4625-BC9E-08E9B3047219 :)
Of course, we will not torture users so much, so we need to give them the opportunity to rename the account. Since the user does not know that his account has already been created, do not destroy his illusion of simplicity, and you can call the item “create an account”. But hiding under this will be exactly the renaming:

I have not yet decided whether to give the user the opportunity to rename the account again, or limit one renaming - from random to normal. I leave this question on your conscience - in the voting box you can select the item, or express your opinion in the comments.
Work with teams
And now we proceed to the most interesting - sending commands to the device. The application does it like this:

It should be noted that the application is sending commands now to the server, and not to the device directly. There is also a lock in the situation where several applications try to kill each other with different teams. For example, Peter is sitting at home and turned on the kettle to maintain the temperature. And Petya's girlfriend, still offended at him for a postcard with a strange girlfriend, does not want to call him and ask him to warm up the teapot, but tries to do this from his phone. Unfortunately, this gesture of insult will not be perceived as she expected - the application on her phone will report an error, because on the teapot another team is already running. But at the same time, with such a logic, for any cancellation of the command, you must first send a command to clear the queue, and only then a new command. It will not be very convenient for Petit, who was mistaken with a button, and pressed the button for heating to the temperature of infant formula (36 degrees), and not the button for heating to 90, for tea. He understands that he was mistaken, presses another button - and the application reports an error. Well, all right - the team is already running. I had to make an additional handler, which cancels the command without confirmation, if it has already run another command in the same program.
As a result, we have come to the logic of the work that suits us: from the phone from which the command was sent, it can be replaced with another one without asking any questions, but from other phones it is impossible. Because it is useless to interfere with another person to boil tea.
So, the application sends a command to the server, and the server ... This is what the server is:

It checks the rights (whether Petya can turn on this particular teapot), assigns the serial number to the team, saves it to the database, and tries to send it via an open connection to the device. If there is no connection, he will wait until it appears. After sending, the server receives a message about the successful delivery of the command, and forwards it to the application. And after the command is completed, it writes itself to the log, deletes the command from the database, and sends a notification about the execution of the command on the teapot with the UUID-D to everyone who has this UUID-D recorded in the account.
So the girl Petya, coming up to the house, will still receive a notice that the teapot has boiled up, realizes that he was warming the teapot before her arrival, and finally forgive Petya for this freaking postcard.
And a teapot, an eternal worker, receiving a command from the server, has no choice but to execute it:

Of course, under the small square “Execution of the team” there is a block diagram no less (or even more extensive than this), but this is a completely different story ...
As usual:
1) Report grammatical and punctuation errors in private
2) About errors in logic, sentences, thoughts - in the comments.
3) Arrange srachi - allowed.
4) Subscribe to those dudes who make the kettle in
on the company page (button "subscribe")
5) You can view the picture in fullsize
here .
6) And you can pick up its source in the format of the OmniGraffle program for Mac
here . I do not know why, but suddenly someone takes it as a basis, I will be pleased.