Compare commits

...

2 Commits

  1. 4
      apiserver/apiserver/api/apps.py
  2. 40
      apiserver/apiserver/api/migrations/0001_initial.py
  3. 43
      apiserver/apiserver/api/migrations/0002_coolerdata_fan_coolerdata_max_temp_coolerdata_pump_and_more.py
  4. 19
      apiserver/apiserver/api/migrations/0003_minerdata_json_version.py
  5. 27
      apiserver/apiserver/api/models.py
  6. 67
      apiserver/apiserver/api/views.py
  7. 50
      apiserver/apiserver/settings.py
  8. 1
      apiserver/apiserver/urls.py

@ -1,6 +1,4 @@
from django.apps import AppConfig
class ApiConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'api'
name = 'apiserver.api'

@ -0,0 +1,40 @@
# Generated by Django 4.0.4 on 2022-04-27 23:47
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='CoolerData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('time', models.DateTimeField()),
('cooler_id', models.CharField(blank=True, max_length=36)),
],
),
migrations.CreateModel(
name='MinerData',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('time', models.DateTimeField()),
('miner_id', models.CharField(blank=True, max_length=36)),
('summary', models.JSONField()),
('fans', models.JSONField()),
('devdetails', models.JSONField()),
('version', models.JSONField()),
('devs', models.JSONField()),
('config', models.JSONField()),
('coin', models.JSONField()),
('pools', models.JSONField()),
('tunerstatus', models.JSONField()),
('temps', models.JSONField()),
],
),
]

@ -0,0 +1,43 @@
# Generated by Django 4.0.4 on 2022-06-23 21:30
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='coolerdata',
name='fan',
field=models.IntegerField(default=0),
preserve_default=False,
),
migrations.AddField(
model_name='coolerdata',
name='max_temp',
field=models.DecimalField(decimal_places=4, default=0, max_digits=7),
preserve_default=False,
),
migrations.AddField(
model_name='coolerdata',
name='pump',
field=models.IntegerField(default=0),
preserve_default=False,
),
migrations.AddField(
model_name='coolerdata',
name='rad_temp',
field=models.DecimalField(decimal_places=4, default=0, max_digits=7),
preserve_default=False,
),
migrations.AddField(
model_name='coolerdata',
name='tub_temp',
field=models.DecimalField(decimal_places=4, default=0, max_digits=7),
preserve_default=False,
),
]

@ -0,0 +1,19 @@
# Generated by Django 4.0.4 on 2022-06-24 00:01
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('api', '0002_coolerdata_fan_coolerdata_max_temp_coolerdata_pump_and_more'),
]
operations = [
migrations.AddField(
model_name='minerdata',
name='json_version',
field=models.IntegerField(default=1),
preserve_default=False,
),
]

@ -1,3 +1,28 @@
from django.db import models
# Create your models here.
class MinerData(models.Model):
time = models.DateTimeField()
miner_id = models.CharField(max_length=36, blank=True)
json_version = models.IntegerField()
summary = models.JSONField()
fans = models.JSONField()
devdetails = models.JSONField()
version = models.JSONField()
devs = models.JSONField()
config = models.JSONField()
coin = models.JSONField()
pools = models.JSONField()
tunerstatus = models.JSONField()
temps = models.JSONField()
class CoolerData(models.Model):
time = models.DateTimeField()
cooler_id = models.CharField(max_length=36, blank=True)
tub_temp = models.DecimalField(max_digits=7, decimal_places=4)
rad_temp = models.DecimalField(max_digits=7, decimal_places=4)
max_temp = models.DecimalField(max_digits=7, decimal_places=4)
fan = models.IntegerField()
pump = models.IntegerField()

@ -1,7 +1,21 @@
import logging
logger = logging.getLogger(__name__)
from django.contrib.auth.models import User
from rest_framework import viewsets
from rest_framework import viewsets, views, mixins
from rest_framework import permissions
from apiserver.api import serializers
from rest_framework.decorators import action
from rest_framework.response import Response
from apiserver.api import serializers, models
from datetime import datetime, timezone
Base = viewsets.GenericViewSet
List = mixins.ListModelMixin
Retrieve = mixins.RetrieveModelMixin
Create = mixins.CreateModelMixin
Update = mixins.UpdateModelMixin
Destroy = mixins.DestroyModelMixin
class UserViewSet(viewsets.ModelViewSet):
@ -9,3 +23,52 @@ class UserViewSet(viewsets.ModelViewSet):
serializer_class = serializers.UserSerializer
permission_classes = [permissions.IsAuthenticated]
class DataViewSet(Base, List, Retrieve):
@action(detail=False, methods=['post'])
def push(self, request):
miner_data = request.data['miner_data']
cooler_data = request.data['cooler_data']
for miner_id, miner in miner_data.items():
time = miner['summary'][0]['STATUS'][0]['When']
models.MinerData.objects.update_or_create(
time=datetime.fromtimestamp(time, tz=timezone.utc),
miner_id=miner_id,
defaults=dict(
json_version=2,
summary=miner['summary'][0]['SUMMARY'][0],
fans=miner['fans'][0]['FANS'],
devdetails=miner['devdetails'][0]['DEVDETAILS'],
version=miner['version'][0]['VERSION'][0],
devs=miner['devs'][0]['DEVS'],
config=miner['config'][0]['CONFIG'][0],
coin=miner['coin'][0]['COIN'][0],
pools=miner['pools'][0]['POOLS'],
tunerstatus=miner['tunerstatus'][0]['TUNERSTATUS'][0],
temps=miner['temps'][0]['TEMPS'],
),
)
time = cooler_data['time']
cooler_id = cooler_data['cooler_id']
models.CoolerData.objects.update_or_create(
time=datetime.fromtimestamp(time, tz=timezone.utc),
cooler_id=cooler_id,
defaults=dict(
tub_temp=cooler_data['tub_temp'],
rad_temp=cooler_data['rad_temp'],
max_temp=cooler_data['max_temp'],
fan=cooler_data['fan'],
pump=cooler_data['pump'],
),
)
logging.info('Added {} miner data points from cooler {}.'.format(
len(miner_data),
cooler_id,
))
return Response(200)

@ -10,6 +10,10 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""
import os
import logging.config
logger = logging.getLogger(__name__)
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
@ -22,8 +26,8 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-au(y+z)$-iy#(obif&ilg*_pn0j_+0u=q*p7h(3c-ii-euncwx'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
DEBUG_ENV = os.environ.get('DEBUG', False)
DEBUG = DEBUG_ENV or False
ALLOWED_HOSTS = [
'api.soak.stctech.ca',
@ -40,6 +44,8 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
#'rest_framework.authtoken',
'apiserver.api',
]
MIDDLEWARE = [
@ -127,3 +133,43 @@ STATIC_URL = 'static/'
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'medium': {
'format': '[%(asctime)s] [%(process)d] [%(levelname)7s] %(message)s'
},
},
'filters': {
},
'handlers': {
'console': {
'level': 'DEBUG',
'filters': [],
'class': 'logging.StreamHandler',
'formatter': 'medium'
},
},
'loggers': {
'gunicorn': {
'handlers': ['console'],
'level': 'DEBUG' if DEBUG else 'INFO',
'propagate': False,
},
'': {
'handlers': ['console'],
'level': 'DEBUG',
'propagate': True,
},
},
'root': {
'level': 'DEBUG' if DEBUG else 'INFO',
'handlers': ['console'],
},
}
logging.config.dictConfig(LOGGING)
if DEBUG: logger.info('Debug mode ON')
logger.info('Test logging for each thread')

@ -4,6 +4,7 @@ from apiserver.api import views
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'data', views.DataViewSet, basename='data')
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.

Loading…
Cancel
Save