#Repost – Alibaba Function compute vs @Azure function via @mteheran. Details on 💲⌛and more…

Buy Me A Coffee

Hi !

My friend Miguel shared a very interesting comparative between Alibaba Function Compute and Azure Functions. You can read his original post in Spanish here.

To be, this table is amazing:

FeatureALIBABA FUNCTION COMPUTEAZURE FUNCTION
Programming LanguagesNode.js (JS), Python, Java, PHP, dotnet (C#), customNode.js (JS), Python, Java, dotnet (C#), PowerShell, custom
Operating SystemsLinuxLinux / Windows
Supported HTTPGET, POST, PUT, PATCH, DELETE, HEADGET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, TRACE
CustomizationMemoryAzure compute unit (ACU), Memory
Free Request1 Million
400,000gb seconds
1 Million
400,000gb seconds
Cost$0.2 x 1 Million requests$0.2 x 1 Million requests
RegionsChina, USA, Germany, India, Japan, Australia, IndonesiaCanada, USA, Germany, India, Japan, Australia, Brazil, Korea, France
Functions typesHttp Function, Event FunctionHttp Trigger, Timer Trigger, Azure Queue Storage trigger, Azure Service Bus Queue trigger, Azure Service Bus Topic trigger, Azure Event Grid trigger, Durable Functions HTTP starter, more …

Happy coding!

Greetings

El Bruno

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

#Coding4Fun – How to control your #drone ✈ with 20 lines of code! (24/N) #AzureIoT

Buy Me A Coffee

Hi !

Final post, so let’s recap

We have a device template representing a drone, tracking accelerometer, battery and temperature values.

We have created a new device to twin our drone in Azure IoT Central. And, copy the connect information: ScopeId, DeviceId and Key.

Let’s use a “get data from drone demo” and publish this information to Azure IoT Central.

I’ll share the complete file below, however let’s take a look at the main app code.

  • The following code block iterates 300 times while is reading drone information.
  • In each iteration, it send to the drone devices the accelerometer values. These are drone telemetry capabilities.
  • Every 10 iterations, it also update other drone capabilities: battery and temperature. These are drone properties.
# MAIN APP
battery = 0
agx     = 0
agy     = 0
agz     = 0
temph   = 0
templ   = 0

i = 0
while i < 300:
    i = i + 1
    sendReadCommand('battery?')
    await drone.send_telemetry(agx, agy, agz)
    if (i % 10) == 0:
        await drone.send_properties(temph, templ, battery)
    time.sleep(1)

Once we run the app, Azure IoT Central dashboard will show the real-time information from the drone. If the drone is flying and reporting accelerometer values, the agx, agy, agz chart will display the values related to axis x, y and z.

drone azure iot central out of battery

Disclaimer: I declared the temperature unit as Celsius. You can quickly realize that the values are in Farenheight.

And as promised here is the full code for this demo.

# Copyright (c) 2020
# Author: Bruno Capuano
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ———————————————–
# 70 AZURE IOT HUB Sample
# ———————————————–
import socket
import time
import threading
import iotc
import provision_service
import asyncio
import json
import datetime
from drone_device import Drone_Device
# ———————————————–
# RECEIVE DATA FUNCTIONS
# ———————————————–
def receiveData():
global response, clientSocket
while True:
try:
response, _ = clientSocket.recvfrom(1024)
except:
break
def readStates():
global battery, agx, agy, agz, temph, templ
global response, response_state, clientSocket, stateSocket, address
while True:
try:
response_state, _ = stateSocket.recvfrom(256)
if response_state != 'ok':
response_state = response_state.decode('ASCII')
list = response_state.replace(';', ':').split(':')
battery = int(list[21])
agx = float(list[27])
agy = float(list[29])
agz = float(list[31])
temph = int(list[15])
templ = int(list[13])
# except:
# break
except Exception as e:
print(f'exc: {e}')
pass
# ———————————————–
# SEND COMMAND FUNCTIONS
# ———————————————–
def sendCommand(command):
global response, clientSocket, address
timestamp = int(time.time() * 1000)
clientSocket.sendto(command.encode('utf-8'), address)
while response is None:
if (time.time() * 1000) timestamp > 5 * 1000:
return False
return response
def sendReadCommand(command):
global response
response = sendCommand(command)
try:
response = str(response)
except:
pass
return response
def sendControlCommand(command):
global response, response_state, clientSocket, stateSocket, address
response = None
for i in range(0, 5):
response = sendCommand(command)
if response == 'OK' or response == 'ok':
return True
return False
# ———————————————–
# AZURE IOT CENTRAL
# ———————————————–
async def init_drone_AzureIoT():
global drone
iothub = ""
scope = "Azure IoT Central Device Connect Scope ID goes here"
device_id = "Azure IoT Central Device Connect Device ID goes here"
key = "Azure IoT Central Device Connect KEY goes here"
drone = Drone_Device(scope, device_id, key)
await drone.init_azureIoT()
# ———————————————–
# 35 CAMERA
# APP DISPLAY CAMERA WITH OPENCV and FPS
# ———————————————–
async def main():
global battery, agx, agy, agz, temph, templ
global response, response_state, clientSocket, stateSocket, address
global drone
await init_drone_AzureIoT()
# CONNECTION TO THE DRONE
# connection info
UDP_IP = '192.168.10.1'
UDP_PORT = 8889
last_received_command = time.time()
STATE_UDP_PORT = 8890
address = (UDP_IP, UDP_PORT)
response = None
response_state = None
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
clientSocket.bind(('', UDP_PORT))
stateSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
stateSocket.bind(('', STATE_UDP_PORT))
# LISTENER THREADS
# start threads
recThread = threading.Thread(target=receiveData)
recThread.daemon = True
recThread.start()
stateThread = threading.Thread(target=readStates)
stateThread.daemon = True
stateThread.start()
# START DRONE CONNECTION
# connect to drone
response = sendControlCommand("command")
print(f'command response: {response}')
response = sendControlCommand("streamon")
print(f'streamon response: {response}')
# MAIN APP
# drone information
battery = 0
agx = 0
agy = 0
agz = 0
temph = 0
templ = 0
i = 0
while i < 300:
i = i + 1
sendReadCommand('battery?')
await drone.send_telemetry(agx, agy, agz)
if (i % 10) == 0:
await drone.send_properties(temph, templ, battery)
time.sleep(1)
if __name__ == "__main__":
asyncio.run(main())

In the next post we will connect everything together !

Happy coding!

Greetings

El Bruno

References

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

#Coding4Fun – How to control your #drone ✈ with 20 lines of code! (23/N) #AzureIoT

Buy Me A Coffee

Hi !

Now that we have a device template created, we can create a new device in our Azure IoT Central portal and start to send information to Azure IoT.

We start by creating a new device based on the previous template and it’s time to copy and paste the connection information for this device:

  • ID scope
  • Device ID
  • Primary Key
drone connect information

And, based on the official Python SDK documentation, I created this full class to send information to Azure IoT Central. A couple of notes

  • The class needs scopeID, deviceID and key in the constructor to create the device connection string
  • There are 2 main functions to showcase how to send telemetry and update properties
  • Telemetry (send_telemetry) uses the predefined device capabilities: agx, agy and agz
  • Properties (send_properties) uses the predefined device capabilities: battery, templ and temph
# Copyright (c) 2020
# Author: Bruno Capuano
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
import os
import datetime
import asyncio
import json
from azure.iot.device.aio import IoTHubDeviceClient
from azure.iot.device import MethodResponse
from azure.iot.device.aio import ProvisioningDeviceClient
class Drone_Device():
def __init__(self, scope, device_id, key, iothub : str = ""):
self.scope = scope
self.device_id = device_id
self.key = key
self.iothub = iothub
async def init_azureIoT(self):
cnn_str = await self.get_connection_string()
self.device_client = IoTHubDeviceClient.create_from_connection_string(cnn_str)
await self.device_client.connect()
async def __register_device(self):
provisioning_device_client = ProvisioningDeviceClient.create_from_symmetric_key(
provisioning_host='global.azure-devices-provisioning.net',
registration_id=self.device_id,
id_scope=self.scope,
symmetric_key=self.key,
)
return await provisioning_device_client.register()
async def get_connection_string(self):
if(self.iothub == None or self.iothub == ""):
print(f'{datetime.datetime.now()}: No IOTHUB specified. Attempting to resolve via global.azure-devices-provisioning.net')
results = await asyncio.gather(self.__register_device())
print(results)
registration_result = results[0]
cnn_str = 'HostName=' + registration_result.registration_state.assigned_hub + \
';DeviceId=' + self.device_id + \
';SharedAccessKey=' + self.key
else:
cnn_str = 'HostName=' + self.iothub + \
';DeviceId=' + self.device_id + \
';SharedAccessKey=' + self.key
print(f'{datetime.datetime.now()}: Connection String = {cnn_str}')
return cnn_str
async def send_telemetry(self, agx, agy, agz):
try:
payload:str = ""
data = {
"agx": agx,
"agy": agy,
"agz": agz
}
payload = json.dumps(data)
print(f"{datetime.datetime.now()}: telemetry: {payload}")
await self.device_client.send_message(payload)
except Exception as e:
print(f"{datetime.datetime.now()}: Exception during sending metrics: {e}")
async def send_properties(self, bat, temph, templ):
try:
data = {
'bat': bat,
'templ': templ,
'temph': temph
}
propertiesToUpdate = data
print(f"{datetime.datetime.now()}: properties: {propertiesToUpdate}")
await self.device_client.patch_twin_reported_properties(propertiesToUpdate)
except Exception as e:
print(f"{datetime.datetime.now()}: Exception during sending metrics: {e}")

In the next post we will connect everything together !

Happy coding!

Greetings

El Bruno

References

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

#Coding4Fun – How to control your #drone ✈ with 20 lines of code! (22/N) #AzureIoT

Buy Me A Coffee

Hi !

In my the live events where I explain how to code to control the drone, I show a scenario where drone information is sent to Azure IoT Central. I just realized that I never wrote about it, so here is post 1 of N to describe this scenario.

Azure IoT Central

As usual let’s start with the official description for this Azure Service

IoT Central is an IoT application platform that reduces the burden and cost of developing, managing, and maintaining enterprise-grade IoT solutions. Choosing to build with IoT Central gives you the opportunity to focus time, money, and energy on transforming your business with IoT data, rather than just maintaining and updating a complex and continually evolving IoT infrastructure.

The web UI lets you monitor device conditions, create rules, and manage millions of devices and their data throughout their life cycle. Furthermore, it enables you to act on device insights by extending IoT intelligence into line-of-business applications.

What is Azure IoT Central ? see references

In the final output of this demo, we will have a device definition on Azure IoT central tracking

  • Realtime values for the drone accelerator (axis x, y, z)
  • Drone temperature (lowest and highest)
  • Battery charge, in %

Something similar to this 👇

drone azure iot central out of battery

Drone Template

My 1st step is to create a device template. I was testing different configurations, and at the end I finalize with the 4th iteration of my drone template: DroneTemplate v4

drone device template list

This template defines the following capabilities

  • Telemetry
    • agx
    • agy
    • agz
  • Properties
    • temph
    • templ
    • bat
drone template capabilities

Important: we can use custom data types, like Vector for accelerometer. However in this sample, all the properties and telemetry are defined as Integer values.

Now it’s time to create a view to display some of the device properties. In this scenario I added a chart with the telemetry agx, agy and agz. And 2 separate viewers for the battery and temperature.

In the temperature tile, I added a conditional formatting to display the battery value in different colors depending of the device battery charge.

And that’s it! With this simple device definition I can start to connect my test drone with the Azure IoT Central portal.

Happy coding!

Greetings

El Bruno

References

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

Digital transformation forecast in Mixed Reality and Augmented reality technologies via @ivanatilca

Buy Me A Coffee

The last few years turned out to be hard for many both online and offline stores. Technology is an instrument that can help retailers significantly improve their marketing strategies and ensure a higher revenue. A continuous stream of new, digitally-based technological innovations is every day, conquering the world. This phenomenon is part of the current mega-trend “digitalization”, which has already significantly impacted numerous industries. Concrete examples of two technologies, with are expected to drive major change – thereby offering significant revenue opportunities – in numerous industries in the next few years, are augmented reality (AR) and mixed reality (MR).

Fig. 1

Augmented Reality Market Size forecast

AR applications are increasingly accessible via everyday mobile devices and have the potential to make people’s lives easier. Over the last few years, augmented reality has become one of the most valuable marketing tools for numerous companies. This technology is gaining popularity across the globe. The following Statista report shows the global augmented reality (AR) and virtual reality (VR) market is forecast to reach 72.8 billion U.S. dollars in 2024.

image

Business owners and marketers are leveraging these trends to craft innovative strategies to achieve a competitive edge from enhancing marketing communications and taking customer experience to a new height to increase the efficiency of their business operations.

Read the complete article here.

Happy coding!

Greetings

El Bruno

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

#Python – Working with dates 📅, formats, and subtract for time difference. Timedelta type rocks!

Buy Me A Coffee

Hi !

I’m switching from C#9 to Python to write this down, so I avoid to search and write this from scratch again and again. My scenario includes very simple operations with dates,

  • Tag a start date time
  • Do some process, I’ll fake it with random sleep
  • Tag a end date time
  • Calculate the different between them
  • Process and show the difference with a specific format

For this I’ll use the datetime type, and a cool feature using datetime is that we can directly substract 2 dates. In example:

start = datetime.datetime.utcnow()
time.sleep(10)
end = datetime.datetime.utcnow()

delta = end - start

In this code 👆, the delta variable is a timedelta type. This is not a standard datetime, in C# we know this as TimeSpan. We can access the internal values, and get some details around hours, minutes, seconds and millisecons:

def get_timedelta_values(delta):
    # Get the hours, minutes, seconds and milliseconds
    millis           = round(delta.microseconds/1000, 0)
    minutes, seconds = divmod(delta.seconds, 60)
    hours, minutes   = divmod(minutes, 60)
    return hours, minutes, seconds, millis    

def get_timedelta_min_and_sec(delta):
    hours, minutes, seconds, millis = get_timedelta_values(delta)
    return str(f'{str(minutes).zfill(2)}:{str(seconds).zfill(2)}')

The 2nd function, get the delta values and creates a standard output with “mm:ss” format. So, not tricky and easy to move forward.

Another cool feature of the timedelta is that support adding. So as a final example, I’ll generate some random deltas in a loop, and add them in a totalTime var.

import time
import datetime
from random import randint

def get_timedelta_values(delta):
    # Get the hours, minutes, seconds and milliseconds
    millis           = round(delta.microseconds/1000, 0)
    minutes, seconds = divmod(delta.seconds, 60)
    hours, minutes   = divmod(minutes, 60)
    return hours, minutes, seconds, millis    

def get_timedelta_min_and_sec(delta):
    hours, minutes, seconds, millis = get_timedelta_values(delta)
    return str(f'{str(minutes).zfill(2)}:{str(seconds).zfill(2)}')

totalTime = None
i = 0
while i < 25:
    i = i + 1
    rndSleep = randint(1, 10)
    print(f'current iteration: {i} - rnd sleep: {rndSleep}')

    start = datetime.datetime.utcnow()
    time.sleep(rndSleep)
    end = datetime.datetime.utcnow()

    delta = end - start

    if (totalTime is None):
        totalTime = delta
    else:
        totalTime += delta

    print(f'  >> delta     : {get_timedelta_min_and_sec(delta)}')
    print(f'  >> total time: {get_timedelta_min_and_sec(totalTime)}')

The output as expected shows the delta with specific format in each iteration and also the accumulator for the total time

python adding time delta vars

So, here it is, a simple example that will save me some time in the future for sure !

Happy coding!

Greetings

El Bruno

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

References

#Net5 – C#9 “records” and “deconstruction” super cool feature 🆒🆒🆒

Buy Me A Coffee

Hi !

I’m still learning about C#9, and there is a lot to learn about records. And, between all this information, I Just learn a super cool feature related to records: deconstruction.

Let’s start with a simple record definition for a pet. This one includes pet’s name and pet’s age:

public record Pet
{
    public string Name { get; init; }
    public int Age { get; init; }
    public Pet(string name, int age)
        => (Name, Age) = (name, age);
}

This is fine, init only properties (cool feature!) and we can access the values as usual.

static void Main(string[] args)
{
    var pet = new Pet("Goku", 2);

    // get pet info, standard way
    var gokuName = pet.Name;
    var gokuAge = pet.Age;
}

So far, so good. However, if you like clean code, we can improve this a little using some new features in C#9. So, let’s start with much simpler record definition.

public record NewPet(string Name, int Age);

And we can access the pet properties using deconstruction (new term for me!)

// get pet info, C#9 deconstruction
var newPet = new NewPet("Goku", 2);
var (gokuName, gokuAge) = newPet;

I like this new one 👆 too ! I’ll always like features that improves readability and saves us a lot of extra code.

Happy coding!

Greetings

El Bruno

References

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

#Event – Let’s code a drone ✈ to follow faces 😀 with #AzureIoT (x2!) Supporting the #GlobalAI Bootcamp Singapore and Germany!

Buy Me A Coffee

Hi !

Let’s start the 2021 with some drones events supporting 2 Global AI Bootcamp events

Please each event location for specific details on time and streaming options.

Let’s code a drone to follow faces syncing everything with Azure IoT

You can control a drone using 20 lines of code. That’s the easy part. However, adding extra features like face or object detection and program the drone to follow and object or a face requires … another 20 lines of code! During this workshop we will review how to connect to a drone, how to send and receive commands from the drone, how to read the camera video feed and how to apply AI on top of the camera feed to recognize objects or faces. We will use a simple house drone ($100) and Python. And, when we review some enterprise scenarios, we will use Azure IoT to sync the drone information in IoT mode. Let’s build this!

For this session I’ll explain how to create a SDK from zero to control a DJI Tello drone, and the last past will include some examples on how to connect the drone reported information to Azure IoT.

And this is probably the last one my Microsoft MVP room-office (see below), there are some changes in the near future, so let’ rock these 2 sessions !

Happy coding!

Greetings

El Bruno

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

#Net5 – C#9 “Init-only properties” are super cool 🆒🆒🆒

Buy Me A Coffee

Hi !

So this one does not fit in the line “readability improvement”, however is a nice step in order to write cleaner code. Yes, I know that doesn’t make sense, let me try to explain.

Let’s start with a simple class with 2 properties. Interesting enough the property Age has a new accessor [init] to describe the property as a read-only property:

class Pet
{
  public string Name { get; set; }
  public int Age { get; init; }
}

When we create a new Pet object, we can set the initial value of Age on the construction of the object (object initialization), and that’s it. Otherwise we will get this amazing error.

Error CS8852 Init-only property or indexer 'Program.Pet.Age' can only be assigned in an object initializer, or on 'this' or 'base' in an instance constructor or an 'init' accessor. 
Csharp9 init only properties

Until C#9, the properties in a class need to be mutable in order to support Object Initialization. And that means some extra code in the property-set definition in order to support read-only properties. Now in C# 9, this is solved with the [init] accessor 😁😁😁

I like this new one 👆 ! Not a great readability improvement, but it saves us a lot of extra code.

Happy coding!

Greetings

El Bruno

References

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría:

#Net5 – C#9 logical operators “is” and “is not” are super cool 🆒🆒🆒

Buy Me A Coffee

Hi !

In the line of good features, that are also nice to read, the new use of is and is not is a huge improvement in readability.

As usual, old school validation for objects and types:

// old school
if(!(testObj is MyClass)) {...}

And now, we can type the validation with some style:

// C# 9 style
if(testObj is not MyClass) {...}

I like this new one 👆, now null / not null and other validations will be the same. With an improed readability !

Happy coding!

Greetings

El Bruno

References

¿Con ganas de ponerte al día?

En Lemoncode te ofrecemos formación online impartida por profesionales que se baten el cobre en consultoría: