41
loading...
This website collects cookies to deliver better user experience
python manage.py startapp devices
ACCESS_ID = "<Insert your Tuya Cloud ACCESS_ID here>"
ACCESS_KEY = "<Insert your Tuya Cloud ACCESS_KEY here>"
API_ENDPOINT = "https://openapi.tuyaeu.com" # note EU after tuya
MQ_ENDPOINT = "wss://mqe.tuyaeu.com:8285/" # note EU after tuya
from django.urls import path
from . import views
urlpatterns = [
path('devices/', views.devices, name="devices"),
path('power/<device_id>', views.power_device, name="power_device"),
path('monitor/<device_id>', views.monitor_device, name="monitor_device"),
]
from django.conf import settings
from django.db import models
from datetime import datetime
from django.conf.urls.static import static
from django.urls import reverse
class Device(models.Model):
name = models.CharField(max_length=150)
device_id = models.CharField(max_length=150)
status = models.BooleanField(default=False)
watts = models.IntegerField(null=True)
monitoring = models.BooleanField(default=False)
powered_on = models.DateTimeField(blank=True, null=True)
powered_off = models.DateTimeField(blank=True, null=True)
created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
def __str__(self):
return self.name
class DeviceLog(models.Model):
device = models.ForeignKey(Device, on_delete=models.CASCADE, related_name="device")
powered_on = models.DateTimeField(blank=True, null=True)
powered_off = models.DateTimeField(blank=True, null=True)
consumption = models.FloatField(blank=True, null=True)
cost = models.FloatField(blank=True, null=True)
from django.db import models
from .models import *
from django import forms
class setWattsForm(forms.Form):
watts = forms.IntegerField(widget=forms.NumberInput(attrs={'placeholder': 'Insert device Watts'}))
from django.shortcuts import render, get_object_or_404, redirect
from datetime import datetime, date
from .models import *
from settings.models import *
pip install tuya-connector-python
import logging
from .env import ACCESS_ID, ACCESS_KEY, API_ENDPOINT
from tuya_connector import TuyaOpenAPI, TUYA_LOGGER
TUYA_LOGGER.setLevel(logging.DEBUG)
openapi = TuyaOpenAPI(API_ENDPOINT, ACCESS_ID, ACCESS_KEY)
openapi.connect()
from django.shortcuts import render, get_object_or_404, redirect
from datetime import datetime, date
from .models import *
from settings.models import *
from .forms import *
# Import Logging
import logging
# Import connection configuration (.env file) & import TuyaOpenAPI and Logger
from .env import ACCESS_ID, ACCESS_KEY, API_ENDPOINT
from tuya_connector import TuyaOpenAPI, TUYA_LOGGER
# Uncomment this if you want to Debug Tuya Cloud Functions
#TUYA_LOGGER.setLevel(logging.DEBUG)
# Connect to TuyaOpenAPI
openapi = TuyaOpenAPI(API_ENDPOINT, ACCESS_ID, ACCESS_KEY)
openapi.connect()
# Refresh Devices
def refresh_devices(request):
# Fetch all available Devices
all_devices = openapi.get("/v1.2/iot-03/devices")
all_devices = all_devices['result']['list']
# Loop through all fetched devices and save/update them in the database
for device in all_devices:
device_id = device['id']
name = device['name']
# Check the Cloud state of the device
dev = openapi.get('/v1.0/iot-03/devices/{}/status'.format(device_id))
state = dev['result'][0]['value']
obj, created = Device.objects.update_or_create(
device_id=device_id, defaults={'name': name, 'status':state}
all_devices = openapi.get(“/v1.2/iot-03/devices”)
def power_device(request, device_id):
today = datetime.now()
# Get a device
device = get_object_or_404(Device, device_id=device_id)
# Check if device is powered on/off
if device.status:
commands = {'commands': [{'code': 'switch_1', 'value': False}]}
device.status = False
device.save()
# Update Powered Off time in Device model
obj, created = Device.objects.update_or_create(
device_id=device_id, defaults={'powered_off': today}
)
# Calculate consumption
started = device.powered_on
ended = today
# difference between the start and the end of an activity in seconds
dur = ended - started
duration = dur.total_seconds()
# convert duration to hours
hours = duration / 3600
# calculate device kilowatts
kilowatts = device.watts / 1000
# calculate kilowatt-hours
kwh = hours * kilowatts
# calculate the activity session cost
price = Price.objects.last()
kwh_price = price.kwh_price
cost = kwh * kwh_price
# Create DeviceLog entry with each active session of a device
DeviceLog.objects.create(device_id=device.id, powered_on=device.powered_on, powered_off=today, consumption=kwh, cost=cost)
else:
commands = {'commands': [{'code': 'switch_1', 'value': True}]}
device.status = True
device.save()
# Update Powered On time in Device model
obj, created = Device.objects.update_or_create(
device_id=device_id, defaults={'powered_on': today}
)
# Send the commands for powering on/off
openapi.post('/v1.0/iot-03/devices/{}/commands'.format(device_id), commands)
return redirect(request.META['HTTP_REFERER'])
def devices(request):
refresh_devices(request)
devices = Device.objects.all()
form = setWattsForm()
if request.method == 'POST':
form = setWattsForm(request.POST)
if form.is_valid():
device_id = request.POST.get('device_id')
watts = form.cleaned_data['watts']
monitoring = True
Device.objects.filter(device_id=device_id).update_or_create(device_id=device_id, defaults={'watts': watts, 'monitoring': monitoring})
return redirect('devices')
else:
print('Not valid')
context = {
'devices': devices,
'form': form
}
return render(request, 'devices.html', context)
def monitor_device(request, device_id):
# Get a device
device = get_object_or_404(Device, device_id=device_id)
# Remove device from monitoring state
if device.monitoring:
device.monitoring = False
device.save()
# Add device for monitoring
else:
device.monitoring = True
device.save()
return redirect(request.META['HTTP_REFERER'])
python manage.py startapp settings
from django.urls import path
from . import views
urlpatterns = [
path('settings/', views.settings, name="settings"),
]
from django.conf import settings
from django.db import models
from datetime import datetime
from django.urls import reverse
class Price(models.Model):
kwh_price = models.FloatField()
currency_name = models.CharField(max_length=150)
currency_abbr = models.CharField(max_length=150)
updated = models.DateTimeField(auto_now_add=True, blank=True, null=True)
def __str__(self):
return self.currency_name
from django.db import models
from .models import *
from django import forms
class setPriceCurrencyForm(forms.ModelForm):
kwh_price = forms.FloatField(widget=forms.NumberInput(attrs={'placeholder': 'Insert price'}))
currency_name = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Insert currency name'}))
currency_abbr = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Insert abbreviation or symbol'}))
class Meta:
model = Price
fields = ("kwh_price", "currency_name", "currency_abbr" )
def __init__(self, *args, **kwargs):
super(setPriceCurrencyForm, self).__init__(*args, **kwargs)
from django.shortcuts import render, get_object_or_404, redirect
from datetime import datetime, date
from devices.models import *
from .models import *
from .forms import *
def settings(request):
price = Price.objects.last()
form = setPriceCurrencyForm(instance=price)
if request.method == 'POST':
form = setPriceCurrencyForm(request.POST, instance=price)
if form.is_valid():
form.save()
return redirect('settings')
context = {
'form': form,
}
return render(request, 'settings.html', context)
python manage.py startapp dashboard
from django.urls import path
from . import views
urlpatterns = [
path('', views.dashboard, name="dashboard"),
]
from django.shortcuts import render
from datetime import datetime, date
from devices.models import *
from settings.models import *
from django.db.models import Sum
from devices.views import refresh_devices
def dashboard(request):
# Check the Cloud state of the devices
refresh_devices(request)
# Get all devices
devices = Device.objects.filter(monitoring=True)
# Devices count
devices_count = devices.count()
# Price per kWh
price = Price.objects.last()
# Get the Device Log
device_log = DeviceLog.objects.all().order_by('-powered_off')
# Sum total consumption in kWh
total_kwh = DeviceLog.objects.aggregate(Sum('consumption'))['consumption__sum']
# Sum total cost
total_cost = DeviceLog.objects.aggregate(Sum('cost'))['cost__sum']
context = {
'devices': devices,
'device_log': device_log,
'devices_count': devices_count,
'price': price,
'total_kwh': total_kwh,
'total_cost': total_cost
}
return render(request, 'dashboard.html', context)