Build a current meter and log the data for future analysis and suggestion using Microsoft Azure cloud for secure and robust communication.
What is it?A current meter for household measures the current being used in the household at any point of time or at regular interval. A current meter is useful to keep track of how much electricity is being used and helps in deciding how and where it can be reduced. This serves two purposes:
1. It allows the homeowner to be more economical in terms of electrical cost .
2. It allows each homeowner to contribute their two cents in preserving the environment.
BackgroundThe benefits of a detailed reading of electricity usage are many. Even though any smart meter available now-a-days on the market could be an option, I found the following negative points in using a smart meter for my use.
1. First and foremost, is to deal with data privacy. Smart meters are generally provided by the energy company and communicates directly with energy company. While it gives the client access to more detailed information and billing, it also provides the data to the energy company which has a lot of potential for misuse. The electricity consumption by a household at any point of time contains many vital information about the household (e.g. at which time intervals the house is relatively empty, When/which electrical appliances are being used, etc.).
2. Due to lack of regulations regarding storage and privacy of data from smart meters (e.g. in India), I do not want a smart meter from the energy company (at least for now).
3. Purchasing and installing a market available smart meter is costly as well as risky.
For these reasons, I prefer to build my own meter and keep my data to myself.
Why AvnetMT3620?I have been considering building a current meter for long time. Even though it was possible to build such a meter using my other devices like, Raspberry pi, NodeMCU, Arduino, but in all cases I was worried about security.
· While I can provide secure wireless network and secure cloud access, my device would be sitting at a not-so-secure location and physical security to the device is not possible.
· Without physical security, I was in risk of divulging my wireless network’s psk, secret key for cloud access etc. along with the data gathered by the device.
When I learned about Avnet MT3620 with Microsoft AzureSphere was giving the all-around security I knew that this is the platform that was required for this project.
ProcedureAlready thanks to the wonderful community, there is quite a large number of resources available for the Avnet MT3620 Starter Kit. To prepare the kit for usage follow the step-by-step guide from element14 (https://www.element14.com/community/groups/azuresphere/blog/2019/04/24/avnets-azure-sphere-starter-kit-out-of-box-demo-part-1-of-3)
Hardware SetupIt is very easy to setup the rest of the hardware in this project. The AC-current click fits on the MikroBus 1 of the starter kit. The (non-invasive) current sensor is put around a live wire. Make sure that the sensor is latched around on the insulator covered portions of only one of the wires and not more. Also, make sure that at no point of time the current passing through the wire is more than 30 Amperes. (Warning: As you work with live wires, be careful that the portions of the wire you are touching and putting the sensor is covered well with insulator.) This is how my setup looks once deployed (building an enclosure for the device and wires would be the next step).
I have repurposed one of the reference codes from Avnet (AvnetAzureSphereStarterKitReferenceDesign) for the purpose of building and logging data from the device to cloud. Instead of providing the existing code again, the diff with the original code is available here. To get the actual project perform the following operations:
1. Clone the repository from https://github.com/Avnet/AvnetAzureSphereStarterKitReferenceDesign.
2. Download the git diff from here.
3. Apply the diff using the command in the cloned directory:
git apply path_to_patch/currentMeter.patch
Short Description: The main code is situated in the file “i2c.c”. The function “AccelTimerEventHandler” contains the code to get the values from the sensor and send it to cloud (or show on debug terminal). In the file “build_options.h”, based on your preference you can comment/uncomment the following lines to communicate with IOT hub.
#define IOT_CENTRAL_APPLICATION
#define IOT_HUB_APPLICATION
In this case, I have only sent temperature, pressure and current reading to the cloud as these are the parameters that will be required later.
On the cloud side, follow the steps from the wonderful step-by-step tutorial from element14 (https://www.element14.com/community/groups/azuresphere/blog/2019/05/01/azure-sphere-starter-kit-out-of-box-demo-blog-post-2). This sets up a IoT hub on the Microsoft Azure portal and modifies the code that lets you send data from device and access the raw data as well.
After all these setup, I have my data online which can be visualised by a time-series insight application.
It is possible to change the frequency of the data read and sent (15 second) by modifying the code
#define ACCEL_READ_PERIOD_SECONDS 15
in “build_options.h” (the free tier of IoT hub lets you send 8000 messages per day).
Once you are satisfied with the changes, you can put the device in OTA enabled mode using the following command in the azureSphere Developer Command Prompt
azsphere device enable-cloud-test --productname "MyProduct"
Getting the Data from IOT hub (in Python)The “IOT hub” on Microsoft Azure has a free tier allowing your device to send upto 8000 messages per day. While IOT hub simplifies and makes the communication between device and cloud very seamless, it is not a storage service and hence only guarantees to store messages only for a day. You can register for storage services from Azure separately and store the data from the device there.
Since I already have enough storage available at home, I chose to collect the data from the device in my storage by periodically downloading all the data from IOT hub. The following steps are required to setup a backend program in python to download all the data from IOT hub at least once a day.
1. Install Azure SDK for python (with preview): The Azure SDK for python (with preview) can be installed using pip by using the command
pip install –pre azure-eventhub
(The information given by the present version of Azure portal is compatible with the preview version of the SDK.)
2. Get Information from IOT hub: The main information required to pull data from IOT hub is the hub name and the connection string for the built-in Endpoint. These two details can be extracted from Azure portal as show in the figure.
3. Pull Data: The script below pulls data from IOT hub and stores in a MongoDB database. (track_last_enqueued_event_properties=True, tracks the position upto which data has been extracted from the hub.)
#!/usr/bin/env python
#--------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
#-------------------------------------------------------------------------------------
"""
An example to show receiving events from an Event Hub partition.
"""
import os
from azure.eventhub import EventPosition,EventHubConsumerClient
import pymongo
CONNECTION_STR = "eventhub-compatible_endpoint_from_azure_iothub"
EVENT_HUB = "eventhub_compatible_name_from_azure_iothub"
EVENT_POSITION = EventPosition("-1")
PARTITION = "0"
total = 0
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["currentMeter"]
mycol = mydb["readings"]
def do_operation(event):
# do some operations on the event, avoid time-consuming ops
mydict = json.loads(event['body'])
mydict['timestamp']=event['enqueued_time']
x = mycol.insert_one(mydict)
print(event)
def on_partition_initialize(partition_context):
# put your code here
print("Partition: {} has been intialized".format(partition_context.partition_id))
def on_partition_close(partition_context, reason):
# put your code here
print("Partition: {} has been closed, reason for closing: {}".format(partition_context.partition_id,reason))
def on_error(partition_context, error):
# put your code here
print("Partition: {} met an exception during receiving: {}".format(partition_context.partition_id,error))
def on_events(partition_context, events):
# put your code here
global total
print("received events: {} from partition: {}".format(len(events), partition_context.partition_id))
total += len(events)
for event in events:
do_operation(event)
if __name__ == '__main__':
consumer_client = EventHubConsumerClient.from_connection_string(
conn_str=CONNECTION_STR,
event_hub_path=EVENT_HUB
)
try:
with consumer_client:
consumer_client.receive(on_events=on_events, consumer_group='$Default',
on_partition_initialize=on_partition_initialize,
on_partition_close=on_partition_close,
on_error=on_error,track_last_enqueued_event_properties=True)
except KeyboardInterrupt:
print('Stop receiving.')
On running the script it shows the data pulled from the IOT hub as well as puts it in the database. Following is the output in this case.
Once all data has been extracted and the output of the script stalls, waiting for more data, you can exit the script using ctrl+c.
Future ScopeThe data logged from the project can be used to predict and suggest different measures based on consumption. The following analysis and prediction can be done.
1. Use the data collected over a period of time to develop a consumption profile (using Machine Learning Studio on Microsoft Azure) with respect to outside temperature and pressure for my household and detect/warn in future if the consumption is not following the profile.
2. In future, based on outside temperature and pressure compute a probable electricity consumption rate and notify in case the consumption is too high.
3. Build a mobile application to show (is a user-friendly manner) past and present consumption and all notifications.
Comments