yf_ymm 1 年間 前
コミット
d54381f1d4

+ 20 - 0
.vscode/launch.json

@@ -0,0 +1,20 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Python: Django",
+            "type": "python",
+            "request": "launch",
+            "program": "${workspaceFolder}\\manage.py",
+            "args": [
+                "runserver",
+                "0.0.0.0:10001"
+            ],
+            "django": true,
+            "justMyCode": true
+        }
+    ]
+}

+ 0 - 0
apps/DeviceCount/__init__.py


+ 3 - 0
apps/DeviceCount/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
apps/DeviceCount/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class DevicecountConfig(AppConfig):
+    name = 'DeviceCount'

+ 0 - 0
apps/DeviceCount/migrations/__init__.py


+ 19 - 0
apps/DeviceCount/models.py

@@ -0,0 +1,19 @@
+from django.db import models
+
+# Create your models here.
+
+
+# 统计测报灯设备每天源图片增长量,A识别图片量,B识别图片量,C识别图片量
+class CbdPhoto(models.Model):
+
+    id = models.AutoField("ID", primary_key=True)
+    day = models.CharField("年月日", max_length=11, blank=True, null=True)
+    device_id = models.CharField("设备ID", max_length=64, blank=True, null=True)
+    org_photo_ct = models.PositiveIntegerField("源图片数量", default=0)
+    discern_a_ct = models.PositiveIntegerField("A识别数量", default=0)
+    discern_b_ct = models.PositiveIntegerField("B识别数量", default=0)
+    discern_c_ct = models.PositiveIntegerField("C识别数量", default=0)
+
+    class Meta:
+        db_table = "ct_cbd_photo"
+    

+ 10 - 0
apps/DeviceCount/serializers.py

@@ -0,0 +1,10 @@
+# coding=utf-8
+from rest_framework import serializers
+from apps.DeviceCount.models import CbdPhoto
+
+
+class CbdPhotoSerializers(serializers.ModelSerializer):
+
+    class Meta:
+        model = CbdPhoto
+        fields = "__all__"

+ 3 - 0
apps/DeviceCount/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 13 - 0
apps/DeviceCount/views.py

@@ -0,0 +1,13 @@
+from django.shortcuts import render
+from rest_framework.views import APIView
+from rest_framework.views import Response
+from apps.DeviceCount.models import CbdPhoto
+from apps.DeviceCount.serializers import CbdPhotoSerializers
+
+
+class CbdPhotoCount(APIView):
+
+    def post(self, request):
+        query = CbdPhoto.objects.all().order_by("-id")
+        serializer = CbdPhotoSerializers(query, many=True)
+        return Response({"data": serializer.data}, status=200)

+ 161 - 0
apps/Equipment/men_tou_gou.py

@@ -0,0 +1,161 @@
+from rest_framework.views import APIView
+from rest_framework.response import Response
+
+import pymongo
+from urllib import parse
+import datetime
+import re
+import json
+
+
+def get_device(device_type=None):
+    device = {
+        "864865060482180": "5",
+        "860181067701570": "15",
+        "L31671797-1": "6",
+        "L42185263-1": "6"
+    }
+    if not device_type:
+        return device 
+    else:
+        new_device = {}
+        for k, v in device:
+            if v == device_type:
+                new_device[k] = v 
+        return new_device
+
+
+def get_table():
+    passwd = parse.quote_plus("yfkj@6020")
+    user = parse.quote_plus("root")
+    myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(user,passwd))
+    return myclient
+
+
+class CountDeviceStatus(APIView):
+    # 设备状态,在线与离线数量
+    def post(self, request):
+        devices = get_device()
+        device_ids = devices.keys()
+        # 获取设备的版本,经纬度
+        myclient = get_table()
+        db = myclient.smartfarming
+        sa_device = db.sa_device
+        query = {
+            'device_id': {
+                "$in": list(device_ids)
+            }
+        }
+        device = list(sa_device.find(query, {"device_id": 1,"lng":1, "lat": 1, "device_status": 1, "_id": 0, "uptime": 1, "province": 1, "city":1, "district": 1, "device_name": 1}))
+        offline = 0
+        online = 0
+        new = []
+        for k in device:
+            if k.get("device_status") == 1:
+                online += 1
+            else:
+                offline += 1
+            new.append(k)
+        myclient.close()
+        return Response({"count": offline + online, "online": online, "offline": offline, "device": new, "mtg_name": True})
+
+
+class QxData(APIView):
+    # 气象、墒情监测数据
+    def post(self, request):
+        result = {}
+        device_id = {
+            "气象站": "864865060482180", 
+            "墒情站": "860181067701570"
+        }
+        myclient = get_table()
+        db = myclient.smartfarming
+        qxz_conf = db.sa_qxz_conf
+        query = {'device_id': "864865060482180"}
+        conf = qxz_conf.find_one(query, {"_id": 0, "uptime": 0, "device_id": 0, "id": 0})
+        conf = {k: v for k, v in conf.items() if v is not None and v != ""}
+        qxz_data = db.sa_qxz_data
+        query = {'device_id': "864865060482180"}
+        field = conf.keys()
+        fields = {i: 1 for i in field}
+        fields.update({"_id": 0, "uptime": 1})
+        data = qxz_data.find(query, fields).sort("uptime", pymongo.DESCENDING).limit(1)
+        data = data[0]
+        tmp = {}
+        print(conf)
+        for k, v in data.items():
+            tp = conf.get(k)
+            if tp:
+                tp_m = tp.split("#")
+                tmp[k] = v.split("#")[0] + tp_m[-1]
+
+        sa_nd_qxz_status = db.sa_nd_qxz_status
+        qxz_obj = sa_nd_qxz_status.find({"device_id": "860181067701570"}, {"_id": 0}).sort("upl_time", pymongo.DESCENDING).limit(1)
+        qxz_obj = qxz_obj[0]
+        if qxz_obj.get("depth"):
+            depth = qxz_obj.get("depth")
+        else:
+            depth = ""
+            len_ = len((qxz_obj.get("temp")).split(","))
+            for i in range(len_):
+                if i != 0:
+                    depth += ","
+                depth += str((i+1)*10)
+        data = {"depth":depth,"csq":qxz_obj.get("csq"),"temp":qxz_obj.get("temp"),"swc":qxz_obj.get("swc"),"atm":qxz_obj.get("atm"),"at":qxz_obj.get("at"),"ats":qxz_obj.get("ats"),"uptime":qxz_obj.get("upl_time")}
+
+        myclient.close()
+        return Response({
+            "qxz":tmp,
+            "qxz_conf": conf,
+            "sqz": data,
+            "mtg_name": True
+        })
+
+
+class QxWarning(APIView):
+    # 气象预警数据
+    def post(self, request):
+        myclient = get_table()
+        db = myclient.smartfarming
+        qxz_alarm = db.sa_qxz_alarm_log_new
+        k = qxz_alarm.find_one(sort=[("id", -1)])["id"] + 1
+        query = {'device_id': "864865060482180"}
+        data = qxz_alarm.find(query, {"_id":0, "warning_content": 1, "upl_time": 1}).sort("upl_time", pymongo.DESCENDING).limit(5)
+        myclient.close()
+        return Response({"warning": list(data), "mtg_name": True})
+    
+
+class CameraDetail(APIView):
+    # 监控数据
+    def post(self, request):
+        myclient = get_table()
+        db = myclient.smartfarming
+        sa_device_camera = db.sa_device_camera
+        sa_device_camera_account = db.sa_device_camera_account
+        sa_device = db.sa_device
+        result = []
+        for device_id in ["L31671797-1", "L42185263-1"]:
+            camera = sa_device_camera.find_one({"device_id": device_id}, {"device_info": 1, "account_id": 1, "_id": 0})
+            addr = camera.get("device_info")
+            account_id = camera.get("account_id")
+            camera_account = sa_device_camera_account.find_one({"id": account_id}, {"account_type": 1, "_id": 0})
+            if camera_account:
+                account_type = camera_account.get("account_type")
+                if account_type == 0:
+                    addr = addr.replace("http://", "https://")
+                elif account_type == 1:
+                    pass
+            else:
+                addr = addr.replace("http://", "https://")
+            device_info = sa_device.find_one({"device_id": device_id}, {"_id": 0, "device_name":1})
+            device_name = device_info.get("device_name")
+            result.append({
+                "device_id": device_id,
+                "device_name": device_name if device_name else device_id,
+                "device_info": addr,
+                "is_name": device_name,
+                
+            })
+        myclient.close()
+        return Response({"camera": result, "mtg_name": True})
+        

+ 15 - 1
apps/Equipment/urls.py

@@ -2,6 +2,14 @@ from django.conf.urls import url
 
 from . import views
 
+from .men_tou_gou import (
+    CountDeviceStatus,
+    QxData,
+    QxWarning,
+    CameraDetail
+)
+
+
 urlpatterns = [
     url(r'^search/$', views.SearchEquip.as_view(), name='equip_search'),
 
@@ -28,5 +36,11 @@ urlpatterns = [
 
     url(r'^gssq/list/$', views.GssqDeviceListView.as_view(), name='gssq_list'),
     url(r'^gssq/detail/$', views.GssqDeviceDetailView.as_view(), name='gssq_detail'),
-    
+
+    # 门头沟一张图
+    url(r'^mtg/device/$', CountDeviceStatus.as_view(), name='mtg_device'),
+    url(r'^mtg/qxz/$', QxData.as_view(), name='mtg_qxz'),
+    url(r'^mtg/qxz_warning/$', QxWarning.as_view(), name='mtg_qxz_warning'),
+    url(r'^mtg/camera/$', CameraDetail.as_view(), name='mtg_camera'),
+
 ]

+ 8 - 4
apps/Equipment/views.py

@@ -81,10 +81,14 @@ class QxzDeviceDetailView(APIView):
         conf_m = MongoDBTools(db_name='smartfarming', table_name='sa_qxz_conf')
         conf_data = conf_m.find_one(wheres=conf_wheres)
         if conf_data:
-            conf_data.pop("id")
-            conf_data.pop("device_id")
-            conf_data.pop("uptime")
-            conf_data = dict(sorted(conf_data.items(), key=lambda e:int(e[0].split("e")[1])))
+            conf_data_temp = {}
+            for k, v in conf_data.items():
+                if v:
+                    conf_data_temp[k] = v
+            conf_data_temp.pop("id")
+            conf_data_temp.pop("device_id")
+            conf_data_temp.pop("uptime")
+            conf_data = dict(sorted(conf_data_temp.items(), key=lambda e:int(e[0].split("e")[1])))
         result = {"conf":conf_data,"total_counts":0,"items":[]}
 
         data_m = MongoDBTools(db_name='smartfarming', table_name='sa_qxz_data')

+ 1 - 1
apps/IOTCard/views.py

@@ -320,7 +320,7 @@ class PlatformIOTCardViewSet(viewsets.ModelViewSet):
                     usage_value = ""
                 if usage_value == 0 or usage_value == "":
                     if uptime:
-                        time_diff_days = time_dif(uptime)
+                        time_diff_days = time_dif_new(uptime)
                         if time_diff_days > 270:
                             save_data["是否需要充值"].append("否")
                         else:

+ 1 - 0
apps/QxzApp/views.py

@@ -656,3 +656,4 @@ def init_data():
         c.is_default = True
         c.save()
 
+

+ 0 - 0
apps/Weather/__init__.py


+ 5 - 0
apps/Weather/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class UserappConfig(AppConfig):
+    name = 'apps.Weather'

+ 68 - 0
apps/Weather/models.py

@@ -0,0 +1,68 @@
+from django.db import models
+
+
+class District(models.Model):
+
+    id = models.AutoField("ID", primary_key=True)
+    city_id = models.CharField("城市ID", max_length=64, blank=True, null=True)
+    city = models.CharField("城市", max_length=64, blank=True, null=True)
+    pid = models.CharField("PID",max_length=64,  blank=True, null=True)
+
+    class Meta:
+        db_table = "district"
+
+
+class DayData(models.Model):
+
+    id = models.AutoField("ID", primary_key=True)
+    cityid = models.CharField("城市ID", max_length=64, blank=True, null=True)
+    province = models.CharField("省", max_length=64, blank=True, null=True)
+    city = models.CharField("市", max_length=64, blank=True, null=True)
+    district = models.CharField("区", max_length=64, blank=True, null=True)
+    content = models.TextField("天气")
+    class Meta:
+        db_table = "day_data"
+
+class ServerDayData(models.Model):
+
+    id = models.AutoField("ID", primary_key=True)
+    cityid = models.CharField("城市ID", max_length=64, blank=True, null=True)
+    province = models.CharField("省", max_length=64, blank=True, null=True)
+    city = models.CharField("市", max_length=64, blank=True, null=True)
+    district = models.CharField("区", max_length=64, blank=True, null=True)
+    content = models.TextField("天气")
+
+    class Meta:
+        db_table = "server_day_data"
+
+
+class AddressInfo(models.Model):
+
+    id = models.AutoField("ID", primary_key=True)
+    cityid = models.CharField("城市ID", max_length=64, blank=True, null=True)
+    province = models.CharField("省", max_length=64, blank=True, null=True)
+    city = models.CharField("市", max_length=64, blank=True, null=True)
+    district = models.CharField("区", max_length=64, blank=True, null=True)
+
+    class Meta:
+        db_table = "address_info"
+
+
+class HistoryData(models.Model):
+    id = models.AutoField("ID", primary_key=True)
+    timestamp = models.PositiveIntegerField("时间戳", default=0)
+    cityid = models.PositiveIntegerField("地址ID", default=0)
+    content = models.TextField("天气")
+
+    class Meta:
+        db_table = "history_data"
+
+
+class HistoryDayData(models.Model):
+
+    id = models.AutoField("ID", primary_key=True)
+    cityid = models.CharField("城市ID", max_length=64, blank=True, null=True)
+    content = models.TextField("天气")
+    addtime = models.PositiveIntegerField("时间", default=0)
+    class Meta:
+        db_table = "history_today"

+ 148 - 0
apps/Weather/views.py

@@ -0,0 +1,148 @@
+import traceback
+from rest_framework.views import APIView
+from rest_framework.response import Response
+from django.contrib.auth import authenticate
+from apps.Weather.models import DayData, ServerDayData, AddressInfo, HistoryData
+from apps.UserApp.models import MyUser
+
+import logging
+import json
+
+
+province_dict = {
+"11": '北京市',
+"12": '天津市',
+"13": '河北省',
+"14": '山西省',
+"15": '内蒙古自治区',
+"21": '辽宁省',
+"22": '吉林省',
+"23": '黑龙江省',
+"31": '上海市',
+"32": '江苏省',
+"33": '浙江省',
+"34": '安徽省',
+"35": '福建省',
+"36": '江西省',
+"37": '山东省',
+"41": '河南省',
+"42": '湖北省',
+"43": '湖南省',
+"44": '广东省',
+"45": '广西壮族自治区',
+"46": '海南省',
+"50": '重庆市',
+"51": '四川省',
+"52": '贵州省',
+"53": '云南省',
+"54": '西藏自治区',
+"61": '陕西省',
+"62": '甘肃省',
+"63": '青海省',
+"64": '宁夏回族自治区',
+"65": '新疆维吾尔自治区'
+}
+
+
+
+logging.basicConfig(level=logging.DEBUG, filename='/data/logs/weather.log', filemode='w',
+                    format='%(asctime)s - %(levelname)s - %(message)s')
+
+class GetWeather(APIView):
+
+    def post(self, request):
+        # 对外提供天气接口,需要提供省,市,区(县)
+        try:
+            data = request.data
+            cityid = data.get("cityid", "")
+            province = data.get("province")
+            city = data.get("city")
+            district = data.get("district")
+            day_type = data.get("day_type")
+            username = data.get("username")
+            password = data.get("password")
+            user = authenticate(username=username, password=password)
+            if not user:
+                return Response({"msg":"认证失败", "code": 400})
+            table = DayData if day_type == "1" else ServerDayData
+            if cityid:
+                logging.warning(f"{cityid}: 使用cityid查询")
+                query = table.objects.filter(cityid=cityid)
+                if  query:
+                    temp = query.first().content.replace("'", '"')
+                    try:
+                        result = json.loads(temp)
+                    except json.decoder.JSONDecodeError:
+                        result = eval(temp)
+                    return Response({"content": result, "msg": "success", "code": 200})
+                else:
+                    return Response({"msg": "请联系管理员排查", "code": 500})
+            else:
+                logging.warning("使用province,city,distinct查询")
+                query = table.objects.filter(province=province, city=city, district=district)
+                if not query:
+                    # 省市正确
+                    query = table.objects.filter(province=province, city=city)
+                    if not query:
+                        # 省正确
+                        query = table.objects.filter(province=province)
+                        
+                if query:
+                    try:
+                        temp = query.first()
+                        temp = (temp.content).replace("'", '"')
+                        try:
+                            result = json.loads(temp)
+                        except json.decoder.JSONDecodeError:
+                            result = eval(temp)
+                        return Response({"content": result, "msg": "success", "code": 200})
+                    except Exception as e:
+                        logging.info(f"cityid: {cityid} province:{province} city:{city} district: {district}   {traceback.format_exc()}")
+                        return Response({"msg": "请联系管理员", "code": "50001"})
+                else:
+                    return Response({"content": "", "msg": "success", "code": 500})
+        except Exception as e:
+            logging.info(f"cityid: {cityid} province:{province} city:{city} district: {district}   {traceback.format_exc()}")
+            return Response({"msg": "请联系管理员", "code": "50001"})
+        
+
+class HistoryAPIView(APIView):
+
+    def post(self, request):
+        data = request.data
+        timestamp = data.get("timestamp") 
+        province = data.get("province")
+        city = data.get("city")
+        district = data.get("district")
+        district = AddressInfo.objects.filter(province=province, city=city, district=district)
+        if district:
+            cityid = district.first().cityid
+        else:
+            msg = f"地区:{district} 取不到,使用 {province} {city} 取"
+            logging.warning(msg)
+            city = AddressInfo.objects.filter(province=province, city=city)
+            if city:
+                cityid = city.first().cityid
+            else:
+                return Response({"msg": "暂无数据", "code": 500})
+        # 去历史表中查询数据
+        try:
+            history_data = HistoryData.objects.get(cityid=cityid, timestamp=timestamp)
+            content = history_data.content
+            low_heigh = json.loads(content)
+            return Response(
+                {
+                    "data": [low_heigh["yWendu"], low_heigh["bWendu"]],
+                    "province": province,
+                    "city": city,
+                    "district": district
+                }
+            )
+        except Exception as e:
+            return Response({"msg": "暂无指定城市数据", "code": 500})
+        
+
+class TestAPI(APIView):
+
+    def post(self, request):
+        return Response({"test": 111})

+ 11 - 2
bigdataAPI/settings.py

@@ -24,9 +24,9 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 SECRET_KEY = '$rs)*w)9gh)nkf1=@r$2xguf1b(qz8ba!%hm8lwt54ti3_da^b'
 
 # SECURITY WARNING: don't run with debug turned on in production!
-DEBUG = False
+DEBUG = True
 
-if DEBUG == True:
+if DEBUG:
     config_path = os.path.join(BASE_DIR,"test.json")
 else:
     config_path = os.path.join(BASE_DIR,"formal.json")
@@ -58,6 +58,8 @@ INSTALLED_APPS = [
     'apps.PestAnalysis',
     'apps.Equipment',
     'apps.QxzApp',
+    'apps.Weather',
+    'apps.DeviceCount'
 ]
 
 MIDDLEWARE = [
@@ -151,6 +153,7 @@ USE_TZ = False
 # https://docs.djangoproject.com/en/2.1/howto/static-files/
 
 STATIC_URL = '/static/'
+STATIC_ROOT = os.path.join(BASE_DIR, 'static')
 
 AUTH_USER_MODEL = 'UserApp.MyUser'
 
@@ -170,3 +173,9 @@ REST_FRAMEWORK = {
 JWT_AUTH = {
     'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),
 }
+
+
+# 历史天气接口URL
+HISTORY_WEATHER_URL = "https://v0.yiketianqi.com/api?version=history&"
+HISTORY_WEATHER_APPID = "73341114"  # 73341114  69334222
+HISTORY_WEATHER_APPSECRET = "gCneL6mr"  # gCneL6mr  2u4bHXHD

+ 9 - 3
bigdataAPI/urls.py

@@ -13,14 +13,20 @@ Including another URLconf
     1. Import the include() function: from django.urls import include, path
     2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
 """
-# from django.contrib import admin
+from django.contrib import admin
 from django.urls import path, include
+from apps.Weather.views import GetWeather, TestAPI, HistoryAPIView
+from apps.DeviceCount.views import CbdPhotoCount
 
 urlpatterns = [
-    # path('admin/', admin.site.urls),
+    path('admin/', admin.site.urls),
     path('iotcard/', include('apps.IOTCard.urls')),
     path('user/', include('apps.UserApp.urls')),
     path('equipment/', include('apps.Equipment.urls')),
     path('pestanalysis/', include('apps.PestAnalysis.urls')),
-    path('qxzconfig/', include('apps.QxzApp.urls'))
+    path('qxzconfig/', include('apps.QxzApp.urls')),
+    path("yf_weather", GetWeather.as_view(), name="weather"),
+    path("yf_weather_history", HistoryAPIView.as_view(), name="history_weather"),
+    path("test", TestAPI.as_view(), name="test"),
+    path("cbd_count/", CbdPhotoCount.as_view(), name="cbd_count")
 ]

+ 85 - 0
crond_script/ct_cbd.py

@@ -0,0 +1,85 @@
+# coding=utf-8
+import os 
+import sys
+import time 
+import datetime
+import pymongo
+from urllib import parse
+import django
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.append(BASE_DIR)
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bigdataAPI.settings')
+django.setup()
+from apps.DeviceCount.models import CbdPhoto
+
+user = parse.quote_plus("root")
+passwd = parse.quote_plus("yfkj@6020")
+# 账号密码方式连接MongoDB | "mongodb://用户名:密码@公网ip:端口/"
+myclient = pymongo.MongoClient("mongodb://{0}:{1}@8.136.98.49:57017/".format(user,passwd))
+db = myclient.smartfarming
+device = db.sa_device
+cbdphoto_a_collection = db.sa_device_cbdphoto
+cbdphoto_b_collection = db.sa_device_cbdphoto
+cbdphoto_c_collection = db.sa_device_cbdphoto
+
+
+
+def main():
+    now = time.time()
+    # 过去 16.5 小时间戳
+    last = int(now) - 16.5 * 3600
+    date_format = datetime.datetime.fromtimestamp(now).strftime("%Y-%m-%d")
+    query = [
+        {
+            "$match": {
+                "addtime":{
+                    "$gte": last
+                }
+                
+            }
+        },
+        {
+            "$group": {
+                "_id": "$device_id",
+                "count": {"$sum": 1}
+            }
+        },
+        {
+            "$sort": {"count": -1}
+        }
+        ,
+        {
+            "$match": {
+                "count": {
+                    "$gte": 100
+                }
+            }
+        }
+    ]
+    a_result = cbdphoto_a_collection.aggregate(query)
+    a_result_lst = list(a_result)
+    ids = [int(i.get("_id")) for i in a_result_lst]
+    devices = device.find({"id": {"$in": ids}}, {"device_id": 1, "id": 1, "_id": 0})
+    id_de = {
+        str(i.get("id")): i.get("device_id")
+        for i in list(devices)
+    }
+    for k in a_result_lst:
+        id = k.get("_id")
+        org_photo_ct = k.get("count")
+        device_id = id_de.get(id)
+        cbd_photo, is_created = CbdPhoto.objects.get_or_create(
+            day = date_format,
+            device_id = device_id,
+            defaults={
+                "day": date_format,
+                "device_id": device_id,
+                "org_photo_ct": org_photo_ct
+            }
+        )
+        print(cbd_photo, is_created)
+    myclient.close()
+
+
+if __name__ == "__main__":
+    main()

+ 118 - 0
crond_script/server_weather.py

@@ -0,0 +1,118 @@
+from datetime import datetime
+import requests
+import sqlite3
+import json
+import os
+import sys
+from weather import all_city
+import logging
+import django
+import time
+import random
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.append(BASE_DIR)
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bigdataAPI.settings')
+django.setup()
+from apps.Weather.models import District, DayData, ServerDayData
+
+app_id = "69334222"
+app_secret = "2u4bHXHD"
+
+province_dict = {
+"11": '北京市',
+"12": '天津市',
+"13": '河北省',
+"14": '山西省',
+"15": '内蒙古自治区',
+"21": '辽宁省',
+"22": '吉林省',
+"23": '黑龙江省',
+"31": '上海市',
+"32": '江苏省',
+"33": '浙江省',
+"34": '安徽省',
+"35": '福建省',
+"36": '江西省',
+"37": '山东省',
+"41": '河南省',
+"42": '湖北省',
+"43": '湖南省',
+"44": '广东省',
+"45": '广西壮族自治区',
+"46": '海南省',
+"50": '重庆市',
+"51": '四川省',
+"52": '贵州省',
+"53": '云南省',
+"54": '西藏自治区',
+"61": '陕西省',
+"62": '甘肃省',
+"63": '青海省',
+"64": '宁夏回族自治区',
+"65": '新疆维吾尔自治区'
+}
+
+def init_data():
+    # 导入全部的城市
+    for k in all_city:
+        print(k, "-------------")
+        district = District()
+        district.city_id = str(k[0])
+        district.city = k[1]
+        district.pid = str(k[2])
+        district.save()
+    
+
+def main():
+    headers = {
+        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299',
+        'Accept-Language': 'en-US,en;q=0.8',
+        'Accept-Encoding': 'gzip, deflate, br',
+        'Connection': 'keep-alive',
+    }
+    server_error = 0
+    print("up server day ...")
+    server_ct = 0
+    server_days = ServerDayData.objects.all()
+    server_start_ct_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+    for server_day_obj in server_days:
+        time_out_k = False 
+        print(server_day_obj.cityid)
+        server_day_url = f"http://v1.yiketianqi.com/api?unescape=1&version=v91&appid=69334222&appsecret=2ME6U58N&cityid={server_day_obj.cityid}&ext=hours,aqi,life"
+        server_day_response = requests.get(server_day_url, headers=headers, timeout=10)
+        server_ct += 1
+        try:
+            if server_day_response.status_code == 200:
+                server_day_data = json.loads(server_day_response.text)
+                if "errcode" not in server_day_data.keys():
+                    server_day_obj.content = str(server_day_data)
+                    server_day_obj.save()
+            else:
+                time.sleep(2)
+                print(f"cityid {server_day_obj.cityid}  error_code {server_day_response.status_code}")
+                print(f"request fail again : {server_day_obj.cityid}")
+                server_day_response = requests.get(server_day_url, headers=headers, timeout=5)
+                server_ct += 1
+                if server_day_response.status_code == 200:
+                    server_day_data = json.loads(server_day_response.text)
+                    if "errcode" not in server_day_data.keys():
+                        server_day_obj.content = str(server_day_data)
+                        server_day_obj.save()
+                        print(f"request again success: {server_day_obj.cityid}")
+                else:
+                    print(f"cityid {server_day_obj.cityid}  error_code {server_day_response.status_code}  again request afil")
+                    print(f"error {server_error}")
+                    server_error += 1
+                    time_out_k = True
+        except Exception as e:
+            print(f"request fail again : {server_day_obj.cityid} {e.args}")
+        if time_out_k:
+            time.sleep(1)
+        else:
+            time.sleep(0.5)
+    with open("/data/weather/weather_count.txt", 'a+', encoding='utf-8') as f:
+        f.write(f"七日天气接口:  开始时间:{server_start_ct_time}  结束时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} 调用次数:{server_ct}  \n")
+
+
+if __name__ == "__main__":
+    main()

+ 157 - 0
crond_script/today_weather.py

@@ -0,0 +1,157 @@
+from datetime import datetime
+import requests
+import sqlite3
+import json
+import os
+import sys
+from weather import all_city
+import logging
+import django
+import time
+import random
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.append(BASE_DIR)
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bigdataAPI.settings')
+django.setup()
+from apps.Weather.models import District, DayData, HistoryDayData
+# # 配置日志级别和格式
+# logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
+
+# # 创建一个文件处理器,指定日志文件名和写入模式
+# os.mkdir("/data/weather/") if not os.path.exists("/data/weather/") else None
+# file_handler = logging.FileHandler('/data/weather/app.log')
+# file_handler.setLevel(logging.INFO)
+
+# # 创建一个格式化程序,用于定义日志消息的显示方式
+# formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
+# file_handler.setFormatter(formatter)
+
+# # 将文件处理器添加到根日志记录器中
+# logging.getLogger('').addHandler(file_handler)
+
+app_id = "69334222"
+app_secret = "2u4bHXHD"
+
+province_dict = {
+"11": '北京市',
+"12": '天津市',
+"13": '河北省',
+"14": '山西省',
+"15": '内蒙古自治区',
+"21": '辽宁省',
+"22": '吉林省',
+"23": '黑龙江省',
+"31": '上海市',
+"32": '江苏省',
+"33": '浙江省',
+"34": '安徽省',
+"35": '福建省',
+"36": '江西省',
+"37": '山东省',
+"41": '河南省',
+"42": '湖北省',
+"43": '湖南省',
+"44": '广东省',
+"45": '广西壮族自治区',
+"46": '海南省',
+"50": '重庆市',
+"51": '四川省',
+"52": '贵州省',
+"53": '云南省',
+"54": '西藏自治区',
+"61": '陕西省',
+"62": '甘肃省',
+"63": '青海省',
+"64": '宁夏回族自治区',
+"65": '新疆维吾尔自治区'
+}
+
+def init_data():
+    # 导入全部的城市
+    for k in all_city:
+        print(k, "-------------")
+        district = District()
+        district.city_id = str(k[0])
+        district.city = k[1]
+        district.pid = str(k[2])
+        district.save()
+    
+
+def main():
+    headers = {
+        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299',
+        'Accept-Language': 'en-US,en;q=0.8',
+        'Accept-Encoding': 'gzip, deflate, br',
+        'Connection': 'keep-alive',
+    }
+    print("up today ....")
+    day_data = DayData.objects.all()
+    today_error = 0
+    # 调用次数统计
+    day_ct = 0
+    now = datetime.now()
+    start_ct_time = now.strftime('%Y-%m-%d %H:%M:%S')
+    now_hour = now.hour
+    today_str = datetime.strptime(f'{now.year}-{now.month}-{now.day} 19:00:00', "%Y-%m-%d %H:%M:%S")
+    for day_obj in day_data:
+        time_out = False 
+        print(day_obj.cityid)
+        today_url = f"http://v1.yiketianqi.com/api?unescape=1&version=v62&appid=69334222&appsecret=2ME6U58N&cityid={day_obj.cityid}"
+        today_response = requests.get(today_url, headers=headers, timeout=10)
+        day_ct += 1
+        try:
+            if today_response.status_code == 200:
+                today_data = json.loads(today_response.text)
+                if "errcode" not in today_data.keys():
+                    day_obj.content = str(today_data)
+                    day_obj.save()
+                    try:
+                        if now_hour == 19:
+                            HistoryDayData.objects.create(
+                                cityid = day_obj.cityid,
+                                content = today_data,
+                                addtime = int(today_str.timestamp())
+                            )
+                    except Exception as e:
+                        print(e, "历史数据入库失败")
+            else:
+                print(f"cityid {day_obj.cityid}  error_code {today_response.status_code}")
+                print(f"request fail again : {day_obj.cityid}")
+                time.sleep(2)
+                today_response = requests.get(today_url, headers=headers, timeout=5)
+                day_ct += 1
+                if today_response.status_code == 200:
+                    today_data = json.loads(today_response.text)
+                    if "errcode" not in today_data.keys():
+                        day_obj.content = str(today_data)
+                        day_obj.save()
+                        print(f"request again success: {day_obj.cityid}")
+                        try:
+                            if now_hour == 19:
+                                HistoryDayData.objects.create(
+                                    cityid = day_obj.cityid,
+                                    content = today_data,
+                                    addtime = int(today_str.timestamp())
+                                )
+                        except Exception as e:
+                            print(e, "历史数据入库失败")
+                else:
+                    print(f"cityid {day_obj.cityid}  error_code {today_response.status_code}  again request fail")
+                    print(f"error {today_error}")
+                    today_error += 1
+                    time_out = True
+        except Exception as e:
+            print(f"request fail again : {day_obj.cityid} {e.args}")
+        if time_out:
+            time.sleep(1)
+        else:
+            time.sleep(0.5)
+
+    with open("/data/weather/weather_count.txt", 'a+', encoding='utf-8') as f:
+        f.write(f"当日天气接口:  开始时间:{start_ct_time}  结束时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} 调用次数:{day_ct} \n")
+
+    # 把19点的数据写入历史天气数据中
+    
+
+if __name__ == "__main__":
+    main()

ファイルの差分が大きいため隠しています
+ 3391 - 0
crond_script/weather.py


+ 72 - 0
crond_script/weather_history.py

@@ -0,0 +1,72 @@
+import requests
+import datetime
+import json
+import os
+import sys
+from weather import all_city
+import logging
+import django
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.append(BASE_DIR)
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bigdataAPI.settings')
+django.setup()
+from django.conf import settings
+from apps.Weather.models import HistoryData, AddressInfo, DayData
+
+
+# 配置日志级别和格式
+logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
+file_handler = logging.FileHandler('/data/weather/history.log')
+file_handler.setLevel(logging.INFO)
+# 创建一个格式化程序,用于定义日志消息的显示方式
+formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
+file_handler.setFormatter(formatter)
+# 将文件处理器添加到根日志记录器中
+logging.getLogger('').addHandler(file_handler)
+
+
+def add_address_info_data():
+    address = AddressInfo.objects.all().count()
+    if not address:
+        day_data = DayData.objects.all()
+        for day in day_data:
+            AddressInfo.objects.get_or_create(
+                cityid = day.cityid,
+                defaults={
+                    "cityid": day.cityid,
+                    "province": day.province,
+                    "city": day.city,
+                    "district": day.district
+                }
+            )
+    else:
+        logging.warning("address_info 已存在数据")
+
+
+def history_data():
+    url = settings.HISTORY_WEATHER_URL
+    appid = settings.HISTORY_WEATHER_APPID
+    appsecret = settings.HISTORY_WEATHER_APPSECRET
+    address = AddressInfo.objects.all().values("cityid")
+    for i in address[:1]:
+        cityid = i.get("cityid")
+        for y in [2022, 2023]:
+            for m in range(1,13):
+                response = requests.get(url=f"{url}appid={appid}&appsecret={appsecret}&cityid={cityid}&year={y}&month={m}")
+                result = json.loads(response.text)
+                for k in result["data"]:
+                    ymd = k["ymd"]
+                    timestamp = datetime.datetime.strptime(ymd, "%Y-%m-%d").timestamp()
+                    HistoryData.objects.get_or_create(
+                        timestamp = timestamp,
+                        cityid = cityid,
+                        defaults={
+                            "timestamp":timestamp,
+                            "cityid": cityid,
+                            "content": str(k)
+                        }
+                    )
+
+
+if __name__ == "__main__":
+    history_data()

+ 5 - 5
test.json

@@ -1,24 +1,24 @@
 {
 	"mysql": {
-		"host": "localhost",
+		"host": "114.55.0.7",
 		"port": 3306,
-		"user": "api",
+		"user": "root",
 		"pwd": "yfkj@6020"
 	},
 	"redis": {
-		"host": "localhost",
+		"host": "114.55.0.7",
 		"port": "56379",
 		"password": "yf6021",
         "url": "redis://:yf6021@127.0.0.1:56379/12"
 	},
 	"bigdatamysql": {
-		"host": "localhost",
+		"host": "114.55.0.7",
 		"port": 3306,
 		"user": "root",
 		"pwd": "yfkj@6020"
 	},
 	"bigdatamongo": {
-		"host": "localhost",
+		"host": "114.55.0.7",
 		"port": 27017,
 		"user": "root",
 		"pwd": "yfkj@6020"

+ 8 - 0
utils/rendererresponse.py

@@ -14,6 +14,14 @@ class CustomRender(JSONRenderer):
         # print(renderer_context["response"].status_code)
         # print(renderer_context["response"].accepted_media_type)
         if renderer_context:
+            # 优化处理指定返回code的数据
+            if isinstance(data, dict) and renderer_context["response"].status_code == 200 and data.get("mtg_name"):
+                ret = {
+                    'code': "000000",
+                    'msg': "success",
+                    'data': data,
+                }
+                return super().render(ret, accepted_media_type, renderer_context)
             if isinstance(data, dict):
                 msg = data.pop('msg', 'success')
                 code = data.pop('code', renderer_context["response"].status_code)

+ 6 - 1
uwsgi.ini

@@ -29,7 +29,12 @@ enable-threads=true
 post-buffering=4096
 # 设置日志目录
 daemonize=/data/bigdataAPI/uwsgi/uwsgi.log
-
+# 启用日志按日期分割
+log-date = %Y-%m-%d
+# 设置日志备份文件的名称格式
+log-backupname = /data/bigdataAPI/uwsgi/uwsgi.{date}.log
+# 设置日志保留的时间(7天)
+log-keep = 7
 
 harakiri=3600
 http-timeout=3600