Pārlūkot izejas kodu

初始化仓库

yf_yzl 2 gadi atpakaļ
revīzija
3d84b716c2
100 mainītis faili ar 10223 papildinājumiem un 0 dzēšanām
  1. 20 0
      .vscode/launch.json
  2. 10 0
      README.md
  3. 1 0
      base.json
  4. 15 0
      formal
  5. 0 0
      kedong/__init__.py
  6. BIN
      kedong/__pycache__/__init__.cpython-36.pyc
  7. BIN
      kedong/__pycache__/decoration.cpython-36.pyc
  8. BIN
      kedong/__pycache__/settings.cpython-36.pyc
  9. BIN
      kedong/__pycache__/tools.cpython-36.pyc
  10. BIN
      kedong/__pycache__/urls.cpython-36.pyc
  11. BIN
      kedong/__pycache__/utils.cpython-36.pyc
  12. BIN
      kedong/__pycache__/wsgi.cpython-36.pyc
  13. 198 0
      kedong/decoration.py
  14. 253 0
      kedong/settings.py
  15. 21 0
      kedong/tools.py
  16. 12 0
      kedong/urls.py
  17. 69 0
      kedong/utils.py
  18. 16 0
      kedong/wsgi.py
  19. 15 0
      logs/app.log
  20. 0 0
      logs/app.log.2023-06-27
  21. 13 0
      logs/app.log.2023-06-28
  22. 0 0
      logs/data_ingestion.log
  23. 0 0
      logs/django.log
  24. 2 0
      logs/other.log
  25. 0 0
      logs/other.log.2023-07-08
  26. 15 0
      manage.py
  27. BIN
      media/123.jpg
  28. BIN
      media/192.168.1.64_01_20230328205244808_ALARM_INPUT.jpg
  29. 147 0
      requirements.txt
  30. 38 0
      restart.sh
  31. 181 0
      scripts/cbd_device.py
  32. 115 0
      scripts/ftp_server_spider_new.py
  33. 89 0
      scripts/mqtt_gateway.py
  34. 44 0
      scripts/test/add_pests.py
  35. 109 0
      scripts/test/cbd_data.py
  36. 83 0
      scripts/test/cbd_device_config.py
  37. 75 0
      scripts/test/cbd_photo.py
  38. 58 0
      scripts/test/cbd_save_photo.py
  39. 46 0
      scripts/test/dbd_warning.py
  40. 113 0
      scripts/test/jk_data.py
  41. 91 0
      scripts/test/qx_conf.py
  42. 142 0
      scripts/test/qx_data.py
  43. 122 0
      scripts/test/scd_data.py
  44. 107 0
      scripts/test/xy_data.py
  45. 59 0
      scripts/tools/utils.py
  46. 0 0
      smartfarming/__init__.py
  47. BIN
      smartfarming/__pycache__/__init__.cpython-36.pyc
  48. BIN
      smartfarming/__pycache__/admin.cpython-36.pyc
  49. BIN
      smartfarming/__pycache__/qxz.cpython-36.pyc
  50. BIN
      smartfarming/__pycache__/urls.cpython-36.pyc
  51. BIN
      smartfarming/__pycache__/utils.cpython-36.pyc
  52. 3 0
      smartfarming/admin.py
  53. 1 0
      smartfarming/api/__init__.py
  54. BIN
      smartfarming/api/__pycache__/__init__.cpython-36.pyc
  55. BIN
      smartfarming/api/__pycache__/sites.cpython-36.pyc
  56. 26 0
      smartfarming/api/sites.py
  57. 62 0
      smartfarming/api/views/__init__.py
  58. BIN
      smartfarming/api/views/__pycache__/__init__.cpython-36.pyc
  59. 0 0
      smartfarming/api/views/camera/__init__.py
  60. BIN
      smartfarming/api/views/camera/__pycache__/__init__.cpython-36.pyc
  61. BIN
      smartfarming/api/views/camera/__pycache__/camera_manage.cpython-36.pyc
  62. 220 0
      smartfarming/api/views/camera/camera_manage.py
  63. 3 0
      smartfarming/api/views/device/__init__.py
  64. BIN
      smartfarming/api/views/device/__pycache__/__init__.cpython-36.pyc
  65. BIN
      smartfarming/api/views/device/__pycache__/device_manage.cpython-36.pyc
  66. BIN
      smartfarming/api/views/device/__pycache__/device_sms_alert.cpython-36.pyc
  67. 97 0
      smartfarming/api/views/device/device_manage.py
  68. 113 0
      smartfarming/api/views/device/device_sms_alert.py
  69. 3 0
      smartfarming/api/views/forecast/__init__.py
  70. BIN
      smartfarming/api/views/forecast/__pycache__/__init__.cpython-36.pyc
  71. BIN
      smartfarming/api/views/forecast/__pycache__/all_dict.cpython-36.pyc
  72. BIN
      smartfarming/api/views/forecast/__pycache__/common.cpython-36.pyc
  73. BIN
      smartfarming/api/views/forecast/__pycache__/forecast_system.cpython-36.pyc
  74. BIN
      smartfarming/api/views/forecast/__pycache__/send_control.cpython-36.pyc
  75. BIN
      smartfarming/api/views/forecast/__pycache__/worm_lamp.cpython-36.pyc
  76. 1157 0
      smartfarming/api/views/forecast/all_dict.py
  77. 61 0
      smartfarming/api/views/forecast/common.py
  78. 664 0
      smartfarming/api/views/forecast/forecast_system.py
  79. 862 0
      smartfarming/api/views/forecast/send_control.py
  80. 2095 0
      smartfarming/api/views/forecast/worm_lamp.py
  81. 3 0
      smartfarming/api/views/weather/__init__.py
  82. BIN
      smartfarming/api/views/weather/__pycache__/__init__.cpython-36.pyc
  83. BIN
      smartfarming/api/views/weather/__pycache__/all_dict.cpython-36.pyc
  84. BIN
      smartfarming/api/views/weather/__pycache__/weather.cpython-36.pyc
  85. 107 0
      smartfarming/api/views/weather/all_dict.py
  86. 409 0
      smartfarming/api/views/weather/weather.py
  87. 5 0
      smartfarming/apps.py
  88. BIN
      smartfarming/middleware/__pycache__/response.cpython-36.pyc
  89. 71 0
      smartfarming/middleware/response.py
  90. 1969 0
      smartfarming/migrations/0001_initial.py
  91. 0 0
      smartfarming/migrations/__init__.py
  92. BIN
      smartfarming/migrations/__pycache__/0001_initial.cpython-36.pyc
  93. BIN
      smartfarming/migrations/__pycache__/__init__.cpython-36.pyc
  94. 13 0
      smartfarming/models/__init__.py
  95. BIN
      smartfarming/models/__pycache__/__init__.cpython-36.pyc
  96. BIN
      smartfarming/models/__pycache__/agriculture.cpython-36.pyc
  97. BIN
      smartfarming/models/__pycache__/ascend.cpython-36.pyc
  98. BIN
      smartfarming/models/__pycache__/camera.cpython-36.pyc
  99. BIN
      smartfarming/models/__pycache__/device.cpython-36.pyc
  100. 0 0
      smartfarming/models/__pycache__/green_house.cpython-36.pyc

+ 20 - 0
.vscode/launch.json

@@ -0,0 +1,20 @@
+{
+    // 使用 IntelliSense 了解相关属性。 
+    // 悬停以查看现有属性的描述。
+    // 欲了解更多信息,请访问: 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:8000"
+            ],
+            "django": true,
+            "justMyCode": true
+        }
+    ]
+}

+ 10 - 0
README.md

@@ -0,0 +1,10 @@
+## 气象站涉及表格
+```
+气象站基础信息表      MongoQXZ_Base_Info    sa_qxz_base_info
+新气象站全部数据记录  QXZdata_New            sa_qxz_data
+新气象站配置表        MongoQXZ_Conf         sa_qxz_conf
+气象站短信预警        MongoQXZ_Alarm_New    sa_qxz_alarm_new
+气象站开关配置表      MongoQXZ_Switch       sa_qxz_switch
+气象站阈值表          MongoQXZ_Auto_Switch  sa_qxz_auto_switch
+气象站开关定时表      MongoQXZ_Timing_Switch sa_qxz_timing_switch
+```

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
base.json


+ 15 - 0
formal

@@ -0,0 +1,15 @@
+{
+  "bigdata": {
+    "debug": 0,
+    "mysql_host": "127.0.0.1",
+    "mysql_port": 3306,
+    "mysql_user": "kedong",
+    "mysql_password": "%RDX2wsx9ijn%TGB",
+    "mysql_db": "smarfarming"
+  },
+  "mqtt_config":{
+    "ip": "127.0.0.1",
+    "port": 1883,
+    "user":"mq_yfkj"
+  }
+}

+ 0 - 0
kedong/__init__.py


BIN
kedong/__pycache__/__init__.cpython-36.pyc


BIN
kedong/__pycache__/decoration.cpython-36.pyc


BIN
kedong/__pycache__/settings.cpython-36.pyc


BIN
kedong/__pycache__/tools.cpython-36.pyc


BIN
kedong/__pycache__/urls.cpython-36.pyc


BIN
kedong/__pycache__/utils.cpython-36.pyc


BIN
kedong/__pycache__/wsgi.cpython-36.pyc


+ 198 - 0
kedong/decoration.py

@@ -0,0 +1,198 @@
+import time
+import json
+import traceback
+import collections
+import sys
+
+from django.db import transaction
+from django.core.exceptions import ObjectDoesNotExist
+from django.http import HttpResponse
+from django.views.decorators.csrf import csrf_exempt
+from django.contrib.auth.models import User
+from django.contrib.sessions.models import Session
+from django.utils import timezone
+
+
+from kedong.utils import PrAes
+from smartfarming.models.user import DeviceUser
+
+
+JsonResponse = lambda x: HttpResponse(json.dumps(x, indent=True,ensure_ascii=False),content_type="application/json")
+
+class PortError(Exception):
+    def __init__(self, field_name, message,data=1):
+        Exception.__init__(self)
+        self.message = message
+        self.field_name = field_name
+        self.data = data
+    def __str__(self):
+        return str("$fielderror" + json.dumps({"field_name": self.field_name, "message": self.message,"data": self.data}))
+    def __unicode__(self):
+        return str("$fielderror" + json.dumps({"field_name": self.field_name, "message": self.message,"data": self.data}))
+
+
+class ReturnValue(Exception):
+    def __init__(self, data, message=""):
+        self.data = data
+        self.message = message
+
+def session_check(session_key):
+    try:
+        sessions = Session.objects.get(session_key=session_key)
+    except:
+        return False
+    else:
+        expired_time = sessions.expire_date
+        if timezone.now() < expired_time:
+            sessions = sessions.get_decoded()
+            return sessions
+        else:
+            return False
+
+
+def kedong_deco(login_required=False,inteam_required=False,inproject_required=False):
+    def _kedong_deco(views):
+        @csrf_exempt
+        def _(request, *args, **kwargs):
+            start_time = time.time()
+            params = {}
+            for i in request.POST:
+                params[str(i)] = request.POST[i]
+            session_key = request.POST.get("token", "")
+            if '%2B' in session_key or " " in session_key:
+                session_key = str(session_key).replace("%2B","+").replace(" ","+")
+            try:
+                session_key = PrAes.aesdecrypt(session_key)
+            except:
+                pass
+            try:
+                if session_key:
+                    sessions = session_check(session_key)
+                    assert sessions
+            except Exception as e:
+                _result = (
+                        {"errorCode": 403, "message": "session 校验失败!无权访问!",
+                            "formError": {}, "data": None})
+            else:
+                try:
+                    value = sessions.get('user_id')
+                    try:
+                        ip = request.META['HTTP_X_FORWARDED_FOR']
+                    except:
+                        ip = request.META['REMOTE_ADDR']
+                    uid = int(value)
+                    state = 1
+                    try:
+                        auto_login_uid = int(sessions.get('auto_login_uid'))
+                        temp_state = auto_login_uid - uid
+                        if temp_state in [1, 4]:
+                            state = temp_state
+                    except Exception as e:
+                        pass
+                    device_user = DeviceUser.objects.get(uid=uid, state=state)
+                    request.myuser = device_user
+                    request.ip = ip
+                    try:
+                        perm = device_user.perm(uid)
+                        request.user_perm = perm
+                        request.role_id = device_user.role_id
+                        request.user_type = device_user.user_type
+                    except:
+                        request.user_perm = None
+                        request.role_id = None
+                        pass
+                except:
+                    request.myuser = None
+                    request.user_perm = None
+                    request.role_id = None
+                if request.method == "OPTIONS":
+                    _result = {}
+                else:
+                    if login_required and not request.myuser:
+                        _result = (
+                            {"errorCode": 403, "message": "当前设备尚未登陆,不允许操作",
+                                "formError": {}, "data": None})
+                    else:
+                        _result = None
+                        if login_required:
+                            perm = request.user_perm
+                            port_name = views.__name__
+                            if port_name == 'logout_user':
+                                del sessions['user_id']
+                            if port_name in ["lamp_list"]:
+                                try:
+                                    device_type_id = request.POST["device_type_id"]
+                                    port_name = port_name + device_type_id
+                                except:
+                                    _result = (
+                                    {"errorCode": 500, "message": "device_type_id 必传", "formError": {},
+                                        "data": None})
+                            if not _result:
+                                if ("logout" not in port_name) and perm != 'all' \
+                                        and ('user_login_info' not in port_name) \
+                                        and ('user_theme' not in port_name) \
+                                        and ('changepwd' not in port_name):
+                                    if port_name == 'check_suyuan_user':
+                                        pass
+                        if not _result:
+                            try:
+                                try:
+                                    result = views(request, *args, **kwargs)
+                                except AssertionError as _re:
+                                    if str(_re).startswith("$fielderror"):
+                                        _re_info = str(_re).strip("$fielderror")
+                                        _re_info = json.loads(_re_info)
+                                        raise PortError(_re_info["field_name"], _re_info["message"])
+                                    else:
+                                        raise Exception(traceback.format_exc())
+                            except PortError as e:
+                                _result = ({"errorCode": 0, "message": e.message, "formError":
+                                    {"name": e.field_name, "message": e.message}, "data": None})
+                            else:
+                                message = ""
+                                http_origin = request.META.get('HTTP_ORIGIN', None)
+                                origin = "https://web.hnyfwlw.com"
+                                if http_origin == origin:
+                                    try:
+                                        temp_result = json.dumps(result)
+                                        temp_result = temp_result.replace("http://8.136.98.49:8002", f"{origin}:58002")
+                                        temp_result = temp_result.replace("http://8.136.98.49:8003", f"{origin}:58003")
+                                        temp_result = temp_result.replace("http://120.27.222.26:8002", f"{origin}:58002/siqing")
+                                        temp_result = temp_result.replace("http://static.yfpyx.com",
+                                                                          f"{origin}:58002/static.yfpyx.com")
+                                        temp_result = temp_result.replace("https://bkimg.cdn.bcebos.com",
+                                                                          f"{origin}:58002/bkimg.cdn.bcebos.com")
+                                        temp_result = temp_result.replace("http://47.99.110.100",
+                                                                          f"{origin}:58002/47.99.110.100")
+                                        result = json.loads(temp_result)
+                                    except Exception as e:
+                                        print('转换https异常: ', e)
+
+                                if isinstance(result, ReturnValue):
+                                    message = result.message
+                                    result = result.data
+                                _result = ({"errorCode": 0, "message": message, "formError": {}, "data": result})
+            _result["params"] = params
+            end_time = time.time()
+            delta_time = int((end_time - start_time) * 1000)
+            result = JsonResponse(_result)
+            result["Access-Control-Allow-Origin"] = "*"
+            if request.META.get("HTTP_ORIGIN"):
+                result["Access-Control-Allow-Origin"] = request.META.get("HTTP_ORIGIN")
+            result["Access-Control-Allow-Method"] = "OPTIONS, GET, POST"
+            result["X-Requested-With"] = "XMLHttpRequest"
+            result["Access-Control-Allow-Headers"] = "x-requested-with,session,Session,Content-Type,Accept,Origin"
+            result["Access-Control-Max-Age"] = "86400"
+            result["Access-Control-Allow-Credentials"] = "true"
+            return result
+        _.__doc__ = views.__doc__
+        _.login_required = login_required
+        _.inteam_required = login_required and inteam_required
+        _.inproject_required = login_required and inproject_required
+        _.api_factory = "bigdata_deco"
+        if not getattr(sys, "api_config", None):
+            sys.api_config = collections.OrderedDict()
+        module_name = views.__module__.replace('smartfarming.api.views.', '')
+        sys.api_config[module_name + "." + views.__name__] = _
+        return _
+    return _kedong_deco

+ 253 - 0
kedong/settings.py

@@ -0,0 +1,253 @@
+# coding=utf-8
+import logging
+import logging.config
+import os
+import redis
+from kedong.utils import parse_config_new
+
+
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+print(BASE_DIR)
+SECRET_KEY = 'qqou#yc6-2kj==&-$lr%q(1&5uqayp+zx$423q_%)fmsvms(e1'
+DEBUG = True
+ALLOWED_HOSTS = ["*"]
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'rest_framework',
+    'smartfarming',
+    'corsheaders',
+]
+MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'corsheaders.middleware.CorsMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    # 'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    # 'smartfarming.middleware.response.ResponseMiddleware'
+]
+
+
+REST_FRAMEWORK = {
+    'DEFAULT_PERMISSION_CLASSES': (
+        'smartfarming.permissions.smking.LoginPermission',
+    )
+}
+
+CORS_ORIGIN_WHITELIST = ()
+CORS_ALLOW_CREDENTIALS = True
+CORS_ORIGIN_ALLOW_ALL = True
+
+CORS_ALLOW_METHODS = (
+    'DELETE',
+    'GET',
+    'OPTIONS',
+    'PATCH',
+    'POST',
+    'PUT',
+    'VIEW',
+)
+CORS_ALLOW_HEADERS = (
+    'accept',
+    'accept-encoding',
+    'authorization',
+    'content-type',
+    'dnt',
+    'origin',
+    'user-agent',
+    'x-csrftoken',
+    'x-requested-with',
+)
+
+ROOT_URLCONF = 'kedong.urls'
+TEMPLATES = [
+    {
+        'BACKEND': 'django.template.backends.django.DjangoTemplates',
+        'DIRS': [],
+        'APP_DIRS': True,
+        'OPTIONS': {
+            'context_processors': [
+                'django.template.context_processors.debug',
+                'django.template.context_processors.request',
+                'django.contrib.auth.context_processors.auth',
+                'django.contrib.messages.context_processors.messages',
+            ],
+        },
+    },
+]
+WSGI_APPLICATION = 'kedong.wsgi.application'
+CONFIG = parse_config_new(BASE_DIR)
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': CONFIG['bigdata']['mysql_db'],
+        'USER': CONFIG['bigdata']['mysql_user'],
+        'PASSWORD': CONFIG['bigdata']['mysql_password'],
+        'HOST': CONFIG['bigdata']['mysql_host'],
+        'PORT': CONFIG['bigdata']['mysql_port'],
+        'OPTIONS': {'charset': 'utf8mb4'}
+    },
+    "mqtt_record_db": {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': CONFIG['mqtt_record_db']['mysql_db'],
+        'USER': CONFIG['mqtt_record_db']['mysql_user'],
+        'PASSWORD': CONFIG['mqtt_record_db']['mysql_password'],
+        'HOST': CONFIG['mqtt_record_db']['mysql_host'],
+        'PORT': CONFIG['mqtt_record_db']['mysql_port'],
+        'OPTIONS': {'charset': 'utf8mb4'}
+    }
+}
+# redis连接
+# REDIS 订阅数据
+redis_host = CONFIG["redis"]['ip']
+redis_port = CONFIG["redis"]['port']
+redis_password = CONFIG["redis"]['password']
+redis_db = CONFIG["redis_db"]
+# 下发指令 
+pub_redis = redis.ConnectionPool(
+    host=redis_host,
+    port=redis_port,
+    password=redis_password,
+    db=11,
+    decode_responses=True
+)
+pub_redis_pool = redis.StrictRedis(connection_pool=pub_redis)
+# REDIS 验证码
+captcha_redis = redis.ConnectionPool(
+    host=redis_host,
+    port=redis_port,
+    password=redis_password,
+    db=1,
+    decode_responses=True
+)   
+captcha_redis_pool = redis.StrictRedis(connection_pool=captcha_redis)
+# FTP监听
+ftp_redis = redis.ConnectionPool(
+    host=redis_host,
+    port=redis_port,
+    password=redis_password,
+    db=12,
+    decode_responses=True
+)
+ftp_redis_pool = redis.StrictRedis(connection_pool=ftp_redis)
+
+# Password validation
+# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+
+LANGUAGE_CODE = 'zh-hans'
+
+TIME_ZONE = 'Asia/Shanghai'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = False
+
+
+STATIC_URL = '/static/'
+MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
+MEDIA_ROOT = CONFIG.get("media") 
+os.makedirs(MEDIA_ROOT) if not os.path.exists(MEDIA_ROOT) else None 
+MEDIA_URL = '/media/'
+
+# 日志处理系统
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'handlers': {
+        'console': {  # 将日志输出到控制台
+            'class': 'logging.StreamHandler',
+            'formatter': 'simple'
+        },
+        'django': {  # 将日志写入到文件
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': 'logs/django.log',
+            'when': 'midnight',
+            'backupCount': 30,
+            'encoding': 'utf-8',
+            'formatter': 'verbose'
+        },
+        'myapp': {  # 将日志写入到文件
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': 'logs/app.log',
+            'when': 'midnight',
+            'backupCount': 30,
+            'encoding': 'utf-8',
+            'formatter': 'verbose'
+        },
+        'data_ingestion': {  # 将日志写入到文件
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': 'logs/data_ingestion.log',
+            'when': 'midnight',
+            'backupCount': 30,
+            'encoding': 'utf-8',
+            'formatter': 'verbose'
+        },
+        'other':{  # 记录utils中日志
+            'class': 'logging.handlers.TimedRotatingFileHandler',
+            'filename': 'logs/other.log',
+            'when': 'midnight',
+            'backupCount': 30,
+            'encoding': 'utf-8',
+            'formatter': 'verbose'
+        },
+    },
+    'loggers': {
+        'django': {  # 默认的日志器
+            'handlers': ['console'],
+            'level': 'INFO',
+            'propagate': True,
+        },
+        'myapp': {  # 自定义的日志器
+            'handlers': ['myapp'],
+            'level': 'WARNING',
+            'propagate': True,
+        },
+        'data_ingestion': {  # 自定义的日志器
+            'handlers': ['data_ingestion'],
+            'level': 'WARNING',
+            'propagate': True,
+        },
+        'other': {  # 自定义的日志器
+            'handlers': ['other'],
+            'level': 'WARNING',
+            'propagate': True,
+        },
+    },
+    'formatters': {
+        'simple': {
+            'format': '{asctime} - {levelname} - {message}',
+            'style': '{',
+        },
+        'verbose': {
+            'format': '{asctime} - {levelname} - {name} - {message}',
+            'style': '{',
+        },
+    },
+}
+
+logging.config.dictConfig(LOGGING)

+ 21 - 0
kedong/tools.py

@@ -0,0 +1,21 @@
+from kedong.settings import CONFIG
+import redis
+
+
+
+class RedisPool():
+
+    def __init__(self):
+        self.redis_host = CONFIG["redis"]['ip']
+        self.redis_port = CONFIG["redis"]['port']
+        self.redis_password = CONFIG["redis"]['password']
+
+    def get_redis_pool(self, db):
+        rk = redis.ConnectionPool(
+            host=self.redis_host,
+            port=self.redis_port,
+            password=self.redis_password,
+            db=db,
+            decode_responses=True
+        )
+        return redis.StrictRedis(connection_pool=rk)

+ 12 - 0
kedong/urls.py

@@ -0,0 +1,12 @@
+from django.conf import settings
+from django.contrib import admin
+from django.urls import path, include
+from django.conf.urls.static import static
+from smartfarming import api
+
+urlpatterns = [
+    path('admin/', admin.site.urls),
+    path("api/", include("smartfarming.urls")),
+    path("api_v1/", api.site.urls),  # API模块
+]
+urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

+ 69 - 0
kedong/utils.py

@@ -0,0 +1,69 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/5/18 9:17 上午
+# @Author  : Creat by Han
+from Crypto.Cipher import AES
+import base64
+import configparser
+import os
+import json
+
+environ = None
+try:
+    try:
+        with open(os.path.expanduser("~/.environ"), "r") as f:
+            environ = f.read().strip()
+            assert environ
+    except:
+        with open(os.path.expanduser("F:\.environ.txt"), "r") as f:
+            environ = f.read().strip()
+            assert environ
+except:
+    raise Exception("no ~/.environ found! you must create one!")
+
+_ = configparser.ConfigParser()
+_flag = None
+
+# 获取项目配置文件
+def parse_config_new(config_dir=None):
+    dir_name = os.path.dirname(os.path.dirname(__file__))
+    config_dir = os.path.abspath(dir_name)
+    global _flag
+    if not _flag:
+        with open(os.path.join(config_dir, "%s" % environ), "r") as f:
+            _flag = f.read()
+            if _flag:
+                _flag = json.loads(_flag)
+            else:
+                _flag = {}
+    return _flag
+
+
+# token加密
+class Aescrypt():
+    def __init__(self, key, model, iv, encode_):
+        self.encode_ = encode_
+        self.model = {'ECB': AES.MODE_ECB, 'CBC': AES.MODE_CBC}[model]
+        self.key = self.add_16(key)
+        if model == 'ECB':
+            self.aes = AES.new(self.key, self.model)
+        elif model == 'CBC':
+            self.aes = AES.new(self.key, self.model, iv)
+
+    def add_16(self, par):
+        par = par.encode(self.encode_)
+        while len(par) % 32 != 0:
+            par += b'\x00'
+        return par
+
+    def aesencrypt(self, text):
+        text = self.add_16(text)
+        self.encrypt_text = self.aes.encrypt(text)
+        return base64.encodebytes(self.encrypt_text).decode().strip()
+
+    def aesdecrypt(self, text):
+        text = base64.decodebytes(text.encode(self.encode_))
+        self.decrypt_text = self.aes.decrypt(text)
+        return self.decrypt_text.decode(self.encode_).strip('\0')
+
+
+PrAes = Aescrypt('yf7232275', 'ECB', '', 'gbk')

+ 16 - 0
kedong/wsgi.py

@@ -0,0 +1,16 @@
+"""
+WSGI config for kedong project.
+
+It exposes the WSGI callable as a module-level variable named ``application``.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
+"""
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kedong.settings')
+
+application = get_wsgi_application()

+ 15 - 0
logs/app.log

@@ -0,0 +1,15 @@
+2023-07-08 11:14:25,106 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:("'str' object has no attribute 'get'",)
+2023-07-08 11:33:09,079 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:("'str' object has no attribute 'get'",)
+2023-07-08 11:35:11,464 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1048, "Column 'device_type_id' cannot be null")
+2023-07-08 11:39:07,128 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 14:25:54,939 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 14:31:04,983 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 14:36:56,547 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 14:44:21,223 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 14:47:00,850 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 14:48:28,029 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 14:54:30,720 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 14:55:40,992 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:("'int' object is not callable",)
+2023-07-08 14:57:35,797 - ERROR - myapp - 测报灯设备 867038039304375 处理上报数据或增加设备失败,错误原因:("'int' object is not callable",)
+2023-07-08 15:26:30,235 - ERROR - myapp - 测报灯设备 867435052203452 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")
+2023-07-08 15:49:49,512 - ERROR - myapp - 测报灯设备 867435052203452 处理上报数据或增加设备失败,错误原因:(1264, "Out of range value for column 'device_id' at row 1")

+ 0 - 0
logs/app.log.2023-06-27


+ 13 - 0
logs/app.log.2023-06-28

@@ -0,0 +1,13 @@
+2023-06-28 05:07:36,095 - ERROR - myapp - Role matching query does not exist.
+2023-06-28 05:08:52,151 - ERROR - myapp - Role matching query does not exist.
+2023-06-28 05:11:39,338 - ERROR - myapp - int() argument must be a string, a bytes-like object or a number, not 'builtin_function_or_method'
+2023-06-28 05:12:49,820 - ERROR - myapp - int() argument must be a string, a bytes-like object or a number, not 'builtin_function_or_method'
+2023-06-28 05:14:51,003 - ERROR - myapp - Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'dict'>`
+2023-06-28 06:05:44,867 - ERROR - myapp - Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` to be returned from the view, but received a `<class 'dict'>`
+2023-06-28 08:02:16,642 - ERROR - myapp - 'BasePermissionMetaclass' object is not iterable
+2023-06-28 08:03:03,640 - ERROR - myapp - 'BasePermissionMetaclass' object is not iterable
+2023-06-28 08:03:39,721 - ERROR - myapp - 'BasePermissionMetaclass' object is not iterable
+2023-06-28 08:03:57,241 - ERROR - myapp - 'BasePermissionMetaclass' object is not iterable
+2023-06-28 08:05:26,177 - ERROR - myapp - 'BasePermissionMetaclass' object is not iterable
+2023-06-28 08:07:32,437 - ERROR - myapp - 'BasePermissionMetaclass' object is not iterable
+2023-06-28 08:08:11,631 - ERROR - myapp - 'Request' object has no attribute 'myuser'

+ 0 - 0
logs/data_ingestion.log


+ 0 - 0
logs/django.log


+ 2 - 0
logs/other.log

@@ -0,0 +1,2 @@
+2023-07-14 14:34:27,641 - ERROR - other - 获取腾讯地理位置接口失败  ('province',)
+2023-07-14 17:28:51,518 - ERROR - other - 获取腾讯地理位置接口失败  ('province',)

+ 0 - 0
logs/other.log.2023-07-08


+ 15 - 0
manage.py

@@ -0,0 +1,15 @@
+#!/usr/bin/env python
+import os
+import sys
+
+if __name__ == '__main__':
+    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'kedong.settings')
+    try:
+        from django.core.management import execute_from_command_line
+    except ImportError as exc:
+        raise ImportError(
+            "Couldn't import Django. Are you sure it's installed and "
+            "available on your PYTHONPATH environment variable? Did you "
+            "forget to activate a virtual environment?"
+        ) from exc
+    execute_from_command_line(sys.argv)

BIN
media/123.jpg


BIN
media/192.168.1.64_01_20230328205244808_ALARM_INPUT.jpg


+ 147 - 0
requirements.txt

@@ -0,0 +1,147 @@
+aiocontextvars==0.2.2
+aliyun-python-sdk-core==2.13.26
+aliyun-python-sdk-core-v3==2.13.11
+aliyun-python-sdk-kms==2.11.0
+amqp==1.4.9
+anyjson==0.3.3
+appdirs==1.4.4
+asgiref==3.4.1
+asn1crypto==1.4.0
+async-timeout==4.0.2
+autopep8==2.0.2
+backcall==0.2.0
+bcrypt==3.1.7
+billiard==3.3.0.23
+cached-property==1.5.2
+cachetools==4.2.1
+captcha==0.4
+casbin==0.8.4
+celery==3.1.26.post2
+certifi==2020.4.5.1
+cffi==1.14.3
+chardet==3.0.4
+charset-normalizer==2.0.12
+click==7.1.2
+click-didyoumean==0.3.0
+click-plugins==1.1.1
+click-repl==0.2.0
+configobj==5.0.6
+configparser==4.0.2
+contextvars==2.4
+crcmod==1.7
+cryptography==3.4.7
+cssselect==1.1.0
+cssutils==1.0.2
+cycler==0.10.0
+dataclasses==0.8
+DBUtils==3.0.2
+decorator==4.4.2
+Deprecated==1.2.13
+DingtalkChatbot==1.5.2
+Django==2.1.4
+django-celery==3.3.1
+django-cors-headers==2.4.0
+djangorestframework==3.11.0
+djangorestframework-jwt==1.11.0
+djongo==1.3.6
+docx==0.2.4
+dwebsocket==0.5.12
+fs==2.4.12
+fs.sshfs==1.0.0
+fuzzywuzzy==0.18.0
+gcpy-utils==0.2.15
+geographiclib==1.50
+geopy==2.1.0
+gevent==20.9.0
+greenlet==0.4.17
+gt-push-sdk==4.1.1.2
+gunicorn==20.0.4
+happybase==1.2.0
+haversine==2.8.0
+idna==2.9
+immutables==0.16
+importlib-metadata==4.8.3
+imutils==0.5.4
+install==1.3.5
+ipython==7.9.0
+ipython-genutils==0.2.0
+itchat==1.3.10
+jedi==0.17.2
+jieba==0.42.1
+jmespath==0.10.0
+kiwisolver==1.1.0
+kombu==3.0.37
+loguru==0.5.3
+lxml==4.6.2
+Markdown==3.3.6
+matplotlib==3.0.3
+munch==2.5.0
+mysqlclient==2.1.1
+numpy==1.18.5
+oauth==1.0.1
+opencv-contrib-python==3.4.1.15
+opencv-python==3.4.2.16
+oss2==2.13.0
+packaging==21.0
+paho-mqtt==1.5.0
+pandas==0.24.2
+paramiko==2.7.2
+parso==0.7.1
+pexpect==4.8.0
+pickleshare==0.7.5
+Pillow==7.1.1
+ply==3.11
+premailer==3.7.0
+prompt-toolkit==2.0.10
+property-cached==1.6.4
+protobuf==3.17.3
+psutil==5.7.2
+ptyprocess==0.6.0
+pycodestyle==2.10.0
+pycparser==2.20
+pycryptodome==3.9.8
+pycuber==0.2.2
+pyftpdlib==1.5.6
+Pygments==2.7.1
+pyinotify==0.9.6
+PyJWT==1.7.1
+pymongo==3.12.3
+PyMySQL==0.9.3
+PyNaCl==1.4.0
+pyparsing==2.4.7
+pypng==0.0.20
+PyQRCode==1.2.1
+pysftp==0.2.9
+python-dateutil==2.8.1
+python-docx==0.8.11
+python-Levenshtein==0.12.2
+pytz==2019.3
+qcloudsms-py==0.1.4
+redis==2.10.6
+requests==2.23.0
+simpleeval==0.9.12
+six==1.16.0
+sqlparse==0.2.4
+superlance==1.0.0
+supervisor==4.2.2
+threadpool==1.3.2
+thriftpy2==0.4.11
+tomli==1.2.3
+traitlets==4.3.3
+typing==3.7.4.3
+typing-extensions==3.10.0.2
+urllib3==1.25.9
+uWSGI==2.0.19.1
+vine==5.0.0
+wcwidth==0.2.5
+websockets==9.1
+wrapt==1.14.0
+xlrd==1.2.0
+XlsxWriter==3.1.0
+xlwt==1.3.0
+xpinyin==0.7.6
+yagmail==0.14.245
+zipp==1.2.0
+zipstream==1.1.4
+zope.event==4.5.0
+zope.interface==5.1.2

+ 38 - 0
restart.sh

@@ -0,0 +1,38 @@
+#!/usr/bin/env bash
+
+
+source activate pingpu
+
+DIR_NAME=$(cd `dirname "$0"`; pwd)
+SCRIPT_NAME="uwsgi.ini"
+SCRIPT_FILE="${DIR_NAME}/${SCRIPT_NAME}"
+
+function start_service() {
+    echo "启动中请稍等"
+
+    uwsgi --ini "${SCRIPT_FILE}"
+    sleep 1
+
+    local ret=$(ps axu | grep "${SCRIPT_FILE}" | grep -v grep | wc -l)
+    if [[ ${ret} -gt 0 ]];then
+        echo "服务启动成功"
+    else
+        echo -e "\033[31m 启动失败请检查 \033[0m"
+    fi
+}
+
+function stop_service() {
+    echo "停止服务中请稍等"
+    ps axu | grep "${SCRIPT_FILE}" | grep -v grep | awk '{print $2}' | xargs kill -9 >/dev/null 2>&1
+    local ret=$(ps axu | grep "${SCRIPT_FILE}"| grep -v grep | wc -l)
+    if [[ ${ret} -eq 0 ]];then
+        echo "服务停止成功"
+        start_service
+    else
+        echo -e "\033[31m 停止失败请检查 \033[0m"
+    fi
+}
+
+stop_service
+
+

+ 181 - 0
scripts/cbd_device.py

@@ -0,0 +1,181 @@
+# coding:utf-8
+import os
+import sys
+import time
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+from django.conf import settings
+from kedong.tools import RedisPool
+from scripts.tools.utils import dashuju_pub_mqtt
+
+
+cbd_redis_pool = RedisPool().get_redis_pool(settings.redis_db["cbd"])
+
+
+def re_cbd_publish(payload):
+    if settings.DEBUG:
+        return None
+
+    imei_id = payload['imei_id']
+    at, ah = payload['at'], payload['ah']
+    try:
+        at = str(round(float(at)))
+    except ValueError as e:
+        at = "25"
+    try:
+        ah = str(round(float(ah)))
+    except ValueError as e:
+        print('at_error', e, payload)
+        ah = "30"
+
+    publics = "/yfkj/cbd/sub/#"
+
+    TASK_TOPIC = publics.replace("#", imei_id)
+    payload_1 = {"cmd": "sensor", "ext": {"new_hum": ah, "new_tem": at}}
+    dashuju_pub_mqtt(TASK_TOPIC, payload_1)
+
+
+def re_pub_cbd_publish(data):
+    if settings.DEBUG:
+        return None
+
+    imei_id = data['imei_id']
+    payload = data['payload']
+    TASK_TOPIC = ""
+    if TASK_TOPIC:
+        dashuju_pub_mqtt(TASK_TOPIC, payload)
+
+
+class CbdDeviceController(DeviceController):
+
+    def cbd_device(self, data):
+        table_name = "sa_device_cbd_data"
+        DEVICE_NAME = "测报灯"
+        DTYPE = 3
+        serverconf = ''
+        payload = data['payload']
+        imei_id = data['imei_id']
+
+        re_cbd_publish(data)
+        re_pub_cbd_publish(data)
+
+        ext = payload["ext"]
+        dver_num = ext.get("dver", "")
+        # 0-手动,1-GPS,2-基站
+        gps = ext["gps"]  
+        lng, lat = data['lng'], data['lat']
+
+        device_code = 0
+        try:
+            device_code = int(ext.get("vtype", 0))
+        except Exception as e:
+            pass
+
+        now_time = int(time.time())
+        device_config = {
+            "cmd": "paramconf",
+            "ext": {
+                "hst": ext.get("hst", "0"),
+                "collt": ext.get("collt", ""),
+                "et": ext.get("et", ""),
+                "datt": ext.get("dat_f", 30),
+                "shake_sec": ext.get("shake_sec", 1),
+                "tpl": ext.get("tpl", 5),
+                "shake": ext.get("shake", 0),
+                "tph": ext.get("tph", 0),
+                "ts": ext.get("ts", 0),
+                "st": ext.get("st", 0),
+                "htim": ext.get("htim", 0),
+                "tt": ext.get("tt", 0),
+                "ds": ext.get("ds", 0),
+                "ws": ext.get("ws", 0),
+            }
+        }
+
+        temp_dict = {
+            'device_id': imei_id, 
+            'device_type_id': DTYPE, 
+            'dver_num': dver_num,
+            'addtime': now_time, 
+            'uptime': now_time, 
+            'device_name': DEVICE_NAME,
+            'lng': lng, 
+            'lat': lat, 
+            'gps': gps, 
+            'serverconf': serverconf, 
+            'device_status': 1,
+            'device_code': device_code
+        }
+        return temp_dict, device_config, table_name
+
+    def xct_device(self, data):
+        """吸虫塔设备"""
+        table_name = "sa_device_xct_data"
+        DEVICE_NAME = "吸虫塔"
+        # 设备类型id
+        DTYPE = 12
+
+        serverconf = ''
+        payload = data['payload']
+        imei_id = data['imei_id']
+
+        re_cbd_publish(data)
+
+        ext = payload["ext"]
+        dver_num = ext["dver"]
+         # 0-手动,1-GPS,2-基站
+        gps = ext["gps"] 
+        lng, lat = data["lng"], data["lat"]
+        now_time = int(time.time())
+        device_config = {
+            "cmd": "paramconf",
+            "ext": {
+                "dat_f": ext.get("dat_f", 30),  # 数据上传时间
+                "shake_sec": ext["shake_sec"],  # 震动时间
+                "shake": ext["shake"],  # 震动开关, 1开启 0关闭
+                "ds": ext["ds"],  # 设备开关机,1开机,0关机
+                "dver": ext["dver"],  # 版本号
+                "st": ext["st"],
+                "et": ext["et"],
+            }
+        }
+        temp_dict = {
+            'device_id': imei_id, 'device_type_id': DTYPE, 'dver_num': dver_num,
+            'addtime': now_time, 'uptime': now_time, 'device_name': DEVICE_NAME,
+            'lng': lng, 'lat': lat, 'gps': gps, 'serverconf': serverconf, 'device_status': 1,
+            'device_code': DTYPE
+        }
+
+        return temp_dict, device_config, table_name
+
+    def make_device_config(self, data):
+        payload = data['payload']
+        ext = payload["ext"]
+        try:
+            vtype = int(ext["vtype"])
+            if vtype == 6:
+                return self.xct_device(data)
+        except Exception as e:
+            pass
+        return self.cbd_device(data)
+
+
+if __name__ == "__main__":
+    # 正常消息订阅
+    PUBLICS = "/yfkj/cbd/pub/#"
+    # 离线消息订阅
+    OFFLINE = "/yfkj/cbd/offline/#"
+    cbd = CbdDeviceController()
+    key = "/yfkj/cbd"
+    while True:
+        try:
+            data = cbd_redis_pool.bpop(key)
+            now_time = int(time.time())
+            create_time = data['create_time']
+            if now_time - create_time > 3600:
+                continue
+            cbd.device_controller(data)
+        except Exception as e:
+            print(e)

+ 115 - 0
scripts/ftp_server_spider_new.py

@@ -0,0 +1,115 @@
+# coding:utf-8
+import os
+import sys
+import time
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+from django.conf import settings
+from pyftpdlib.authorizers import DummyAuthorizer
+from pyftpdlib.handlers import FTPHandler, _strerror, FilesystemError
+from pyftpdlib.servers import FTPServer
+
+ftp_redis_pool = settings.ftp_redis_pool
+CONFIG = settings.CONFIG
+ftp_dict = CONFIG['ftp_config']
+ftp_config = CONFIG['ftp']
+user_list = [
+    ("ftpuser", "yf_123456", "/home/ftpsite")
+]
+user_list.extend(ftp_dict.values())
+FTPHandler.permit_foreign_addresses = True
+
+
+class MyFTPHandler(FTPHandler):
+
+    def _get_redis_key(self, file, prefix):
+        key = None
+        for k in ftp_dict.keys():
+            if file.startswith(k):
+                key = f"{prefix}{k}"
+        return key
+
+    def push_redis(self, key, data):
+        ftp_redis_pool.push(key, data)
+
+    def on_file_received(self, file):
+        """上传结束回调"""
+        if not file.endswith('.jpg'):
+            return None
+        key = self._get_redis_key(file, prefix="/up_complete")
+        if key:
+            data = {
+                'path': file,
+                'create_time': int(time.time())
+            }
+            self.push_redis(key, data)
+
+    def on_incomplete_file_received(self, file):
+        if not file.endswith('.jpg'):
+            return None
+        if file.startswith("/data/ftp/photo/cbd/"):
+            key = self._get_redis_key(file, prefix="/up_complete")
+            if key:
+                data = {
+                    'path': file,
+                    'create_time': int(time.time())
+                }
+                self.push_redis(key, data)
+
+    def ftp_MFMT(self, path, timeval):
+        """真正上传完成调用"""
+        result = super().ftp_MFMT(path, timeval)
+        try:
+            file = result[1]
+            key = self._get_redis_key(file, prefix="/up_success")
+            if key:
+                data = {
+                    'path': file,
+                    'create_time': int(time.time())
+                }
+                self.push_redis(key, data)
+        except Exception as e:
+            pass
+        return result
+
+    def ftp_SIZE(self, path):
+        line = self.fs.fs2ftp(path)
+        if self._current_type == 'a':
+            why = "SIZE not allowed in ASCII mode"
+            self.respond("550 %s." % why)
+            return
+        real_path = self.fs.realpath(path)
+        is_file = self.fs.isfile(real_path)
+        if not is_file:
+            why = "%s is not retrievable" % line
+            self.respond("550 %s." % why)
+            return
+        try:
+            size = self.run_as_current_user(self.fs.getsize, path)
+        except (OSError, FilesystemError) as err:
+            why = _strerror(err)
+            self.respond('550 %s.' % why)
+        else:
+            self.respond("213 %s" % size)
+
+
+def main():
+    # 启动FTP服务
+    authorizer = DummyAuthorizer()
+    for i in user_list:
+        path = i[2]
+        if not os.path.isdir(path):
+            os.makedirs(path)
+        authorizer.add_user(i[0], i[1], path, perm="elradfmwMT")
+    handler = MyFTPHandler
+    handler.authorizer = authorizer
+    handler.passive_ports = range(2000, 6333)
+    server = FTPServer((ftp_config['ip'], ftp_config['port']), handler)
+    server.max_cons = 2048
+    server.serve_forever()
+
+
+if __name__ == '__main__':
+    main()

+ 89 - 0
scripts/mqtt_gateway.py

@@ -0,0 +1,89 @@
+import os
+import sys
+import json
+import time
+import datetime
+import threading
+import logging
+import paho.mqtt.client as mqtt
+import django
+from pathlib import Path
+local_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+print(local_path)
+sys.path.append(local_path)
+print(sys.path)
+try:
+    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+    from django.conf import settings
+    django.setup()
+    from smartfarming.models.mqtt_models import PubRecord, PublishRecord
+    from scripts.tools.utils import DeviceConfig
+except Exception as e:
+    print(e)
+    exit(0)
+
+
+CONFIG = settings.CONFIG
+pub_redis_pool = settings.pub_redis_pool
+QXZ_OFFLINE_CACHE = set()
+dashuju_pub_key = CONFIG.get("dashuju_pub_key")
+
+
+logger = logging.getLogger("data_ingestion")
+
+
+def thread_dashuju_publish_mqtt(client):
+    def _func():
+        while True:
+            try:
+                data = pub_redis_pool.bpop(dashuju_pub_key)
+                topic, payload = data['topic'], data['payload']
+                client.publish(topic, payload)
+                PublishRecord.objects.create(
+                    topic=topic,
+                    payload=payload
+                )
+            except Exception as e:
+                print(e)
+
+    t = threading.Thread(target=_func)
+    t.start()
+
+
+def connect_mqtt(pub):
+    def on_message(client, userdata, msg):
+        """接收到消息的回调方法"""
+        try:
+            payload = json.loads(msg.payload.decode("utf8", "replace"))
+            logger.info(f"payload: {payload}")
+        except Exception as e:
+            payload = {}
+        
+
+    def on_connect(client, userdata, flags, rc):
+        '''mqtt 连接成功后的回调'''
+        # thread_dashuju_publish_mqtt(client)
+        QXZ_OFFLINE_CACHE.clear()
+        client.subscribe(pub)
+
+    client = mqtt.Client()
+    client.username_pw_set(User, Passwd)
+    client.on_connect = on_connect
+    client.on_message = on_message
+    client.connect(HOST, PORT, 30)
+    client.loop_forever()
+
+
+if __name__ == "__main__":
+    publics_list = [
+        DeviceConfig.CBD_PUBLICS,
+        DeviceConfig.CBD_OFFLINE_PUBLICS
+    ]
+    config_dict = settings.CONFIG
+    HOST = config_dict['mqtt']['mqttIp']
+    PORT = config_dict['mqtt']['port']
+    User = config_dict['mqtt']["user"]
+    Passwd = config_dict['mqtt']["password"]
+    p_list = [(p, 0) for p in publics_list]
+    logger.info(f"监听topic: {str(p_list)}")
+    connect_mqtt(p_list)

+ 44 - 0
scripts/test/add_pests.py

@@ -0,0 +1,44 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.pests_bank import MongoPestBank
+from smartfarming.models.worm_forecast import MongoBZYphoto, MongoCBDphoto
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+def dsj_qxz_conf_info():
+    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
+    # 指定集合
+    collection = db.sa_pest_bank
+    pests = collection.find({})
+    for i in pests:
+        bank = MongoPestBank.objects.create(
+            course=i["course"],
+            name=i["name"],
+            img_urls=i["img_urls"],
+            prevention=i["prevention"],
+            search=i["search"],
+            code=i["code"]
+        )
+    print(f"数量:  {pests.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 109 - 0
scripts/test/cbd_data.py

@@ -0,0 +1,109 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice, MongoCBDData
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+scd_device = {
+"866547058627400",
+"866547058637276",
+"866547058633663",
+"866547058613921"
+}
+
+
+def dsj_qxz_conf_info():
+    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))
+    # myclient = pymongo.MongoClient("mongodb://127.0.0.1:12514/")
+    # 指定数据库
+    db = myclient.smartfarming
+    # 指定集合
+    collection = db.sa_device
+    collection1 = db.sa_device_cbd_data
+
+    for i in scd_device:
+        device_info = collection.find_one({'device_id':i})
+        device_id = device_info['id']
+        id = device_info["id"]
+        device, is_created = MongoDevice.objects.get_or_create(
+            device_id = device_info["device_id"],
+            defaults={
+                "dver_num": device_info["dver_num"],
+                "device_model": device_info["device_model"],
+                "device_type_id": device_info["device_type_id"],
+                "device_name": device_info["device_name"],
+                "owner_uid": device_info["owner_uid"],
+                "user_dealer": device_info["user_dealer"],
+                "province": device_info["province"],
+                "city": device_info["city"],
+                "district": device_info["district"],
+                "device_code": device_info["device_code"],
+                "device_status": device_info["device_status"],
+                "off_time": device_info["off_time"],
+                "ftp_push_addr": device_info["ftp_push_addr"],
+                "serverconf": device_info["serverconf"],
+                "lng": device_info["lng"],
+                "lat": device_info["lat"],
+                "gps": device_info["gps"],
+                "addtime": device_info["addtime"],
+                "uptime": device_info["uptime"],
+                "glass_slide_time": device_info["glass_slide_time"],
+                "cultivate_time": device_info["cultivate_time"],
+                "add_position": device_info["add_position"],
+                "simid": device_info["simid"],
+                "disable": device_info["disable"],
+                "decoy": device_info["decoy"],
+                "sim_dealer": device_info["sim_dealer"],
+                "xy_uptime": device_info["xy_uptime"],
+                "networking": device_info["networking"],
+                "equipment": device_info["equipment"],
+                "sale_uid": device_info["sale_uid"],
+                "salesman_task_number": device_info["salesman_task_number"],
+                "whether_equipment_status": device_info["whether_equipment_status"],
+                "device_expire_time": device_info["device_expire_time"],
+                "device_activation": device_info["device_activation"],
+                "device_expire": device_info["device_expire"],
+                "device_expire_days": device_info["device_expire_days"],
+                "water_pump_switch": device_info["water_pump_switch"],
+                "device_notes": device_info["device_notes"],
+                "water_pump_times": device_info["water_pump_times"],
+                "water_pump_switch_times": device_info["water_pump_switch_times"],
+                "xy_expire_time": device_info["xy_expire_time"],
+                "device_tag": device_info["device_tag"]
+            }
+        )
+        print(device.id, is_created)
+        data = {'device_id': device_id,'addtime':{'$gt':1681808604,'$lt':1682413404}}
+        cursor = collection1.find(data,{'_id':0,'id':0,'device_id':0})
+
+        for i in cursor:
+            scd_data = MongoCBDData.objects.create(
+                device_id=device.id,
+                device_data=i["device_data"],
+                addtime=i['addtime']
+            )
+            print(scd_data)
+        print(f"设备: {i} {device_id} 数据量  {cursor.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 83 - 0
scripts/test/cbd_device_config.py

@@ -0,0 +1,83 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice, MongoDeviceConfig
+from smartfarming.models.worm_forecast import MongoBZYphoto, MongoCBDphoto
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+scd_device = {
+"866547058627400",
+"866547058637276",
+"866547058633663",
+"866547058613921",
+"865328061465380",
+"865328061478136",
+"865328061471529",
+"865328061466933",
+"865328061428701",
+"865328061466404",
+"865328061449913",
+"865328061455027",
+"865328061271879",
+"865328061253190",
+"865328061460159",
+"865328061438890",
+"865328061429451",
+"869298052295540",
+"865328061465679",
+"865328061450044",
+"866250061217240",
+"863569067039065",
+}
+
+
+def dsj_qxz_conf_info():
+    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))
+    # myclient = pymongo.MongoClient("mongodb://127.0.0.1:12514/")
+    # 指定数据库
+    db = myclient.smartfarming
+    # 指定集合
+    collection = db.sa_device
+    collection1 = db.sa_device_config
+
+    for i in scd_device:
+        device_info = collection.find_one({'device_id':i})
+        device_id = device_info['id']
+        data = {'d_id': device_id}
+        cursor = collection1.find(data,{'_id':0,'id':0})
+        device_id = MongoDevice.objects.get(device_id=i).id 
+        for i in cursor:
+            MongoDeviceConfig.objects.get_or_create(
+                d_id=device_id,
+                defaults={
+                    "d_id": device_id,
+                    "device_config": i['device_config'],
+                    "cmd": i['cmd'],
+                    "addtime": int(time.time()),
+                    "uptime": int(time.time())
+                }
+            )
+            print(f"设备: {i} {device_id} 数据量  {cursor.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 75 - 0
scripts/test/cbd_photo.py

@@ -0,0 +1,75 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice, MongoCBDData
+from smartfarming.models.worm_forecast import MongoBZYphoto, MongoCBDphoto
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+scd_device = {
+"866547058627400",
+"866547058637276",
+"866547058633663",
+"866547058613921"
+}
+
+
+
+def dsj_qxz_conf_info():
+    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))
+    # myclient = pymongo.MongoClient("mongodb://127.0.0.1:12514/")
+    # 指定数据库
+    db = myclient.smartfarming
+    # 指定集合
+    collection = db.sa_device
+    collection1 = db.sa_device_cbdphoto
+
+    for i in scd_device:
+        device_info = collection.find_one({'device_id':i})
+        device_id = device_info['id']
+        id = device_info["id"]
+        print(device_id, "================")
+        data = {'device_id': str(device_id),'uptime':{'$gte':1689006195}}
+        cursor = collection1.find(data,{'_id':0,'id':0})
+        device_id = MongoDevice.objects.get(device_id=i).id 
+        for i in cursor:
+            if i["addr"] == i["indentify_photo"]:
+                scd_data = MongoCBDphoto.objects.create(
+                    device_id = device_id,
+                    addtime = i["addtime"],
+                    uptime = i["uptime"],
+                    addr = i["addr"],
+                    at = i["at"],
+                    ah = i["ah"],
+                    describe = i["describe"],
+                    indentify_photo = i["indentify_photo"],
+                    indentify_result = i["indentify_result"],
+                    photo_status = i["photo_status"],
+                    is_mark = i["is_mark"],
+                    mark = i["mark"],
+                    label = i["label"]
+                )
+                print(scd_data)
+        print(f"设备: {i} {device_id} 数据量  {cursor.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 58 - 0
scripts/test/cbd_save_photo.py

@@ -0,0 +1,58 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice, MongoCBDData
+from smartfarming.models.worm_forecast import MongoCBDphoto
+import json
+import requests
+import pymongo
+from urllib import parse
+from kedong.settings import MEDIA_ROOT
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+scd_device = {
+"866547058627400",
+"866547058637276",
+"866547058633663",
+"866547058613921"
+}
+
+
+
+def dsj_qxz_conf_info():
+    cbd_photo = MongoCBDphoto.objects.all()
+    for i in cbd_photo:
+        device = MongoDevice.objects.get(id=i.device_id)
+        device_id = device.device_id
+        addr = "https://bigdata-image.oss-cn-hangzhou.aliyuncs.com/Basics/cbd/" + i.addr
+        if i.addr == i.indentify_photo:
+            cbd_path = os.path.join(MEDIA_ROOT, f"cbd/{device_id}")
+            os.makedirs(cbd_path) if not os.path.exists(cbd_path) else None 
+            file_name = (i.addr).split("/")[-1]
+            local_addr = os.path.join(cbd_path, file_name)
+            response = requests.get(addr)
+            try:
+                if int(response.status_code) == 200:
+                    with open(local_addr, "wb") as f:
+                        f.write(response.content)
+            except Exception as e:
+                print(e)
+            tb = f"/media/cbd/{device_id}/{file_name}"
+            i.addr = tb 
+            i.indentify_photo = tb
+            i.save()
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 46 - 0
scripts/test/dbd_warning.py

@@ -0,0 +1,46 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.pest_count import MongoCBDPestWarning
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+
+def dsj_qxz_conf_info():
+    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
+    # 指定集合
+    collection = db.sa_device_cbd_pest_warning
+    pests = collection.find({})
+    for i in pests:
+        bank = MongoCBDPestWarning.objects.create(
+            device_id = i["device_id"],
+            user_id = i["user_id"],
+            warning_name = i["warning_name"],
+            warning_content = i["warning_content"],
+            warning_types = i["warning_types"],
+            upltime = i["upltime"],
+            send_user = i["send_user"],
+            status = i["status"]
+        )
+    print(f"数量:  {pests.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 113 - 0
scripts/test/jk_data.py

@@ -0,0 +1,113 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+scd_device = {
+"7M0AF95PAJ2AAAE-0",
+"8L0161FPAJ2A977-0",
+"8L0161FPAJ03AF9-0",
+"7M03C85PAJ149B8-0",
+"8H09715PHA88629-0",
+"8H09715PHAF7579-0",
+"8H09715PHA5D4B6-0",
+"8H09715PHAC462F-0",
+"8H09715PHA447AB-0",
+"8H09715PHA77BE9-0",
+"8H09715PHACE549-0",
+"8H09715PHA93DEB-0",
+"8H09715PHA4FBD6-0",
+"8H09715PHA50D17-0",
+"8H09715PHA4ABCE-0",
+"8H09715PHA657EC-0",
+"8H09715PHAF45B1-0",
+"8H09715PHA24E37-0",
+"8H09715PHABDF4F-0",
+"8H09715PHA5FFD5-0"
+}
+
+
+def dsj_qxz_conf_info():
+    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))
+    # myclient = pymongo.MongoClient("mongodb://127.0.0.1:12514/")
+    # 指定数据库
+    db = myclient.smartfarming
+    # 指定集合
+    collection = db.sa_device
+
+    for i in scd_device:
+        device_info = collection.find_one({'device_id':i})
+        device_id = device_info['id']
+        id = device_info["id"]
+        device, is_created = MongoDevice.objects.get_or_create(
+            device_id = device_info["device_id"],
+            defaults={
+                "dver_num": device_info["dver_num"],
+                "device_model": device_info["device_model"],
+                "device_type_id": device_info["device_type_id"],
+                "device_name": device_info["device_name"],
+                "owner_uid": device_info["owner_uid"],
+                "user_dealer": device_info["user_dealer"],
+                "province": device_info["province"],
+                "city": device_info["city"],
+                "district": device_info["district"],
+                "device_code": device_info["device_code"],
+                "device_status": device_info["device_status"],
+                "off_time": device_info["off_time"],
+                "ftp_push_addr": device_info["ftp_push_addr"],
+                "serverconf": device_info["serverconf"],
+                "lng": device_info["lng"],
+                "lat": device_info["lat"],
+                "gps": device_info["gps"],
+                "addtime": device_info["addtime"],
+                "uptime": device_info["uptime"],
+                "glass_slide_time": device_info["glass_slide_time"],
+                "cultivate_time": device_info["cultivate_time"],
+                "add_position": device_info["add_position"],
+                "simid": device_info["simid"],
+                "disable": device_info["disable"],
+                "decoy": device_info["decoy"],
+                "sim_dealer": device_info["sim_dealer"],
+                "xy_uptime": device_info["xy_uptime"],
+                "networking": device_info["networking"],
+                "equipment": device_info["equipment"],
+                "sale_uid": device_info["sale_uid"],
+                "salesman_task_number": device_info["salesman_task_number"],
+                "whether_equipment_status": device_info["whether_equipment_status"],
+                "device_expire_time": device_info["device_expire_time"],
+                "device_activation": device_info["device_activation"],
+                "device_expire": device_info["device_expire"],
+                "device_expire_days": device_info["device_expire_days"],
+                "water_pump_switch": device_info["water_pump_switch"],
+                "device_notes": device_info["device_notes"],
+                "water_pump_times": device_info["water_pump_times"],
+                "water_pump_switch_times": device_info["water_pump_switch_times"],
+                "xy_expire_time": device_info["xy_expire_time"],
+                "device_tag": device_info["device_tag"]
+            }
+        )
+        print(device.id, is_created)
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 91 - 0
scripts/test/qx_conf.py

@@ -0,0 +1,91 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice
+from smartfarming.models.weather import QXZdata_New, MongoQXZ_Conf
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+qx_device = {
+"861551055315402",
+"861551056086671",
+"861551056088693",
+"861551056088479",
+"861551056088719",
+"861551055313365",
+"861551056086614",
+"861551056093800"
+}
+
+
+def dsj_qxz_conf_info():
+    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))
+    # myclient = pymongo.MongoClient("mongodb://127.0.0.1:12514/")
+    # 指定数据库
+    db = myclient.smartfarming
+    # 指定集合
+    collection = db.sa_device
+    collection1 = db.sa_qxz_conf
+
+    for k in qx_device:
+        data = {'device_id': k}
+        cursor = collection1.find(data,{'_id':0,'id':0})
+
+        for i in cursor:
+            qx_data = MongoQXZ_Conf.objects.create(
+                device_id = i['device_id'],
+                uptime = i['uptime'],
+                e1 = i['e1'],
+                e2 = i['e2'],
+                e3 = i['e3'],
+                e4 = i['e4'],
+                e5 = i['e5'],
+                e6 = i['e6'],
+                e7 = i['e7'],
+                e8 = i['e8'],
+                e9 = i['e9'],
+                e10 = i['e10'],
+                e11 = i['e11'],
+                e12 = i['e12'],
+                e13 = i['e13'],
+                e14 = i['e14'],
+                e15 = i['e15'],
+                e16 = i['e16'],
+                e17 = i['e17'],
+                e18 = i['e18'],
+                e19 = i['e19'],
+                e20 = i['e20'],
+                e21 = i['e21'],
+                e22 = i['e22'],
+                e23 = i['e23'],
+                e24 = i['e24'],
+                e25 = i['e25'],
+                e26 = i['e26'],
+                e27 = i['e27'],
+                e28 = i['e28'],
+                e29 = i['e29'],
+                e30 = i['e30']
+            )
+        print(f"设备: {k} 数据量  {cursor.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 142 - 0
scripts/test/qx_data.py

@@ -0,0 +1,142 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice
+from smartfarming.models.weather import QXZdata_New
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+qx_device = {
+"861551055315402",
+"861551056086671",
+"861551056088693",
+"861551056088479",
+"861551056088719",
+"861551055313365",
+"861551056086614",
+"861551056093800"
+}
+
+
+def dsj_qxz_conf_info():
+    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))
+    # myclient = pymongo.MongoClient("mongodb://127.0.0.1:12514/")
+    # 指定数据库
+    db = myclient.smartfarming
+    # 指定集合
+    collection = db.sa_device
+    collection1 = db.sa_qxz_data
+
+    for i in qx_device:
+        device_info = collection.find_one({'device_id':i})
+        device_id = device_info['id']
+        id = device_info["id"]
+        device, is_created = MongoDevice.objects.get_or_create(
+            device_id = device_info["device_id"],
+            defaults={
+                "dver_num": device_info["dver_num"],
+                "device_model": device_info["device_model"],
+                "device_type_id": device_info["device_type_id"],
+                "device_name": device_info["device_name"],
+                "owner_uid": device_info["owner_uid"],
+                "user_dealer": device_info["user_dealer"],
+                "province": device_info["province"],
+                "city": device_info["city"],
+                "district": device_info["district"],
+                "device_code": device_info["device_code"],
+                "device_status": device_info["device_status"],
+                "off_time": device_info["off_time"],
+                "ftp_push_addr": device_info["ftp_push_addr"],
+                "serverconf": device_info["serverconf"],
+                "lng": device_info["lng"],
+                "lat": device_info["lat"],
+                "gps": device_info["gps"],
+                "addtime": device_info["addtime"],
+                "uptime": device_info["uptime"],
+                "glass_slide_time": device_info["glass_slide_time"],
+                "cultivate_time": device_info["cultivate_time"],
+                "add_position": device_info["add_position"],
+                "simid": device_info["simid"],
+                "disable": device_info["disable"],
+                "decoy": device_info["decoy"],
+                "sim_dealer": device_info["sim_dealer"],
+                "xy_uptime": device_info["xy_uptime"],
+                "networking": device_info["networking"],
+                "equipment": device_info["equipment"],
+                "sale_uid": device_info["sale_uid"],
+                "salesman_task_number": device_info["salesman_task_number"],
+                "whether_equipment_status": device_info["whether_equipment_status"],
+                "device_expire_time": device_info["device_expire_time"],
+                "device_activation": device_info["device_activation"],
+                "device_expire": device_info["device_expire"],
+                "device_expire_days": device_info["device_expire_days"],
+                "water_pump_switch": device_info["water_pump_switch"],
+                "device_notes": device_info["device_notes"],
+                "water_pump_times": device_info["water_pump_times"],
+                "water_pump_switch_times": device_info["water_pump_switch_times"],
+                "xy_expire_time": device_info["xy_expire_time"],
+                "device_tag": device_info["device_tag"]
+            }
+        )
+        print(device.id, is_created)
+        data = {'device_id': i,'uptime':{'$gt':1688919860}}
+        cursor = collection1.find(data,{'_id':0,'id':0})
+
+        for i in cursor:
+            qx_data = QXZdata_New.objects.create(
+                device_id = i['device_id'],
+                uptime = i['uptime'],
+                e1 = i['e1'],
+                e2 = i['e2'],
+                e3 = i['e3'],
+                e4 = i['e4'],
+                e5 = i['e5'],
+                e6 = i['e6'],
+                e7 = i['e7'],
+                e8 = i['e8'],
+                e9 = i['e9'],
+                e10 = i['e10'],
+                e11 = i['e11'],
+                e12 = i['e12'],
+                e13 = i['e13'],
+                e14 = i['e14'],
+                e15 = i['e15'],
+                e16 = i['e16'],
+                e17 = i['e17'],
+                e18 = i['e18'],
+                e19 = i['e19'],
+                e20 = i['e20'],
+                e21 = i['e21'],
+                e22 = i['e22'],
+                e23 = i['e23'],
+                e24 = i['e24'],
+                e25 = i['e25'],
+                e26 = i['e26'],
+                e27 = i['e27'],
+                e28 = i['e28'],
+                e29 = i['e29'],
+                e30 = i['e30']
+            )
+        print(f"设备: {i} 数据量  {cursor.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 122 - 0
scripts/test/scd_data.py

@@ -0,0 +1,122 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice, MongoSCDData
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+scd_device = {
+    "865328061465380",
+    "865328061478136",
+    "865328061471529",
+    "865328061466933",
+    "865328061428701",
+    "865328061466404",
+    "865328061449913",
+    "865328061455027",
+    "865328061271879",
+    "865328061253190",
+    "865328061460159",
+    "865328061438890",
+    "865328061429451",
+    "869298052295540",
+    "865328061465679",
+    "865328061450044"
+}
+
+
+def dsj_qxz_conf_info():
+    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))
+    # myclient = pymongo.MongoClient("mongodb://127.0.0.1:12514/")
+    # 指定数据库
+    db = myclient.smartfarming
+    # 指定集合
+    collection = db.sa_device
+    collection1 = db.sa_device_scd_data
+
+    for i in scd_device:
+        device_info = collection.find_one({'device_id':i})
+        device_id = device_info['id']
+        id = device_info["id"]
+        device, is_created = MongoDevice.objects.get_or_create(
+            device_id = device_info["device_id"],
+            defaults={
+                "dver_num": device_info["dver_num"],
+                "device_model": device_info["device_model"],
+                "device_type_id": device_info["device_type_id"],
+                "device_name": device_info["device_name"],
+                "owner_uid": device_info["owner_uid"],
+                "user_dealer": device_info["user_dealer"],
+                "province": device_info["province"],
+                "city": device_info["city"],
+                "district": device_info["district"],
+                "device_code": device_info["device_code"],
+                "device_status": device_info["device_status"],
+                "off_time": device_info["off_time"],
+                "ftp_push_addr": device_info["ftp_push_addr"],
+                "serverconf": device_info["serverconf"],
+                "lng": device_info["lng"],
+                "lat": device_info["lat"],
+                "gps": device_info["gps"],
+                "addtime": device_info["addtime"],
+                "uptime": device_info["uptime"],
+                "glass_slide_time": device_info["glass_slide_time"],
+                "cultivate_time": device_info["cultivate_time"],
+                "add_position": device_info["add_position"],
+                "simid": device_info["simid"],
+                "disable": device_info["disable"],
+                "decoy": device_info["decoy"],
+                "sim_dealer": device_info["sim_dealer"],
+                "xy_uptime": device_info["xy_uptime"],
+                "networking": device_info["networking"],
+                "equipment": device_info["equipment"],
+                "sale_uid": device_info["sale_uid"],
+                "salesman_task_number": device_info["salesman_task_number"],
+                "whether_equipment_status": device_info["whether_equipment_status"],
+                "device_expire_time": device_info["device_expire_time"],
+                "device_activation": device_info["device_activation"],
+                "device_expire": device_info["device_expire"],
+                "device_expire_days": device_info["device_expire_days"],
+                "water_pump_switch": device_info["water_pump_switch"],
+                "device_notes": device_info["device_notes"],
+                "water_pump_times": device_info["water_pump_times"],
+                "water_pump_switch_times": device_info["water_pump_switch_times"],
+                "xy_expire_time": device_info["xy_expire_time"],
+                "device_tag": device_info["device_tag"]
+            }
+        )
+        print(device.id, is_created)
+        data = {'device_id': device_id,'addtime':{'$gt':1681808604,'$lt':1682413404}}
+        cursor = collection1.find(data,{'_id':0,'id':0,'device_id':0})
+
+        for i in cursor:
+            scd_data = MongoSCDData.objects.create(
+                device_id=device.id,
+                device_data=i["device_data"],
+                addtime=i['addtime'],
+                device_status=i['device_status']
+            )
+            print(scd_data)
+        # print(f"设备: {i} {device_id} 数据量  {cursor.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 107 - 0
scripts/test/xy_data.py

@@ -0,0 +1,107 @@
+import os
+import sys
+import time
+import django
+local_path = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+print(local_path)
+if local_path not in sys.path:
+    sys.path.append(local_path)
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "kedong.settings")
+django.setup()
+from django.conf import settings
+from smartfarming.models.device import MongoDevice, MongoXYCBData
+import json
+import requests
+import pymongo
+from urllib import parse
+
+
+my_client = pymongo.MongoClient(host="8.136.98.49", port=27017, username="root", password="yfkj@6020")
+my_col = my_client['smartfarming']['sa_device']
+
+scd_device = {
+"866250061217240",
+"863569067039065"
+}
+
+
+def dsj_qxz_conf_info():
+    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))
+    # myclient = pymongo.MongoClient("mongodb://127.0.0.1:12514/")
+    # 指定数据库
+    db = myclient.smartfarming
+    # 指定集合
+    collection = db.sa_device
+    collection1 = db.sa_device_xycb_data
+
+    for i in scd_device:
+        device_info = collection.find_one({'device_id':i})
+        device_id = device_info['id']
+        id = device_info["id"]
+        device, is_created = MongoDevice.objects.get_or_create(
+            device_id = device_info["device_id"],
+            defaults={
+                "dver_num": device_info["dver_num"],
+                "device_model": device_info["device_model"],
+                "device_type_id": device_info["device_type_id"],
+                "device_name": device_info["device_name"],
+                "owner_uid": device_info["owner_uid"],
+                "user_dealer": device_info["user_dealer"],
+                "province": device_info["province"],
+                "city": device_info["city"],
+                "district": device_info["district"],
+                "device_code": device_info["device_code"],
+                "device_status": device_info["device_status"],
+                "off_time": device_info["off_time"],
+                "ftp_push_addr": device_info["ftp_push_addr"],
+                "serverconf": device_info["serverconf"],
+                "lng": device_info["lng"],
+                "lat": device_info["lat"],
+                "gps": device_info["gps"],
+                "addtime": device_info["addtime"],
+                "uptime": device_info["uptime"],
+                "glass_slide_time": device_info["glass_slide_time"],
+                "cultivate_time": device_info["cultivate_time"],
+                "add_position": device_info["add_position"],
+                "simid": device_info["simid"],
+                "disable": device_info["disable"],
+                "decoy": device_info["decoy"],
+                "sim_dealer": device_info["sim_dealer"],
+                "xy_uptime": device_info["xy_uptime"],
+                "networking": device_info["networking"],
+                "equipment": device_info["equipment"],
+                "sale_uid": device_info["sale_uid"],
+                "salesman_task_number": device_info["salesman_task_number"],
+                "whether_equipment_status": device_info["whether_equipment_status"],
+                "device_expire_time": device_info["device_expire_time"],
+                "device_activation": device_info["device_activation"],
+                "device_expire": device_info["device_expire"],
+                "device_expire_days": device_info["device_expire_days"],
+                "water_pump_switch": device_info["water_pump_switch"],
+                "device_notes": device_info["device_notes"],
+                "water_pump_times": device_info["water_pump_times"],
+                "water_pump_switch_times": device_info["water_pump_switch_times"],
+                "xy_expire_time": device_info["xy_expire_time"],
+                "device_tag": device_info["device_tag"]
+            }
+        )
+        print(device.id, is_created)
+        data = {'device_id': device_id,'addtime':{'$gt':1681808604,'$lt':1682413404}}
+        cursor = collection1.find(data,{'_id':0,'id':0,'device_id':0})
+
+        for i in cursor:
+            scd_data = MongoXYCBData.objects.create(
+                device_id=device.id,
+                device_data=i["device_data"],
+                addtime=i['addtime']
+            )
+            print(scd_data)
+        print(f"设备: {i} {device_id} 数据量  {cursor.count()}")
+    return True
+
+
+if __name__ == "__main__":
+    dsj_qxz_conf_info()

+ 59 - 0
scripts/tools/utils.py

@@ -0,0 +1,59 @@
+import os 
+import redis
+import json 
+from kedong.utils import parse_config_new
+
+
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+CONFIG = parse_config_new(BASE_DIR)
+
+class DeviceConfig:
+    CBD_PUBLICS = "/yfkj/cbd/pub/#"
+    CBD_OFFLINE_PUBLICS = "/yfkj/cbd/offline/#"
+    CBD_TYPE = 3
+
+    XCT_PUBLICS = "/yfkj/xct/pub/#"
+    XCT_TYPE = 12
+
+    COLOR_PUBLICS = "yfkj/color/c2s/#"
+    COLOR_OFFLINE_PUBLICS = "yfkj/color/offline/#"
+    COLOR_TYPE = 14
+
+    SCD_PUBLICS = "/yfkj/scd/pub/#"
+    SCD_OFFLINE_PUBLICS = "/yfkj/scd/offline/#"
+    SCD_TYPE = 2
+
+    XYV3_PUBLICS = "/yfkj/xyv3/c2s/#"
+    XYV3_OFFLINE_PUBLICS = "/yfkj/xyv3/offline/#"
+    XYV3_TYPE = 8
+
+    QXZ_PUBLICS = "/yfkj/qxz/pub/#"
+    QXZ_OFFLINE_PUBLICS = "/yfkj/qxz/offline/#"
+    QXZ_TYPE = 5
+
+    BZY_PUBLICS = "/yfkj/bzy/c2s/#"
+    BZY_OFFLINE_PUBLICS = "/yfkj/bzy/offline/#"
+    BZY_TYPE = 7
+
+    XPH_QXZ_PUBLICS = "/xph/qxz/pub/#"
+    XPH_QXZ_OFFLINE_PUBLICS = "/xph/qxz/offline/#"
+    XPH_TYPE = 5
+
+    XYCB_PUBLICS = "/yfkj/xycb/c2s/#"
+    XYCB_OFFLINE_PUBLICS = "/yfkj/xycb/offline/#"
+    XYCB_TYPE = 4
+
+    WS_PUBLICS = "/yfkj/ws/pub/#"
+    WS_OFFLINE_PUBLICS = "/yfkj/ws/offline/#"
+    WS_TYPE = 16
+
+    TRANSPOND_TEST_PUBLICS = "/TranspondData/test"
+
+
+def dashuju_pub_mqtt(topic, payload):
+    msg_info = json.dumps(payload, ensure_ascii=False)
+    temp_data = {
+        'topic': topic,
+        'payload': msg_info
+    }
+    # mqtt_redis_tools.push("dashuju_pub_mqtt", temp_data)

+ 0 - 0
smartfarming/__init__.py


BIN
smartfarming/__pycache__/__init__.cpython-36.pyc


BIN
smartfarming/__pycache__/admin.cpython-36.pyc


BIN
smartfarming/__pycache__/qxz.cpython-36.pyc


BIN
smartfarming/__pycache__/urls.cpython-36.pyc


BIN
smartfarming/__pycache__/utils.cpython-36.pyc


+ 3 - 0
smartfarming/admin.py

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

+ 1 - 0
smartfarming/api/__init__.py

@@ -0,0 +1 @@
+from smartfarming.api.sites import site

BIN
smartfarming/api/__pycache__/__init__.cpython-36.pyc


BIN
smartfarming/api/__pycache__/sites.cpython-36.pyc


+ 26 - 0
smartfarming/api/sites.py

@@ -0,0 +1,26 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/5/18 9:54 上午
+# @Author  : Creat by Han
+from django.urls import include, path
+from django.conf.urls import url
+from smartfarming.api.views import api_gateway, api_document
+from django.http import HttpResponseRedirect
+
+class Api(object):
+    def __init__(self, name="api", app_name="api"):
+        self.namespace = name
+        self.app_name = app_name
+
+    def get_urls(self):
+        urlpatterns = [
+            url(r"^api_gateway", api_gateway, name='api_gateway'),
+            url(r"^api_document", api_document, name='api_document')
+        ]
+        return urlpatterns
+
+    @property
+    def urls(self):
+        return self.get_urls(), self.app_name, self.namespace
+
+
+site = Api()

+ 62 - 0
smartfarming/api/views/__init__.py

@@ -0,0 +1,62 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/5/18 9:56 上午
+# @Author  : Creat by Han
+from itertools import groupby
+from django.shortcuts import render
+import os
+import sys 
+import json
+from collections import OrderedDict
+from importlib import import_module
+JsonResponse = lambda x: HttpResponse(json.dumps(x), content_type="application/javascript")
+from django.http import HttpResponse
+from django.views.decorators.csrf import csrf_exempt
+current_path = os.path.dirname(__file__)
+_modules = os.listdir(os.path.dirname(__file__))
+child_modules = [i for i in _modules if not i.endswith(".py") and (not i.endswith(".pyc")) and (not i.startswith("__"))]
+
+for m in os.walk(current_path):
+    if m[0] == current_path:
+        continue
+    module_name = m[0].split('/')[-1]
+    if '\\' in m[0]:
+        module_name = m[0].split('\\')[-1]
+    if '__init__.py' not in m[2]:
+        continue
+    for i in [i.replace(".py", "") for i in m[2] if i.endswith(".py") and (not i.startswith("__"))]:
+        import_module('smartfarming.api.views.%s.%s' % (module_name,i))
+
+__all__ = [i.replace(".py", "") for i in _modules if i.endswith(".py") and (not i.startswith("__"))]
+__all__ += ["api_gateway", "api_document"]
+
+
+@csrf_exempt
+def api_gateway(request):
+    method = request.GET.get("method")
+    a = {'method': method}
+    _ = sys.api_config.get(method)
+    if _:
+        function = _
+        if function:
+            return function(request)
+    result = JsonResponse({"errorCode": 404, "data": None, "message": "can not find the method!", "formError": {}})
+    if "HTTP_ORIGIN" in request.META:
+        result["Access-Control-Allow-Origin"] = request.META.get("HTTP_ORIGIN")
+    return JsonResponse(a)
+
+def api_document(request):
+    if hasattr(sys, "api_config"):
+        info = list(sys.api_config.items())
+    else:
+        info = []
+    info.sort(key=lambda x: '.'.join(x[0].split(".")[:-1]))
+    result = OrderedDict()
+    for module_name, _iter in groupby(info, key=lambda x: ".".join(x[0].split(".")[:-1])):
+        result[module_name] = []
+        for j in _iter:
+            result[module_name].append((j[0], j[1].__doc__ or '', j[1].login_required,
+                                        j[1].inteam_required,
+                                        j[1].inproject_required,
+                                        j[1].api_factory))
+    result = result.items()
+    return render(request,"api_document.html",locals())

BIN
smartfarming/api/views/__pycache__/__init__.cpython-36.pyc


+ 0 - 0
smartfarming/api/views/camera/__init__.py


BIN
smartfarming/api/views/camera/__pycache__/__init__.cpython-36.pyc


BIN
smartfarming/api/views/camera/__pycache__/camera_manage.cpython-36.pyc


+ 220 - 0
smartfarming/api/views/camera/camera_manage.py

@@ -0,0 +1,220 @@
+import re
+import requests
+import time
+from django.conf import settings
+from django.db.models import Count
+from django.core.paginator import Paginator
+
+from smartfarming.api.views.forecast.all_dict import insect_dict, attract_discern
+from smartfarming.models.sim_card import MongoMsg_Conf
+from smartfarming.models.device import MongoDevice
+from smartfarming.models.camera import MongoCameraPhoto, MongoCameraData, MongoCameraAccount
+from smartfarming.serializers.device_serializers import DeviceSerializers
+from smartfarming.utils import controlMove
+
+from kedong.decoration import kedong_deco, PortError
+config_dict = settings.CONFIG
+
+
+@kedong_deco(login_required=True)
+def list_camera(request):
+    """
+    获取监控设备列表 :
+    参数:
+    
+    page                    非必传(num)                     页码,默认为1
+    device_id               非必传                          设备ID, 不传为监控列表, 传设备号为搜索
+    page_size               非必传                          一页条数,默认为10
+
+    返回值:
+    {
+    "data": {
+        data : {
+            "device_name":"",                            设备名称
+            "device_id":"",                              设备ID
+            "photo_num":"",                              是否拍过照片 0未拍过  1拍过
+            "status":"",                                 设备状态  0离线  1在线
+            "camera_playback":""                         用来判断是否有录像功能 0不支持 1支持
+            "sim":""                                     监控SIM 卡
+        }            
+        counts : 99                                总数
+            } 
+    "errorCode": 0,
+    "message": "",
+    "formError": {}
+    }
+
+    """
+    _list = []
+    myuser = request.myuser
+    post_info = request.POST
+    device_id = post_info.get('device_id')
+    page = int(post_info.get('page', 1))
+    page_size = int(post_info.get('page_size', 10))
+
+    search_dict = {
+        "device_type_id": 6
+    }
+    if device_id:
+        search_dict["device_id"] = re.compile(fr"^.*{device_id}.*$")
+
+    # total_num, data_list = MongoDevice.get_device_list(myuser, match=search_dict, page_num=page, page_size=page_size)
+
+    queryset = MongoDevice.objects.filter(device_type_id=6)
+    total_num = queryset.count()
+    paginator = Paginator(queryset, page_size)
+    page_obj = paginator.get_page(page)
+    serializers = DeviceSerializers(page_obj, many=True)
+    data_list = serializers.data
+    _list = []
+    device_id_list = []
+    for x in data_list:
+        device_id = x.get("device_id")
+        device_id_list.append(device_id)
+
+        _list.append({
+            "device_name": x.get("device_name"),
+            "device_id": device_id,
+            "photo_num": "",
+            "status": x.get("device_status"),
+            "camera_playback": "",
+            "sim": x.get("simid")
+        })
+
+    photo_queryset = MongoCameraPhoto.objects.filter(device_id__in=device_id_list, photo_status=1).values('device_id').annotate(count=Count('device_id'))
+    phote_dict = {p['device_id']: "1" for p in photo_queryset}
+    playback_dict = {y['device_id']: y["camera_playback"] for y in MongoCameraData.objects.filter(device_id__in=device_id_list).values('device_id','camera_playback')}
+
+    for item in _list:
+        item["photo_num"] = phote_dict.get(device_id, "0")
+        item["camera_playback"] = playback_dict.get(device_id,"0")
+    datas = {"data": _list, "counts": total_num}
+    return datas
+
+
+@kedong_deco(login_required=True)
+def addr_camera_list(request):
+    """
+    获取监控设备播放地址 
+    参数:
+    device_id           必传  (string)                  监控设备的序列号
+
+    返回值:
+    {
+    "data": {
+            "hls": "http://test.ys7.com:66/openlive/b475942b03544a5aa35b651670d8712c.m3u8",                  HLS流畅直播地址
+            "hlsHd": "http://test.ys7.com:66/openlive/b475942b03544a5aa35b651670d8712c.hd.m3u8",             HLS高清直播地址
+            "rtmp": "rtmp://10.82.0.190:1935/openlive/b475942b03544a5aa35b651670d8712c",                     RTMP流畅直播地址
+            "rtmpHd": "rtmp://10.82.0.190:1935/openlive/b475942b03544a5aa35b651670d8712c.hd"                 RTMP高清直播地址
+            }
+    "errorCode": 0,
+    "message": "",
+    "formError": {}
+    }
+
+    """
+
+    try:
+        if 'HTTP_X_FORWARDED_FOR' in request.META:
+            ip = request.META['HTTP_X_FORWARDED_FOR']
+        else:
+            ip = request.META['HTTP_X_REAL_IP']
+    except Exception as KeyError:
+        ip = request.META['REMOTE_ADDR']
+
+
+
+    device_id = request.POST.get('device_id')
+    # try:
+    #     ic = InterfaceCallLog()
+    #     ic.ip = ip
+    #     ic.device_id = device_id
+    #     ic.interface = "addr_camera_list"
+    #     ic.meta = str(request.META)
+    #     ic.save()
+    # except Exception as e:
+    #     pass
+
+    # if device_id in jk_list.keys():
+    #     if redis_pool.get(device_id):
+    #         url_path = redis_pool.get(device_id)
+    #     else:
+    #         cameraIndexCode = jk_list.get(device_id,"")
+    #         url = "http://223.151.55.58:8082/zhcg-serve/hkVideo/api/getPreviewURLsByHls?cameraIndexCode={}&streamType=0".format(cameraIndexCode)
+    #         try:
+    #            url_path = (requests.get(url,timeout=5).json())["data"]["url"]
+    #         except:
+    #             url_path = "" 
+    #         # 设置播放地址到期时间5分钟
+    #         redis_pool.set(device_id,url_path,300)
+    #     # 因为其他设备返回的数值是字符串的,所以进行拼接
+    #     data =  "{'hls':'%s','hlsHd':'%s','rtmp':'%s','rtmpHd':'%s'}"%(url_path,url_path,url_path,url_path)
+    #     return data
+
+    try:
+        addr = MongoCameraData.objects.get(device_id=device_id).device_info
+    except:
+        addr = {}
+    return addr
+
+
+@kedong_deco(login_required=True)
+def ctrl_camera(request):
+    """
+    控制监控设备转动 :
+    参数:
+    device_id          必传  (string)                  监控设备的序列号
+    ctrl               必传  (string)                  操作指令  move 控制球机转动   stop 停止球机转动
+    movenum            ctrl=move时必传(string)         0-上,1-下,2-左,3-右,8-放大,9-缩小
+
+    返回值:
+    {
+    "data": success,     success成功   default失败
+    "errorCode": 0,
+    "message": "",
+    "formError": {}
+    }
+
+    """
+    device_id = request.POST.get('device_id')
+    ctrl = request.POST.get('ctrl')
+    account_id = MongoCameraData.objects.filter(device_id=device_id).first()
+    if not account_id:
+        raise PortError("","未找到此设备")
+    camera_query = MongoCameraAccount.objects.filter(id=int(account_id.account_id)).first()
+    if not camera_query:
+        raise PortError("","未找到此账号")
+    channelNo = "1"
+    if device_id.find("-") != -1:
+        channelNo = device_id.split("-")[1]
+        device_id = device_id.split("-")[0]
+    # 操作命令:0-上,1-下,2-左,3-右,4-左上,5-左下,6-右上,7-右下,8-放大,9-缩小,10-近焦距,11-远焦距
+    if ctrl == "move":
+        dire = request.POST.get('movenum')
+        # 增加大华相机操作功能
+        if camera_query.account_type == 1:
+            if dire not in ("0","1","2","3","8","9"):
+                raise PortError("movenum","暂不支持其它指令")
+            appId = camera_query.app_key
+            appSecret = camera_query.app_secret
+            controlMove(appId,appSecret,device_id,dire,channelNo)
+        else:
+            accessToken = camera_query.token
+            ctrl_url = 'https://open.ys7.com/api/lapp/device/ptz/start'
+            speed = '1'
+            data = {'accessToken':accessToken, 'deviceSerial':device_id, 'channelNo':channelNo, 'speed':speed, 'direction':dire}
+            res1 = requests.post(ctrl_url,data=data)
+    elif ctrl == "stop":
+        time.sleep(0.4)
+        # 增加大华相机操作功能
+        if camera_query.account_type == 1:
+            dire = "10"
+            appId = camera_query.app_key
+            appSecret = camera_query.app_secret
+            controlMove(appId,appSecret,device_id,dire,channelNo)
+        else:
+            accessToken = camera_query.token
+            ctrl_url = 'https://open.ys7.com/api/lapp/device/ptz/stop'
+            data = {'accessToken':accessToken, 'deviceSerial':device_id, 'channelNo':channelNo}
+            res2 = requests.post(ctrl_url,data=data)
+    return True

+ 3 - 0
smartfarming/api/views/device/__init__.py

@@ -0,0 +1,3 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/5/22 9:49 上午
+# @Author  : Creat by Han

BIN
smartfarming/api/views/device/__pycache__/__init__.cpython-36.pyc


BIN
smartfarming/api/views/device/__pycache__/device_manage.cpython-36.pyc


BIN
smartfarming/api/views/device/__pycache__/device_sms_alert.cpython-36.pyc


+ 97 - 0
smartfarming/api/views/device/device_manage.py

@@ -0,0 +1,97 @@
+import datetime
+from smartfarming.models.device import MongoDevice
+from kedong.decoration import kedong_deco, PortError
+from smartfarming.utils import get_address_by_lntlat, get_weather_info
+
+
+
+@kedong_deco(login_required=False)
+def weathers(request):
+    """
+    天气接口
+    参数
+    lat             必传(str)               纬度
+    lng             必传(str)               经度
+
+    返回值:
+     "data": [
+        {
+        "id": 1201,
+        "province": "新疆维吾尔自治区",             省
+        "city": "克孜勒苏柯尔克孜自治州",           市
+        "district": "阿克陶县",                     县
+        "lng": "75.945159",                         经度
+        "lat": "39.147079",                         纬度
+        "at": "31",                                 温度
+        "ah": "14",                                 湿度
+        "upl_time": "2021-10-25 14:39:48",          时间
+        "win": "东风",                              风向
+        "win_speed": "1级",                         风速
+        "win_meter": "5km/h",                       风力
+        "wea": "多云",                              天气
+        "visibility": "30km",                       能见度
+        "pressure": "863",                          压力
+        "air": "40",                                空气
+        "air_pm25": "19",                           空气PM2.5
+        "air_level": "优",                          空气等级
+        "air_tips": "空气很好,可以外出活动,呼吸新鲜空气,拥抱大自然!"   空气说明
+        }
+    ],
+    "params": {
+    "lat": "039.1850853",
+    "lng": "075.8749465"
+    }
+    }
+
+
+    """
+
+    lat = request.POST.get('lat', '')
+    lng = request.POST.get('lng', '')
+    device_id = request.POST.get('device_id')
+
+    if not lat and not lng:
+        raise PortError('', '未传经纬度')
+
+    province, city, district = "", "", ""
+    if device_id:
+        try:
+            instance = MongoDevice.objects.get(device_id=device_id)
+            province, city, district = instance.province, instance.city, instance.district
+            if (not city) and district:
+                city = district
+        except Exception as e:
+            pass
+
+    if not (province and city):
+        province, city, district = get_address_by_lntlat(lng, lat)
+
+    result = []
+    weather_info = get_weather_info(lng, lat)
+    try:
+        upl_time = weather_info.get('upl_time')
+        upl_time = datetime.datetime.fromtimestamp(int(upl_time)).strftime("%Y-%m-%d %H:%M:%S")
+    except Exception as e:
+        upl_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+
+    result.append({
+        "province": province,
+        "city": city,
+        "district": district,
+        "lng": lng,
+        "lat": lat,
+        "at": weather_info.get('at', ''),
+        "ah": weather_info.get('ah', ''),
+        "upl_time": upl_time,
+        "win": weather_info.get('win', ''),
+        "win_speed": weather_info.get('win_speed', ''),
+        "win_meter": weather_info.get('win_meter', ''),
+        "wea": weather_info.get('wea', ''),
+        "visibility": weather_info.get('visibility', ''),
+        "pressure": weather_info.get('pressure', ''),
+        "air": weather_info.get('air', ''),
+        "air_pm25": weather_info.get('air_pm25', ''),
+        "air_level": weather_info.get('air_level', ''),
+        "air_tips": weather_info.get('air_tips', ''),
+    })
+    return result

+ 113 - 0
smartfarming/api/views/device/device_sms_alert.py

@@ -0,0 +1,113 @@
+from smartfarming.models.pest_count import MongoCBDPestWarning
+from smartfarming.models.device import MongoDevice
+from kedong.decoration import kedong_deco, PortError
+
+
+@kedong_deco(login_required=True)
+def user_cbd_pest_warning_record_list(request):
+    """ 
+    测报灯预警记录列表
+    
+    page            非必传(str)              页码数
+    page_size       非必传(str)              条数
+    warning_type    必传(str)                1目标种类预警 2、指定害虫数量预警  3 害虫数量总和预警 4综合预警
+    start_time      非必传(str)              开始时间  时间戳
+    end_time        非必传(str)              结束时间  时间戳
+    """
+    
+    page = request.POST.get("page","1")
+    page_size = request.POST.get("page_size","10")
+    warning_type = request.POST.get("warning_type")
+    start_time = request.POST.get("start_time")
+    end_time = request.POST.get("end_time")
+    
+    if page and page_size:
+        if page.isdigit() and page_size.isdigit():
+            page = int(page)
+            page_size = int(page_size)
+        else:
+            raise PortError("page&page_size","参数有误")
+    else:
+        page = 1
+        page_size = 10
+ 
+    start = max((page - 1), 0) * page_size
+    end = page * page_size
+    cbd_pest_warnig_query = MongoCBDPestWarning.objects.filter().order_by("-id")
+    if warning_type:
+        if warning_type not in("1","2","3","4"):
+            raise PortError(warning_type,"参数超出范围")
+        cbd_pest_warnig_query = cbd_pest_warnig_query.filter(warning_types=warning_type)
+    
+    if start_time and end_time:
+        if not (start_time.isdigit() and end_time.isdigit()):
+            raise PortError("start_time&end_time","参数有误") 
+        cbd_pest_warnig_query = cbd_pest_warnig_query.filter(upltime__range=(int(start_time),int(end_time)))
+    total = cbd_pest_warnig_query.count()
+    
+    data = []
+    for xx in cbd_pest_warnig_query[start:end]:
+        data.append({
+            "id":xx.id,
+            "device_id":xx.device_id,
+            "warning_type":xx.warning_types,
+            "warning_name": xx.warning_name,
+            "warning_content": xx.warning_content,
+            "upltime":xx.upltime,
+            "send_user":xx.send_user,
+            "status":xx.status,
+        })
+    return {"data" : data, "total" : total}
+
+
+
+@kedong_deco(login_required=True)
+def user_cbd_pest_warning_record_read(request):
+    """
+    测报灯预警已读
+    参数
+    id                       必传(str)              预警id
+    req                      非必传(str)            一键已读必传 "all"   单个已读无需传递
+    """
+    req = request.POST.get("req")
+    cbd_pest_warnig_query = MongoCBDPestWarning.objects.filter(user_id=request.myuser.id)
+    if req and req=="all":
+        cbd_pest_warnig_query.update(status=1)
+    else:
+        d_id = request.POST.get("id")
+        if not d_id:
+            raise PortError("id","参数缺失")
+        try:
+            cbd_pest_warnig_query = cbd_pest_warnig_query.get(id=d_id)
+        except:
+            raise PortError("id","未找到此数据")
+        cbd_pest_warnig_query.status = 1
+        cbd_pest_warnig_query.save()
+    return True
+
+
+@kedong_deco(login_required=True)
+def user_device_map_location(request):
+    """ 
+    测报灯、气象站设备地图位置
+    参数
+    device_ids                  必传(str)                 设备号用多个,进行连接
+    
+    """
+    
+    device_ids = request.POST.get("device_ids")
+    if not device_ids:
+        raise PortError("device_ids","参数缺失")
+    device_list = device_ids.split(",")
+    data = []
+    device_query = MongoDevice.objects.filter(device_type_id__in=[3,5]).filter(device_id__in=device_list)
+    for xx in device_query:
+        data.append({
+            "device_id" : xx.device_id,
+            "device_type_id" : xx.device_type_id,
+            "device_name" : xx.device_name,
+            "lat" : xx.lat,
+            "lng" : xx.lng,
+            "uptime" : xx.uptime
+        })
+    return data

+ 3 - 0
smartfarming/api/views/forecast/__init__.py

@@ -0,0 +1,3 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/5/22 9:49 上午
+# @Author  : Creat by Han

BIN
smartfarming/api/views/forecast/__pycache__/__init__.cpython-36.pyc


BIN
smartfarming/api/views/forecast/__pycache__/all_dict.cpython-36.pyc


BIN
smartfarming/api/views/forecast/__pycache__/common.cpython-36.pyc


BIN
smartfarming/api/views/forecast/__pycache__/forecast_system.cpython-36.pyc


BIN
smartfarming/api/views/forecast/__pycache__/send_control.cpython-36.pyc


BIN
smartfarming/api/views/forecast/__pycache__/worm_lamp.cpython-36.pyc


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1157 - 0
smartfarming/api/views/forecast/all_dict.py


+ 61 - 0
smartfarming/api/views/forecast/common.py

@@ -0,0 +1,61 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/10/28 2:13 下午
+# @Author  : Creat by Han
+import requests
+import os
+import oss2
+import json
+from PIL.BufrStubImagePlugin import Image
+from Crypto.Util.py3compat import BytesIO
+from django.conf import settings
+config_dict = settings.CONFIG
+
+
+
+auth = oss2.Auth('LTAI4G7tFh5Nk4KXZoSPk1D8', 'RV4S2SfbLPoFNjlI4uIOoA0J1LQPQc')
+
+def down_image(image_name,url):
+    dir_name = os.path.dirname(image_name)
+    if not os.path.isdir(dir_name):
+        os.makedirs(dir_name)
+
+    content = requests.get(url).content
+    with open("%s"%image_name,"wb") as f:
+        f.write(content)
+    return image_name
+
+def push_oss_image(data,http="https://oss-cn-beijing.aliyuncs.com",bt="bigdata-all"):
+    try:
+        http = config_dict["oss"]["http"]
+        bt = config_dict["oss"]["bucket"]
+        bucket = oss2.Bucket(auth,http,bt,connect_timeout=30)
+        headers = {}
+        headers["Content-Type"] = "image/jpg"
+        headers["Content-Disposition"] = "inline"
+        bucket.put_object_from_file(data[0].strip('/'), data[1],headers=headers)
+        requests.adapters.DEFAULT_RETRIES = 5
+        s = requests.session()
+        s.keep_alive = False
+
+        if os.path.exists(data[1]) == True:
+            # 删除图片文件
+            os.remove(data[1])
+    except Exception as e:
+        print("错误",e)
+        pass
+    return True
+
+
+if __name__ == '__main__':
+    # url = "http://image-yunfei.oss-cn-beijing.aliyuncs.com/202010/867435052201308/2020102840.jpg"
+    base_path = "/data/image_result/"
+    http = "http://bigdata-image.yfpyx.com/"
+    addr = "202010/867435052201308/20201028211.jpg"
+    # addr = "08-202/867435052201043/08-2020.jpg"
+    image_path = base_path + addr.split('/')[-1]
+    url = http+addr
+
+    # data = ['/202010/867435052201308/up_2020102836.jpg', 'result_2020102836.jpg']
+    # http = "http://oss-cn-beijing.aliyuncs.com"
+    # bt = "image-yunfei"
+    # push_oss_image(data=data,http=http,bt=bt)

+ 664 - 0
smartfarming/api/views/forecast/forecast_system.py

@@ -0,0 +1,664 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/8/25 9.45 上午
+# @Author  : Creat by cao
+import operator
+import json
+import time
+import os
+import requests
+import random
+import ast
+from django.conf import settings
+
+from smartfarming.api.views.forecast.all_dict import insect_dict, attract_discern
+from smartfarming.models.sim_card import MongoMsg_Conf
+from smartfarming.models.device import MongoDevice
+from smartfarming.models.worm_forecast import MongoCBDphoto, MongoCBDphoto_B, MongoCBDphoto_C
+from kedong.decoration import kedong_deco, PortError
+config_dict = settings.CONFIG
+
+
+@kedong_deco(login_required=True)
+def time_folder(request):
+    """
+    测报灯/色诱/吸虫塔/性诱3.0隐藏时间文件夹接口
+    device_id               必传(str)               设备id
+    identify_model          必传(str)               识别模型AB
+
+    返回值:
+    "data":[
+        {
+        "2021":{
+        "10":[
+        "14",
+        "13",
+
+        ],
+        "09":[
+        "30",
+        "29",
+        "28",
+        "27",
+        "16",
+        "06"
+        ]
+        }
+        }
+        ],
+    """
+    device_id = request.POST.get('device_id')
+    if not device_id:
+        raise PortError("device_id", "未传设备号")
+    
+    try:
+        device = MongoDevice.objects.get(device_id=device_id)
+    except:
+        raise PortError("", "设备号不对")
+
+    myuser_type = request.user_type
+
+    if device.device_type_id == 3:
+        identify_model = request.POST.get("identify_model","A")
+        if identify_model=="A":
+            models = MongoCBDphoto
+        elif identify_model=="B":
+            models = MongoCBDphoto_B
+        if not myuser_type == 1 and device.device_expire == "1":
+            photo_list = models.objects.filter(device_id=device.id,photo_status=1,addtime__lte=int(device.device_expire_time)).order_by("-id")
+        else:
+            photo_list = models.objects.filter(device_id=device.id,photo_status=1).order_by("-id")
+    else:
+        raise PortError("","暂不支持的设备类型")
+    
+    repeat_data = []
+    for i in photo_list:
+        othertime = time.strftime("%Y-%m-%d", time.localtime(i.addtime))
+        year,month,day = othertime.split("-")
+        time_tup =  year,month,day
+        repeat_data.append(time_tup)
+    data = list(set(repeat_data))
+    data.sort(key=repeat_data.index)
+
+    time_data = []
+    year_list = []
+    month_list = []
+    crowbar = -1      #使用撬棍进行列表下标标识,因为数据时经过去重和排序的,所以可以进行。
+    for time_i in data:
+        year_time = time_i[0]
+        month_time = time_i[1]
+        day_time = time_i[2]
+        if year_time in year_list:
+            if year_time+month_time in month_list:
+                time_data[crowbar][year_time][month_time].append(day_time)
+            else:
+                time_data[crowbar][year_time][month_time] = [day_time]
+                month_list.append(year_time+month_time)
+        else:
+            year_list.append(year_time)
+            month_list.append(year_time+month_time)
+            month_dict = {month_time:[day_time]}
+            time_data.append({year_time:month_dict})
+            crowbar+=1
+    return(time_data)
+
+
+@kedong_deco(login_required=True)
+def device_photo_details(request):
+    """
+    色诱测报灯/测报灯/吸虫塔/性诱3.0/图片详情接口
+    img_id                           必传(str)              图片id
+    cmd                              非必传(str)             cmd有值并且为sy时,是色诱测报图片列表接口,
+                                                            为xct时,是吸虫塔图片列表, 
+                                                            为cbd是,是测报灯图片列表,
+                                                            为xy_three 时, 是性诱3.0图片列表
+    identify_model                   非必传("A","B")         cmd为cbd时,A是A模型,B是B模型
+
+
+
+    返回值:
+    "data": {
+        "device_id": "2631",
+        "addtime": 1632413928,
+        "addr": "http://bigdata-all.oss-accelerate.aliyuncs.com/Basics/cbd/867435059571471/2021/9/24/20210924001848354843.jpg",
+        "ids": 86524,
+        "mark": "",
+        "label": "",
+        "indentify_photo": "http://bigdata-all.oss-accelerate.aliyuncs.com/Result/cbd/867435059571471/2021/9/24/20210924001848354843.jpg",
+        "indentify_result": "158,38#670,26#672,4"
+    },
+    """
+    img_id = request.POST.get("img_id")
+    try:
+        imgs = MongoCBDphoto.objects.get(id=img_id)
+    except:
+        raise PortError("img_id", "未找到该图片id")
+    label = imgs.label
+    indentify_photo = imgs.indentify_photo
+    indentify_result = imgs.indentify_result
+    img_url = imgs.addr
+    mark = imgs.mark
+    if mark:
+        mark = json.loads(mark)
+    else:
+        mark = []
+    data= {
+        "device_id":imgs.device_id,
+        "addtime":imgs.addtime,
+        "addr":img_url,
+        "ids":imgs.id,
+        "mark":mark,
+        "indentify_photo":indentify_photo,
+        "indentify_result":indentify_result,
+        "label":label}
+    return data
+
+
+@kedong_deco(login_required=True)
+def device_photo_list(request):
+    """
+    测报灯图片展示接口
+    device_id                        必传(str)              设备id
+    page                             非必传(str)            页数
+    page_number                      非必传(num)            页面显示数据总数,默认10条
+    time_begin                       非必传(时间戳)          开始时间
+    time_end                         非必传(时间戳)          结束时间
+
+
+    返回值:
+    "data": {
+        "disable":0 禁用识别的状态    1 开启识别的状态,
+        {
+	'2021-04-09': [{
+		'device_id': '836',
+		'addtime': 1617936849,
+		'describe': '',
+		'addr': 'http://182.92.193.64:8003/Basics/cbd/866262046927462/2021/4/9/20210409105402642179.jpg',
+		'mark': None,
+		'id': 5877,
+		'add_time': '2021-04-09'
+	}],
+	'2021-04-08': [{
+		'device_id': '836',
+		'addtime': 1617867971,
+		'describe': '',
+		'addr': 'http://182.92.193.64:8003/Basics/cbd/866262046927462/2021/4/8/20210408154604657028.jpg',
+		'mark': None,
+		'id': 5810,
+		'add_time': '2021-04-08'
+	}
+    }
+    """
+    deviceas = request.POST
+    device_id = deviceas.get("device_id")
+    page = int(deviceas.get("page",1))
+    
+    time_begin = deviceas.get("time_begin")
+    time_end = deviceas.get("time_end")
+    page_number = int(deviceas.get("page_number",12))
+    if not device_id:
+        raise PortError("device_id", "未传设备号")
+    try:
+        device = MongoDevice.objects.get(device_id=device_id)
+    except:
+        raise PortError("", "设备号不对")
+    data = []
+    image_path = config_dict["image_url"]["image"] 
+    photo_list = MongoCBDphoto.objects.filter(device_id=device.id,photo_status=1).order_by("-id")
+    if time_begin and time_begin.isdigit() and time_end.isdigit():
+        photo_list = photo_list.filter(addtime__range=(int(time_begin),int(time_end)))
+
+    num = photo_list.count()
+    for i in photo_list[(page_number*(page-1)):(page*page_number)]:
+        # 判断是否有手动标注结果
+        if i.is_mark == 1:
+            try:
+                mark = ast.literal_eval(i.mark)
+            except:
+                mark = json.loads(i.mark)
+            pest_counts = len(mark)
+        else:
+            indentify_result = "" if i.indentify_result == "0" else i.indentify_result
+            pest_counts = sum([int(i.split(",")[1]) for i in indentify_result.split("#")]) if indentify_result else 0
+
+        # TODO 展示图片暂时处理
+        if str(i.addr).startswith('/'):
+            img_url = image_path + i.addr
+        else:
+            img_url = image_path + "/" + i.addr
+        data.append({
+            "device_id":i.device_id,
+            "addtime":i.addtime,
+            "describe":i.describe,
+            "addr":img_url,
+            "ids":i.id,
+            "mark":i.mark,
+            "pest_counts":pest_counts,
+            "indentify_photo":i.indentify_photo,
+            "indentify_result":i.indentify_result
+            })
+
+    return {"disable":device.disable,"data":data,"num":num}
+
+
+
+
+from .common import *
+from django.db.models import Q
+
+
+@kedong_deco(login_required=True)
+def equip_photo_del(request):
+    """
+    测报灯/孢子仪/性诱/吸虫塔/性诱3.0图片删除接口
+    参数
+        device_id                必传(str)                      设备号
+        addrlist                 非必传(str)                    图片列表
+        
+        addrlist没值删除所有的图片,有值就删除里面的值 
+    """
+    deviceas = request.POST
+    device_id = deviceas.get("device_id")
+    img_list = deviceas.get("addrlist")
+    if not device_id:
+        raise PortError("", "未传设备号")
+    try:
+        device_ids = MongoDevice.objects.get(device_id=device_id)
+    except:
+        raise PortError("", "设备号不存在")
+    img_list = eval(img_list)
+    if device_ids.device_type_id == 3:
+        modules = MongoCBDphoto
+    
+    if img_list:
+        for i in img_list:
+            try:
+                modules.objects.filter(id=i).update(photo_status=4)
+            except:
+                raise PortError("device_id", "删除失败")
+    else:
+        try:
+            modules.objects.filter(device_id=device_ids.id).update(photo_status=4)
+        except:
+            raise PortError("device_id", "删除失败")
+    return True
+
+
+# 测报灯短信配置
+@kedong_deco(login_required=True)
+def cbd_msg_conf(request):
+    """
+    测报灯害虫预警短信配置接口:
+    参数:
+    device_id               必传(str)                设备号
+    conf                    非必传(str)              害虫配置信息
+
+    不传conf: 当前短信预警配置
+    传conf:修改短信预警配置
+
+    """
+    device_id = request.POST.get("device_id")
+    if not device_id:
+        raise PortError("device_id", "参数不对")
+    uptime = int(time.time())
+    conf = request.POST.get("conf")
+    if conf:
+        try:
+            if MongoMsg_Conf.objects.filter(device_id=device_id).exists():
+                msgconf = MongoMsg_Conf.objects.get(device_id=device_id)
+                msgconf.conf = conf
+                msgconf.save()
+            else:
+                MongoMsg_Conf.objects.create(device_id=device_id,conf=conf,uptime=uptime)
+        except:
+            raise PortError(" ", "保存失败")
+        return True
+    else:
+        try:
+            msgconf = MongoMsg_Conf.objects.get(device_id=device_id)
+            data = msgconf.conf
+        except:
+            data = ""
+        return data
+
+
+
+def disable_cbd_discern(request):
+    """
+    禁用测报灯害虫识别功能
+
+    device_id            必传(str)                    设备号
+    ret                  必传(str)                    ret=disable时禁用识别功能, ret=enable,时启用识别统计功能, ret =count 计数功能
+
+    """
+    device_id = request.POST.get("device_id")
+    ret = request.POST.get("ret")
+
+    try:
+        device_list = Device.objects.get(device_id=device_id)
+    except:
+        raise PortError("device_id", "找不到该设备")
+    if ret == "disable":
+        device_list.disable = 0
+        device_list.save()
+    elif ret == "enable":
+        device_list.disable = 1
+        device_list.save()
+    elif ret == "count":
+        device_list.disable = 2
+        device_list.save()
+    else:
+        raise PortError("device_id", "参数超出范围")
+    return True
+
+
+
+def cbd_pest_type_ranking(request):
+    """
+    筛选最近识别害虫列表接口
+    参数:
+    start_time      非必传          开始时间 时间戳
+    end_time        非必传          结束时间 时间戳、
+    page            非必传          页数
+    page_size       非必传          一页默认10条数据
+    ret             必传            为num害虫排名,  为type列表详情数据, 
+    identify_model  必传            识别模型A,识别模型B
+
+    type时返回值:
+     "data": {
+        "num": 2,                                       条数
+        "cbd_photo_data": [
+            {
+                "device_id": "867814040006799",         设备号
+                "pest_num": 18,                         害虫种类数据
+                "pest_name": [
+                    {
+                        "pest_name": "水龟虫",          害虫种类
+                        "num": 518                      害虫总数
+                    },
+                    {
+                        "pest_name": "蝼蛄",
+                        "num": 128
+                    },
+        num 时返回值:
+        "data": [
+            {
+                "水龟虫": 539      害虫名称    害虫数量
+            },
+            {
+                "蝼蛄": 153
+            },
+            {
+                "铜绿丽金龟": 62
+            },
+            {
+                "负子蝽": 42
+            },
+            {
+                "暗黑鳃金龟": 21
+            },
+            {
+                "夜蛾": 15
+            }
+        ],
+    """
+    page = int(request.POST.get("page",1))
+    page_size = int(request.POST.get("page_size",10))
+    start_time = request.POST.get("start_time")
+    end_time = request.POST.get("end_time")
+    ret = request.POST.get("ret")
+    recive_pest_name = request.POST.get("pest_name")
+    identify_model = request.POST.get("identify_model","A")
+    if identify_model=="A":
+        models = CBDphoto
+    elif identify_model=="B":
+        models = CBDphoto_B
+    myuser = request.myuser
+    pest_num_data = []
+    date = []
+    devices = Device.devices(uid=myuser.uid, myuser=myuser)
+    print("user_type",myuser.user_type)
+    if myuser.user_type != 4 or myuser.user_type != 1:
+        devices = devices.filter(disable=1)
+    for i in devices:
+        if not myuser.user_type == 1 and i.device_expire == "1":
+            cbd_data = models.objects.filter(~Q(indentify_photo=None),device_id=i.id,photo_status=1,addtime__lte=int(i.device_expire_time)).values()
+            if end_time and int(end_time) > int(i.device_expire_time):
+                end_time = i.device_expire_time
+                cbd_data = cbd_data.filter(addtime__range=(int(start_time),int(end_time)))
+        else:
+            cbd_data = models.objects.filter(~Q(indentify_photo=None),device_id=i.id,photo_status=1).values()
+            if start_time:
+                cbd_data = cbd_data.filter(addtime__range=(int(start_time),int(end_time)))
+        for x in cbd_data:
+            if x["indentify_result"]:
+                xx_result =  x["indentify_result"].split("#")
+                print(xx_result)
+                for yy in xx_result:
+                    yy_result = yy.split(",")
+                    try:
+                        date.append({
+                                "device_id": i.device_id,
+                                "device_name": i.device_name,
+                                "device_add": i.province+i.city+i.district,
+                                "pest_num" : int(yy_result[1]),
+                                "pest_name" : insect_dict[yy_result[0]]})
+                    except:
+                        continue
+    data = {}
+    pest = {}
+    if ret == "type":
+        for item in date:
+            device_id, pest_name,pest_num,device_name,device_add= item['device_id'], item['pest_name'],item['pest_num'],item['device_name'],item['device_add']
+            key = '{},{},{}'.format(device_id,device_name,device_add)
+            if key in data:
+                data[key] += [pest_name]
+            else:
+                data[key] = [pest_name]
+            keys = '{},{}'.format(device_id,pest_name)
+            if keys in pest:
+                pest[keys] += pest_num
+
+            else:
+                pest[keys] = pest_num
+        sort_data = sorted(data.items(), key=lambda d:len(d[1]), reverse = True )
+        for y in sort_data:
+            device_id,device_name, device_addr = y[0].split(',')
+            pest_data = []
+            for x in y[1]:
+                x = {"pest_name":x,"num":pest[device_id +","+x]}
+                if x not in pest_data:
+                    pest_data.append(x)
+            sorted_x = sorted(pest_data, key=operator.itemgetter('num'),reverse = True)
+            if recive_pest_name:
+                for pt_name in sorted_x:
+                    if recive_pest_name in pt_name["pest_name"]:
+                        pest_num_data.append({
+                            "device_id" : device_id,
+                            "pest_num": len(pest_data),
+                            "pest_name": sorted_x,
+                            "device_name" : device_name,
+                            "device_addr": device_addr
+                        })
+                    else:
+                        pass
+            else:
+                pest_num_data.append({
+                    "device_id" : device_id,
+                    "pest_num": len(pest_data),
+                    "pest_name": sorted_x,
+                    "device_name" : device_name,
+                    "device_addr": device_addr
+                })
+        num = len(pest_num_data)
+        cbd_photo_data = pest_num_data[(page_size*(page-1)):(page*page_size)]
+        cbd_pset = {"num":num,"cbd_photo_data":cbd_photo_data}
+        return cbd_pset
+    elif ret == "num":
+        for item in date:
+            pest_num,pest_name = item['pest_num'],item["pest_name"]
+            key = '{}'.format(pest_name)
+            if key in data:
+                data[key] += pest_num
+            else:
+                data[key] = pest_num
+        sort_data = sorted(data.items(), key=lambda d:d[1], reverse = True )[:6]
+        for y in sort_data:
+            pest_num_data.append({
+                y[0] : y[1]
+            })
+        return pest_num_data
+    else:
+        raise PortError("ret", "参数超出范围")
+        
+
+
+
+
+
+def cbd_pest_line_chart(request):
+    """
+    筛选总设备害虫折线图
+    参数:
+    start_time              非必传(string 时间戳)           开始时间    (用于时间搜索)
+    end_time                非必传(string 时间戳)           结束时间    (用于时间搜索)
+    pest_name               非必传(str)                     害虫名称
+    ret                     必传                            等于day_month 24小时数据、近一个月数据, 等于:half_year 半年、一年数据
+    identify_model          必传                            识别模型A,识别模型B
+    
+    等于day_month返回值:
+     "data": [
+        {
+            "addtime": "2021-03-09 11:28:08",                   时间
+            "pest_name": "夜蛾",                                害虫名
+            "pest_num": 5                                       数量
+        },
+        {
+            "addtime": "2021-03-09 18:51:07",
+            "pest_name": "夜蛾",
+            "pest_num": 4
+        },
+    等于half_year返回值:
+     "data": [
+        {
+            "addtime": "2021-03",                           月份
+            "pest_name": "夜蛾",                            害虫名
+            "pest_num": 54                                  数量
+        },
+        {
+            "addtime": "2021-04",
+            "pest_name": "夜蛾",
+            "pest_num": 44
+        }
+    ],
+    "pest_name":{
+        "水龟虫":20
+    }
+    """
+
+    start_time = request.POST.get("start_time")
+    end_time = request.POST.get("end_time")
+    ret = request.POST.get("ret")
+    pest_name = request.POST.get("pest_name")
+    identify_model = request.POST.get("identify_model","A")
+    if identify_model=="A":
+        models = CBDphoto
+    elif identify_model=="B":
+        models = CBDphoto_B
+    myuser = request.myuser
+    print(myuser.uid)
+    date = [] 
+    devices = Device.devices(uid=myuser.uid, myuser=myuser)
+    if myuser.user_type != 4 or myuser.user_type != 1:
+        devices = devices.filter(disable=1)
+    for i in devices:
+        if not myuser.user_type == 1 and i.device_expire == "1":
+            cbd_data = models.objects.filter(~Q(indentify_photo=None),device_id=i.id,photo_status=1).filter(addtime__lte=int(i.device_expire_time))
+            if end_time:
+                if int(end_time) > int(i.device_expire_time):
+                    end_time = i.device_expire_time
+                cbd_data = cbd_data.filter(addtime__range=(int(start_time),int(end_time)))
+        else:
+            cbd_data = models.objects.filter(~Q(indentify_photo=None),device_id=i.id,photo_status=1)
+            if start_time:
+                cbd_data = cbd_data.filter(addtime__range=(int(start_time),int(end_time)))
+        for x in cbd_data:
+            photo_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(x.addtime))
+            if x.indentify_result:
+                xx_result =  x.indentify_result.split("#")
+                for yy in xx_result:
+                    yy_result = yy.split(",")
+                    try:
+                        if pest_name == insect_dict[yy_result[0]]:
+                            date.append({
+                                    "photo_time" : photo_time,
+                                    "pest_num" : int(yy_result[1]),
+                                    "pest_name" : insect_dict[yy_result[0]]})
+                        if not pest_name:
+                            date.append({
+                                    "photo_time" : photo_time,
+                                    "pest_num" : int(yy_result[1]),
+                                    "pest_name" : insect_dict[yy_result[0]]})
+                    except:
+                        continue
+    data = {}
+    if ret == "day_month":
+        print("24小时数据---近一个月数据")
+        for item in date:
+            photo_time, pest_name, pest_num = item['photo_time'], item['pest_name'], item['pest_num']
+            key = '{},{}'.format(photo_time, pest_name)
+            if key in data:
+                data[key] += pest_num
+            else:
+                data[key] = pest_num
+        result = []
+        for key, value in data.items():
+            photo_time,pest_name = key.split(',')
+            result.append({
+                "addtime" : photo_time,
+                "pest_name" : pest_name,
+                "pest_num" : data[key]
+
+            })
+        list2 = sorted(result, key=operator.itemgetter('addtime'))
+    elif ret == "half_year":
+        print("近半年_近一年")
+        for item in date:
+            photo_time, pest_name, pest_num = item['photo_time'], item['pest_name'], item['pest_num']
+            addtime = photo_time.split("-")[0] + "-" + photo_time.split("-")[1]
+            key = '{},{}'.format(addtime, pest_name)
+            if key in data:
+                data[key] += pest_num
+            else:
+                data[key] = pest_num
+        result = []
+        for key, value in data.items():
+            addtime,pest_name = key.split(',')
+            result.append({
+                "addtime" : addtime,
+                "pest_name" : pest_name,
+                "pest_num" : data[key]
+
+            })
+        list2 = sorted(result, key=operator.itemgetter('addtime'))
+    else:
+        raise PortError("ret", "参数超出范围")
+    datp = {}
+    pest_num_data = []
+    for item in date:
+        pest_num,pest_name = item['pest_num'],item["pest_name"]
+        key = '{}'.format(pest_name)
+        if key in datp:
+            datp[key] += pest_num
+        else:
+            datp[key] = pest_num
+    sort_data = sorted(datp.items(), key=lambda d:d[1], reverse = True )[:6]
+    for y in sort_data:
+        pest_num_data.append({
+            y[0] : y[1]
+        })
+    da = {
+        "data":list2,
+        "pest_name":pest_num_data
+    }
+    return da
+

+ 862 - 0
smartfarming/api/views/forecast/send_control.py

@@ -0,0 +1,862 @@
+import requests
+import json
+from json import JSONDecodeError
+
+from requests.auth import HTTPBasicAuth
+from smartfarming.api.views.forecast.all_dict import insect_dict,get_siminfo,get_simsinfo
+from kedong.decoration import kedong_deco, PortError
+from smartfarming.models.device import MongoDeviceConfig, MongoDevice
+
+
+@kedong_deco(login_required=True)
+def device_control_info(request):
+    """
+    设备控制信息/ 设备操作当前状态
+    参数:
+    d_id                   必传                         设备自增id
+    cmd                    必传                         netconf/paramconf/config/。。。用来标记获取什么类型的配置信息
+    """
+    post_info = request.POST
+    d_id = post_info.get("d_id", '')
+    cmd = post_info.get("cmd", '')
+    if not cmd:
+        raise PortError('cmd',"参数缺失")
+    if not d_id:
+        raise PortError('d_id', "参数缺失")
+
+    if MongoDeviceConfig.objects.filter(d_id=d_id,cmd=cmd).exists():
+        d_config = MongoDeviceConfig.objects.get(d_id=d_id,cmd=cmd)
+        try:
+            config = json.loads(d_config.device_config)
+        except:
+            config = eval(d_config.device_config)
+        if "ext" in config:
+            d_config = config["ext"]
+        else:
+            d_config = config
+        return d_config
+    else:
+        raise PortError(d_id, "配置未上传")
+
+
+def user_device_control(request):
+    """
+    用户远程控制设备下发(用于对接)
+    参数:
+    device_type_id              必传                          设备类型  2杀虫灯,3测报灯,4智能性诱,7孢子仪 5气象站, 14色诱测报灯 12吸虫塔
+    device_id                   必传                          设备号
+    config                      必传                          设备控制参数
+    username                    必传                          用户名
+
+    config 说明:
+        测报灯:{'ts': 0, 'tpl': 5, 'tt': 6, 'collt': 10, 'datt': 20, 'htim': 10, 'et': 6, 'st': 20, 'hst': 85, 'tph': 70, 'imgres': 0}
+        测报灯拍照:takephoto
+}
+
+     具体说明太长          对接口问我要
+    """
+    #测报灯  下发主题  /yfkj/cbd/sub/+imei
+    #杀虫灯  下发主题  /yfkj/scd/sub/+imei
+    #性诱设备  下发主题 yfkj/xycb/s2c/+imei
+    #孢子仪  下发主题 /yfkj/bzy/s2c/+imei
+    # myuid = request.myuser.uid
+    # user_type = request.user_type
+    post_info = request.POST
+    username = post_info.get("username")
+    ip = request.META.get('REMOTE_ADDR')
+    try:
+        check_username = DeviceUser.objects.get(real_name=username)
+    except:
+        raise PortError('username', "用户名不存在")
+
+    if check_username.user_type == 3:
+        raise PortError('', "控制异常,请联系上级")
+
+    
+    
+    device_type_id = post_info.get("device_type_id", '')
+    device_id = post_info.get("device_id", '')
+    if not device_id:
+        raise PortError('device_id',"参数缺失")
+    devices = Device.objects.all()
+   
+    try:
+        device = devices.get(device_id=device_id)
+    except:
+        raise PortError("device_id","没有此设备")
+
+    if not check_username.user_type == 1 and device.device_expire == "1":
+        raise PortError("device_id","设备已过期")
+    
+    config = post_info.get("config", '')
+    # cmd = post_info.get("cmd", '')
+    payload = {}
+    # if work_type == "0":
+    #     payload = {"cmd": "workmode", "ext": {"asleep": "1", "common": "0", "power": "0"}}
+    # elif work_type == "1":
+    #     payload = {"cmd": "workmode", "ext": {"asleep": "0", "common": "1", "power": "0"}}
+    # elif work_type == "2":
+    #     payload = {"cmd": "workmode", "ext": {"asleep": "0", "common": "0", "power": "1"}}
+
+    if config:
+        if config == "takephoto":
+            payload["cmd"] = "takephoto"
+        else:
+            try:
+                config = json.loads(config)
+            except  JSONDecodeError as e:
+                config = eval(config)
+            except:
+                raise PortError('',"参数类型错误")
+            payload["cmd"] = "paramconf"
+            payload["ext"] = config
+    else:
+        raise PortError('',"缺少config参数")
+
+    topic = ""
+    if not device_type_id:
+        raise PortError('device_type_id',"参数缺失")
+    if int(device_type_id) == 3:
+        topic = "/yfkj/cbd/sub/%s"%device.device_id
+    else:
+        raise PortError('device_type_id',"参数超出范围")
+
+    payload = json.dumps(payload)
+    cmds = {"topic":topic,"payload":payload,"qos":1}
+
+    content = "设备类型:%s,下发:%s"
+    operation_log(check_username.uid, content % (device_type_id, payload), device.device_id, 0, ip)
+    res = rp(cmds)
+    if res.status_code == 200:
+        return True
+
+
+def user_get_device_config(request):
+    """
+    查询设备配置信息/设备监测最新数据  (用于对接)
+    参数:
+    device_type_id                  必传                         设备类型  3测报灯
+    device_id                       必传                         设备号
+    control_type                    必传                         操作类型  data 读取设备数据信息
+    username                        必传                         用户名
+    """
+    #测报灯  下发主题  /yfkj/cbd/sub/+imei
+    #杀虫灯  下发主题  /yfkj/scd/sub/+imei
+    #性诱设备  下发主题 yfkj/xycb/s2c/+imei
+    #孢子仪  下发主题 /yfkj/bzy/s2c/+imei
+    # uid = request.myuser.uid
+    # user_type = request.user_type
+    # if user_type == 3:
+    #     raise PortError('', "控制异常,请联系上级")
+    
+    post_info = request.POST
+    device_type_id = post_info.get("device_type_id", '')
+    device_id = post_info.get("device_id", '')
+    if not device_id:
+        raise PortError('device_id', "参数缺失")
+    username = post_info.get("username")
+    ip = request.META.get('REMOTE_ADDR')
+    try:
+        check_username = DeviceUser.objects.get(real_name=username)
+    except:
+        raise PortError('username', "用户名不存在")
+    devices = Device.objects.all()
+    device = devices.get(device_id=device_id)
+
+    # myuser_type = request.user_type
+    if not check_username.user_type == 1 and device.device_expire == "1":
+        raise PortError('', "该设备已到期")
+
+
+    control_type = post_info.get("control_type", '')
+    if not control_type:
+        raise PortError('control_type',"参数缺失")
+    payload = {
+        "cmd": "read",
+        "ext":control_type
+    }
+    topic = ""
+    if not device_type_id:
+        raise PortError('device_type_id', "参数缺失")
+    if int(device_type_id) == 3:
+        topic = "/yfkj/cbd/sub/%s" % device.device_id
+    else:
+        raise PortError('device_type_id', "参数超出范围")
+    # elif int(device_type_id) == 2:
+    #     topic = "/yfkj/scd/sub/%s" % device.device_id
+    # elif int(device_type_id) == 4:
+    #     topic = "/yfkj/xycb/s2c/%s" % device.device_id
+    # elif int(device_type_id) == 5:
+    #     topic = "/yfkj/qxz/sub/%s" % device.device_id
+    #     payload = {
+    #     "cmd": "read",
+    #     "ext": {"type": control_type}
+    # }
+    # elif int(device_type_id) == 7:
+    #     topic = "/yfkj/bzy/s2c/%s" % device.device_id
+    # elif int(device_type_id) == 9:
+    #     topic = "/yfkj/tccbd/sub/%s" % device.device_id
+    # elif int(device_type_id) == 14:
+    #     topic = "yfkj/color/s2c/%s" % device.device_id
+    #     payload = {"cmd":"read","ext":"data"}
+    # elif int(device_type_id) == 8:
+    #     topic = "/yfkj/xyv3/s2c/%s" % device.device_id
+    cmd = {"topic": topic, "payload": json.dumps(payload), "qos": 1}    
+    res = requests.post("%s"%config_dict['mqtt_config']["http"], json=cmd,
+                        auth=HTTPBasicAuth(config_dict['mqtt_config']["user"], config_dict['mqtt_config']["secret_key"]))
+
+    if res.status_code == 200:
+        return True
+    else:
+        return False
+
+
+@kedong_deco(login_required=True)
+def device_control(request):
+    """
+    设备下发控制
+    参数:
+    device_type_id              必传                         设备类型  2杀虫灯,3测报灯,4智能性诱,7孢子仪 5气象站, 14色诱测报灯 12吸虫塔
+    d_id                        必传                         设备自增id
+    config                      非必传                        设备控制参数
+    work_type                   非必传                        工作模式时 必传 0节能 1常规  2加强
+    cmd                         非必传                        下发服务器配置使用 setnet
+    device_name                 必传                          设备名称
+
+    config 说明:
+        测报灯:{'ts': 0, 'tpl': 5, 'tt': 6, 'collt': 10, 'datt': 20, 'htim': 10, 'et': 6, 'st': 20, 'hst': 85, 'tph': 70, 'imgres': 0}
+        孢子仪:{'datt': 0, 'drop_time': 0, 'imgres': 0, 'set_temp': 25, 'coll_time': ['7-9', '10-11', Ellipsis], 'cul_time': 24, 'wind_sw': 0}
+        杀虫灯:{'timctrl': 1, 'et': 22, 'st': 20}
+        色诱测报灯: {'cmd': 'photoconf','ext': {'start': '18','end': '22','freq': '20'}   下发设置工作时间
+}
+
+                具体说明太长          对接口问我要
+    """
+    #测报灯  下发主题  /yfkj/cbd/sub/+imei
+    #杀虫灯  下发主题  /yfkj/scd/sub/+imei
+    #性诱设备  下发主题 yfkj/xycb/s2c/+imei
+    #孢子仪  下发主题 /yfkj/bzy/s2c/+imei
+    myuid = request.myuser.uid
+    user_type = request.user_type
+    if user_type == 3:
+        raise PortError('', "控制异常,请联系上级")
+    post_info = request.POST
+    device_type_id = post_info.get("device_type_id", '')
+    d_id = post_info.get("d_id", '')
+    req = post_info.get("req","")
+    work_type = post_info.get("work_type", '')
+    device_name = post_info.get("device_name", '')
+    if not d_id:
+        raise PortError('d_id',"参数缺失")
+    devices = MongoDevice.objects.all()
+    try:
+        device = devices.get(id=int(d_id))
+    except:
+        raise PortError("d_id","没有此设备")
+
+    if not user_type == 1 and device.device_expire == "1":
+        raise PortError("d_id","设备已过期")
+    if device_name:
+        device.device_name = device_name
+        device.save()
+    
+    config = post_info.get("config", '')
+    cmd = post_info.get("cmd", '')
+    payload = {}
+    if work_type == "0":
+        payload = {"cmd": "workmode", "ext": {"asleep": "1", "common": "0", "power": "0"}}
+    elif work_type == "1":
+        payload = {"cmd": "workmode", "ext": {"asleep": "0", "common": "1", "power": "0"}}
+    elif work_type == "2":
+        payload = {"cmd": "workmode", "ext": {"asleep": "0", "common": "0", "power": "1"}}
+
+    if config:
+        try:
+            config = json.loads(config)
+
+        except:
+            raise PortError('',"参数类型错误")
+    if not work_type:
+        if not config:
+            raise PortError('config', "参数缺失")
+        payload["cmd"] = "paramconf"
+        payload["ext"] = config
+
+    if req == "ctr_clear":
+        payload = {"cmd": "ctr_clear"}
+    topic = ""
+    if not device_type_id:
+        raise PortError('device_type_id',"参数缺失")
+    if int(device_type_id) == 3:
+        topic = "/yfkj/cbd/sub/%s"%device.device_id
+    elif int(device_type_id) == 2:
+        topic = "/yfkj/scd/sub/%s"%device.device_id
+    elif int(device_type_id) == 4:
+        topic = "/yfkj/xycb/s2c/%s"%device.device_id
+    elif int(device_type_id) in [5, 8]:
+        topic = "/yfkj/qxz/sub/%s"%device.device_id
+
+        timeout = config.get("timeout","")
+        content = config.get("content","")
+        interval = config.get("interval","")
+        if content:
+            payload["cmd"] = "dotled"
+            payload["ext"] = {
+                "content":content,
+                "timeout":timeout,
+            }
+            cmds = {"topic": topic, "payload": payload, "qos": 1}
+            content = "气象站:%s,下发:%s"
+            rp(cmds)
+        if interval:
+            payload["cmd"] = "config"
+            payload["ext"] = {"interval":interval}
+            cmds = {"topic": topic, "payload": payload, "qos": 1}
+            rp(cmds)
+        return True
+    elif int(device_type_id) == 7:
+        topic = "/yfkj/bzy/s2c/%s"%device.device_id
+    
+    elif int(device_type_id) == 14:
+        payload = config
+        topic = "yfkj/color/s2c/%s"%device.device_id
+    elif int(device_type_id) == 12:
+        topic = "/yfkj/cbd/sub/%s"%device.device_id
+    if cmd == "setnet":
+        ftp = config["ftp"]
+        mqtt = config["mqtt"]
+        mqtt["qos"] = 0
+        payload = {
+            "cmd":cmd,
+            "ftp": ftp,
+            "mqtt": mqtt,
+        }
+    payload = json.dumps(payload)
+    cmds = {"topic":topic,"payload":payload,"qos":1}
+
+    content = "设备类型:%s,下发:%s"
+    # TODO 大数据平台转发
+    print(cmds)
+    response_code = 200
+    if response_code == 200:
+        return True
+
+
+@kedong_deco(login_required=True)
+def clear_insects_permission(request):
+    """
+    杀虫灯账户是否具有清虫权限
+    """
+    uid = request.myuser.uid
+    data = [0, 0]
+    return data
+
+
+
+def clear_insects(request):
+    """
+    杀虫灯批量一键自清虫
+    """
+    uid = request.myuser.uid
+    myuser = request.myuser
+    device_query =  Device.devices(uid=uid,myuser=myuser)
+    scd_query = device_query.filter(device_type_id=2)
+    scd_imei_list = [i.device_id for i in scd_query]
+    for i in scd_imei_list:
+        topic = "/yfkj/scd/sub/%s" % i
+        payload = json.dumps({"cmd": "ctr_clear"})
+        cmds = {"topic":topic,"payload":payload,"qos":1}
+        try:
+            res = rp(cmds)
+            if res.status_code != 200:
+                return False
+        except:
+            return False
+    return True
+
+
+
+def scd_device_control(request):
+    """
+    杀虫灯批量下发控制接口
+    参数:
+    imei_list                   必传                         设备imei号 为选中的设备下发
+    config                      必传                       设备控制参数
+      
+    config 说明:
+        杀虫灯:{"st":"20","et":"2","ds":"0","ts":"0","tt":"4","dattim":"30","clt":"120"}
+
+    下发成功后返回值:
+    "data": [],
+    下发未成功返回值:
+     "data": [
+        "863488050761140"                                   下发未成功设备号
+    ],
+}
+    """
+    #测报灯  下发主题  /yfkj/cbd/sub/+imei
+    #杀虫灯  下发主题  /yfkj/scd/sub/+imei
+    #性诱设备  下发主题 yfkj/xycb/s2c/+imei
+    #孢子仪  下发主题 /yfkj/bzy/s2c/+imei
+    imei_list = request.POST.get("imei_list")
+
+    config = request.POST.get("config", '')
+    uid = request.myuser.uid
+    myuser = request.myuser
+
+    if not config:
+        raise PortError("config","配置信息未传")
+    if not imei_list:
+        raise PortError("imei_list","设备列表未传")
+    
+    try:
+        config = json.loads(config)
+    except:
+        raise PortError('',"参数类型错误")
+    data = []
+    payload = {}
+    payload["cmd"] = "paramconf"
+    payload["ext"] = config
+    payload = json.dumps(payload)
+
+    device_ids = json.loads(imei_list)
+    device_query =  Device.devices(uid=uid,myuser=myuser)
+    scd_query = device_query.filter(device_type_id=2)
+    scd_list = [i.device_id for i in scd_query]
+    
+    for i in device_ids:
+        if i in scd_list:
+            topic = "/yfkj/scd/sub/%s" % i
+            cmds = {"topic":topic,"payload":payload,"qos":1}
+            try:
+                res = rp(cmds)
+                if res.status_code == 200:
+                    pass
+                else:
+                    data.append(i)
+            except:
+                data.append(i)
+        else:
+            raise PortError('permission error',"%s设备非用户账户下"%i)
+    return data      
+
+
+@kedong_deco(login_required=True)
+def get_device_config(request):
+    """
+    查询设备配置信息/设备监测最新数据  刷新按钮
+    参数:
+    device_type_id                  必传                         设备类型  2杀虫灯,3测报灯,4智能性诱,5气象站,6监控设备,7孢子仪  14色诱测报  12吸虫塔
+    d_id                            必传                         设备自增id
+    control_type                    必传                         操作类型  data 读取设备数据信息/serverconf 读取服务器配置信息
+    """
+    #测报灯  下发主题  /yfkj/cbd/sub/+imei
+    #杀虫灯  下发主题  /yfkj/scd/sub/+imei
+    #性诱设备  下发主题 yfkj/xycb/s2c/+imei
+    #孢子仪  下发主题 /yfkj/bzy/s2c/+imei
+    # uid = request.myuser.uid
+    # user_type = request.user_type
+    # if user_type == 3:
+    #     raise PortError('', "控制异常,请联系上级")
+    imei_list = ["866950041980524","866950041980458","866950041975045","866950041941286","866950041941203","866950041980425","866950041941377"]
+    post_info = request.POST
+    device_type_id = post_info.get("device_type_id", '')
+    d_id = post_info.get("d_id", '')
+    if not d_id:
+        raise PortError('d_id', "参数缺失")
+    devices = MongoDevice.objects.all()
+    device = devices.get(id=int(d_id))
+
+    myuser_type = request.user_type
+    if not myuser_type == 1 and device.device_expire == "1":
+        raise PortError('', "该设备已到期")
+
+    control_type = post_info.get("control_type", '')
+    if not control_type:
+        raise PortError('control_type',"参数缺失")
+    payload = {
+        "cmd": "read",
+        "ext":control_type
+    }
+    topic = ""
+    if not device_type_id:
+        raise PortError('device_type_id', "参数缺失")
+    if int(device_type_id) == 3 or int(device_type_id) == 12:
+        topic = "/yfkj/cbd/sub/%s" % device.device_id
+    elif int(device_type_id) == 2:
+        topic = "/yfkj/scd/sub/%s" % device.device_id
+    elif int(device_type_id) == 4:
+        topic = "/yfkj/xycb/s2c/%s" % device.device_id
+    elif int(device_type_id) == 5:
+        topic = "/yfkj/qxz/sub/%s" % device.device_id
+        payload = {
+        "cmd": "read",
+        "ext": {"type": control_type}
+    }
+    elif int(device_type_id) == 7:
+        topic = "/yfkj/bzy/s2c/%s" % device.device_id
+    elif int(device_type_id) == 9:
+        topic = "/yfkj/tccbd/sub/%s" % device.device_id
+    elif int(device_type_id) == 14:
+        topic = "yfkj/color/s2c/%s" % device.device_id
+        payload = {"cmd":"read","ext":"data"}
+    elif int(device_type_id) == 8:
+        topic = "/yfkj/xyv3/s2c/%s" % device.device_id
+    if device.device_id in imei_list:
+        topic = "yfkj/xycb/s2c/%s" % device.device_id
+        cmd = {"topic": topic, "payload": json.dumps(payload), "qos": 1}
+    #     res = requests.post("http://www.yfzhwlw.com:8080/api/v2/mqtt/publish",
+    #                     data=json.dumps(cmd, indent=1), auth=HTTPBasicAuth("admin", "yfkj_6019"))
+    # else:
+    #     cmd = {"topic": topic, "payload": json.dumps(payload), "qos": 1}    
+    #     res = requests.post("%s"%config_dict['mqtt_config']["http"], json=cmd,
+    #                         auth=HTTPBasicAuth(config_dict['mqtt_config']["user"], config_dict['mqtt_config']["secret_key"]))
+    # TODO 暂时处理调用http接口
+    code = 200
+    if code == 200:
+        return True
+    else:
+        return False
+
+
+@kedong_deco(login_required=True)
+def admin_device_control(request):
+    """
+    单个按钮管理员操作  设备控制
+    参数:
+    device_type_id              必传                         设备类型  2杀虫灯,3测报灯,4智能性诱,5气象站,6监控设备,7孢子仪, 9糖醋测报灯 14色诱测报灯 8性诱3.0 12吸虫塔
+    d_id                        必传                         设备自增id
+    cmd                         必传                         设备控制参数  poweroff关机
+                                                                        poweron开机
+                                                                        reboot重启
+                                                                        update升级
+                                                                        coldoff制冷关闭
+                                                                        coldon制冷开启
+                                                                        takephoto拍照
+                                                                        autotakephoto 对焦拍照
+                                                                        boot1 屏幕禁用
+                                                                        boot0 屏幕取消禁用
+                                                                        turnset 设置定时卷粘虫板时间
+                                                                        turn 卷粘虫带/转仓
+                                                                        photoset 拍照时刻
+                                                                        repower 重新上电
+                                                                        data    数据上传
+                                                                        mqttconf  mqtt网络配置
+                                                                        close_shake 关闭震动
+                                                                        open_shake  开启震动
+                                                                        clearworm   清网
+                                                                        dtu_reboot  重启
+                                                                        dtu_update  升级
+                                                                        test        杀虫灯一键测试
+                                                                        big_data    平台转换到大数据平台
+                                                                        yfwlw       平台转发到四情平台
+                                                                        location 手动定位,传lat、lng 参数
+                                                                        imei 修改设备号, 传 imei 参数设备号
+                                                                        photo_num  拍照数量 传num 参数 拍照数
+    parm                        非必传                     当某些控制操作需要参数限制的时候 必传  (比如设置定时时间10分钟  传 10)
+
+
+    """
+    #测报灯  下发主题  /yfkj/cbd/sub/+imei
+    #杀虫灯  下发主题  /yfkj/scd/sub/+imei
+    #性诱设备  下发主题 yfkj/xycb/s2c/+imei
+    #孢子仪  下发主题 /yfkj/bzy/s2c/+imei
+    #气象站  下发主题 /yfkj/qxz/sub/+imei
+    #性诱测报  下发主题 yfkj/color/s2c
+    post_info = request.POST
+    cmd = post_info.get("cmd", '')
+    if not cmd:
+        raise PortError('cmd', "参数缺失")
+    device_type_id = post_info.get("device_type_id", '')
+    parm = post_info.get('parm', "")
+    d_id = post_info.get("d_id", '')
+    if not d_id:
+        raise PortError('d_id',"参数缺失")
+    devices = MongoDevice.objects.all()
+    device_id = devices.get(id=int(d_id)).device_id
+    payload = ""
+    topic = ""
+    if not device_type_id:
+        raise PortError('device_type_id',"参数缺失")
+    if int(device_type_id) == 3 or int(device_type_id) == 12:
+        topic = "/yfkj/cbd/sub/%s"%device_id
+        payload = {"cmd": cmd}
+        if cmd == "boot1":
+            payload = {"cmd":"switch","ext":{"boot":1}}
+        elif cmd == "boot0":
+            payload = {"cmd":"switch","ext":{"boot":0}}
+        elif cmd == "close_shake":
+            payload = {"cmd": "shake", "ext":{"ws":0}}   
+        elif cmd == "open_shake":
+            payload = {"cmd": "shake", "ext":{"ws":1}}
+        elif cmd == "yfwlw":
+            payload ={"cmd": "platform", "ext": {"type": "120.27.222.26"}}
+        elif cmd =="imei":
+            # 修改imei
+            imei = post_info.get("imei", '')
+            payload = {"cmd":"setimei","ext":{"imei":imei}}
+    elif int(device_type_id) == 2:
+        topic = "/yfkj/scd/sub/%s" % device_id
+        if cmd == "clear":
+            if not parm:
+                raise PortError('parm',"参数缺失")
+            payload = {"cmd":"clear","ext":{ "clt":int(parm)}}
+        elif cmd == "test":
+            payload = {"cmd":"test"}
+        elif cmd == "yfwlw": # 平台切换
+            payload ={"cmd":"paramconf","ext":{"type": "120.27.222.26"}}
+        elif cmd == "paramconf1": # 标配物联网
+            payload = {"cmd":"paramconf","ext":{"vt": "uart"}}
+        elif cmd == "paramconf2": # 物联网自清虫
+            payload = {"cmd":"paramconf","ext":{"vt": "uart-ZQC"}}
+        elif cmd == "paramconf3":   # 物联网光控
+            payload = {"cmd":"paramconf","ext":{"vt": "uart-light"}}
+        elif cmd == "paramconf4":   # 物联网光控自清虫
+            payload = {"cmd":"paramconf","ext":{"vt": "uart-light-ZQC"}}
+        else:
+            payload = {"cmd": cmd}
+    elif int(device_type_id) == 4:
+        topic = "/yfkj/xycb/s2c/%s" % device_id
+        payload = {"cmd": cmd}
+
+        if cmd == "turnset":
+            if not parm:
+                raise PortError('parm',"参数缺失")
+            payload = {"cmd": "set", "ext": {"type": "turn", "turn_t": parm}}
+        elif cmd == "turn":
+            payload = {"cmd": "ctrl", "ext": {"turn": "1"}}
+        elif cmd == "photoset":
+            if not parm:
+                raise PortError('parm', "参数缺失")
+            pic_t,pic_f = str(parm).split('|')  #  pic_t定时拍照时刻   "pic_f"定时拍照时间间隔
+            payload = {"cmd": "set", "ext": {"type": "photo", "pic_t": pic_t, "pic_f": pic_f}}
+        elif cmd == "repower":
+            payload = {"cmd": "repower","ext":""}
+        elif cmd == "yfwlw":
+            payload ={"cmd": "platform", "ext": {"type": "120.27.222.26"}}
+ 
+    elif int(device_type_id) == 8:
+        topic = "/yfkj/xyv3/s2c/%s" % device_id
+        payload = {"cmd": cmd}
+
+        if cmd == "turnset":
+            if not parm:
+                raise PortError('parm',"参数缺失")
+            payload = {"cmd": "set", "ext": {"type": "turn", "turn_t": parm}}
+        elif cmd == "turn":
+            payload = {"cmd": "ctrl", "ext": {"turn": "1"}}
+        elif cmd == "photoset":
+            if not parm:
+                raise PortError('parm', "参数缺失")
+            pic_t,pic_f = str(parm).split('|')  #  pic_t定时拍照时刻   "pic_f"定时拍照时间间隔
+            payload = {"cmd": "set", "ext": {"type": "photo", "pic_t": pic_t, "pic_f": pic_f}}
+        elif cmd == "repower":
+            payload = {"cmd": "repower","ext":""}
+       
+    elif int(device_type_id) == 5:
+        topic = "/yfkj/qxz/sub/%s" % device_id
+        payload = {
+            "cmd": cmd
+        }
+    elif int(device_type_id) == 7:
+        lists = ["update","reboot","poweroff","poweron","coldoff","coldon","dtu_update","dtu_reboot"]
+        payload = {"cmd": cmd}
+        if cmd == "takephoto":
+            payload = {"cmd": "ctrl", "ext": {"type": "takephoto"}}
+        elif cmd in lists:
+            payload = {"cmd":cmd}
+        elif cmd == "autotakephoto":
+            payload = {"ext":{"type":"auto_takephoto"},"cmd":"ctrl"}
+        elif cmd == "turn":
+            payload = {"ext":{"type":"turn"},"cmd":"ctrl"}
+        elif cmd == "big_data":
+            # 大数据平台:
+            payload ={"cmd": "platform", "ext": {"type": "8.136.98.49"}}
+        elif cmd == "yfwlw":
+            payload ={"cmd": "platform", "ext": {"type": "120.27.222.26"}}
+
+        elif cmd == "location":
+            #设置手动定位
+            lat = post_info.get("lat", '')
+            lng = post_info.get("lng", '')
+            payload ={"cmd":"location", "ext":{"lat":lat,"lng":lng,"type":0}}
+        elif cmd == "imei":
+            # 修改设备ID:
+            imei = post_info.get("imei", '')
+            payload = {"cmd":"setimei","ext":{"imei":imei}}
+        elif cmd == "photo_num":
+            num = int(post_info.get("num", ''))
+            payload = {"cmd":"warn","ext":{"status":num,"type":"get_photo_step"}}
+        topic = "/yfkj/bzy/s2c/%s" % device_id
+    elif int(device_type_id) == 9:
+        topic = "/yfkj/tccbd/sub/%s" % device_id
+        if cmd == "takephoto":
+            payload = {"ext": {"type": "takephoto"}, "cmd": "ctrl"}
+        elif cmd == "reboot":
+            payload = {"cmd":"reboot","ext":""}
+        elif cmd == "update":
+            payload = {"cmd":"update","ext":""}
+        elif cmd == "status":
+           payload = {"cmd": "read", "ext": {"type": "status"}}
+        elif cmd == "paramconf":
+            payload = {"cmd": "read", "ext": {"type": "paramconf"}}
+        elif cmd == "boot1":
+            payload = {"cmd": "paramconf","ext": {"st": 20,"et": 5,"collt": 10,"htim": 0,"datt": 20,"pump_sec": 20,"shake_sec": 20,"boot": 1}}
+
+    elif int(device_type_id) == 14:
+        topic = "yfkj/color/s2c/%s" % device_id
+        if cmd == "update":
+            payload = {"cmd": "dtu_update"}
+        elif cmd == "reboot":
+            payload = {"cmd": "dtu_reboot"}
+        elif cmd =="takephoto":
+            payload = {"cmd":"rtu_takephoto"}
+    payload = json.dumps(payload)
+    data = {"topic":topic,"payload":payload,"qos":1}
+    # TODO 调用大数据平台接口
+    response_code = 200
+    if response_code == 200:
+        return True
+    else:
+        return False
+
+
+
+def tccbd_device_control(request):
+    """
+    糖醋测报单个按钮操作/设备设置
+    参数:
+    device_type_id              必传                         设备类型   9 糖醋测报灯
+    d_id                        必传                         设备自增id
+    cmd                         必传                         设备控制参数  reboot重启
+                                                                        update升级
+                                                                        takephoto拍照
+                                                                        boot1 屏幕禁用
+                                                                        status 查询最新状态
+                                                                        paramconf 查询配置信息
+                                                                        
+
+                                                                        set 下发设置所需参数
+                                                                        st 定时开始时间
+                                                                        et 定时结束时间
+                                                                        collt 收集时间
+                                                                        htim 糖醋液发挥时间
+                                                                        datt 数据上传时间间隔
+                                                                        pump_sec 水泵打开时间
+                                                                        shake_sec 电磁阀打开时间
+                                                                        jp 加液排水时间
+
+
+    """
+    
+    post_info = request.POST
+    device_type_id = post_info.get("device_type_id", '')
+    d_id = post_info.get("d_id", '')
+    cmd = post_info.get("cmd", '')
+    devices = Device.objects.all()
+    device_id = devices.get(id=int(d_id)).device_id
+    if not cmd:
+        raise PortError('cmd', "参数缺失")
+    if  int(device_type_id) == 9:
+        if cmd == "takephoto":
+            payload = {"ext": {"type": "takephoto"}, "cmd": "ctrl"}
+        elif cmd == "reboot":
+            payload = {"cmd":"reboot","ext":""}
+        elif cmd == "update":
+            payload = {"cmd":"update","ext":""}
+        elif cmd == "status":
+            payload = {"cmd": "read", "ext": {"type": "status"}}
+        elif cmd == "paramconf":
+            payload = {"cmd": "read", "ext": {"type": "paramconf"}}
+        elif cmd == "boot1":
+            payload = {"cmd": "paramconf","ext": {"st": 20,"et": 5,"collt": 10,"htim": 0,"datt": 20,"pump_sec": 20,"shake_sec": 20,"boot": 1}}
+        elif cmd == "set":
+            st = post_info.get('st') #定时开始时间
+            et = post_info.get('et')#定时结束时间
+            collt = post_info.get('collt') #收集时间
+            htim = post_info.get('htim') #糖醋液发挥时间
+            datt = post_info.get('datt') #数据上传时间间隔
+            pump_sec = post_info.get('pump_sec')    #pump_sec水泵打开时间
+            shake_sec = post_info.get('shake_sec') #电磁阀打开时间
+            jp = post_info.get("jp")  # 加液排水时间
+            payload = {"cmd": "paramconf","ext": {"st": int(st),"et": int(et),"collt": int(collt),"htim": int(htim),"datt": int(datt),"pump_sec": int(pump_sec),"shake_sec": int(shake_sec),"jp":int(jp),"boot": 0}}
+
+        topic = "/yfkj/tccbd/sub/%s" % device_id
+        payload = json.dumps(payload)
+        data = {"topic":topic,"payload":payload,"qos":1}
+        res = requests.post("%s" % config_dict['mqtt_config']["http"], json=data,
+                            auth=HTTPBasicAuth(config_dict['mqtt_config']["user"], config_dict['mqtt_config']["secret_key"]))
+        if res.status_code == 200:
+            return True
+    else:
+        raise PortError('cmd', "设备类型错误")
+
+
+
+
+def device_sim(request):
+    """
+    设备查询sim卡接口
+    d_id                        必传                         设备自增id
+    iccid                       非必传                       用户填写的iccid
+    type                        必传                         sim卡类型 sim  hksim 海康sim  change修改 iccid
+    
+    """
+    post_info = request.POST
+    _device_id = post_info.get("d_id")
+    iccid = post_info.get("iccid")
+
+    types = post_info.get("type")
+
+    if not _device_id:
+        raise PortError('d_id', "未传设备id")
+
+    if iccid and not iccid.isalnum():
+        # if not iccid.isalnum():
+        raise PortError('iccid', "不能输入特殊字符")
+
+    data = []
+    try:
+        device = Device.objects.get(id=_device_id)
+    except:
+        raise PortError('d_id', "没有该设备")
+    if types == "hksim":
+        data.append({"iccid":device.simid})
+    elif types == "sim":
+        if device.device_type_id == 7:
+            models = BZYData
+        elif device.device_type_id == 4:
+            models = XYCBData
+        elif device.device_type_id == 2:
+            models = SCDData
+        elif device.device_type_id == 3:
+            models = CBDData
+        elif device.device_type_id == 8:
+            models = XYThreeData
+        elif device.device_type_id == 14:
+            models = SYCBData
+        elif device.device_type_id == 12:
+            models = XCTData
+        else:
+            raise PortError('d_id', "暂无该设备类型")
+        
+        # if device.device_type_id == 12:
+        #     models = XCTData
+
+        decic = models.objects.filter(device_id=_device_id).order_by('-id')[:1]
+        # decic = DeviceData.objects.filter(device_id=_device_id).order_by('-addtime')[:1]
+        for  i in decic:
+            try:
+                iccid = eval(i.device_data)["iccid"]
+            except:
+                iccid = ""
+            data.append({"iccid":iccid})
+    elif types == "change":
+        device.simid = iccid
+        device.save()
+        data.append({"iccid":iccid})
+    else:
+        raise PortError('d_id', "参数有误")
+    return data
+
+

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2095 - 0
smartfarming/api/views/forecast/worm_lamp.py


+ 3 - 0
smartfarming/api/views/weather/__init__.py

@@ -0,0 +1,3 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/6/3 5:26 下午
+# @Author  : Creat by Han

BIN
smartfarming/api/views/weather/__pycache__/__init__.cpython-36.pyc


BIN
smartfarming/api/views/weather/__pycache__/all_dict.cpython-36.pyc


BIN
smartfarming/api/views/weather/__pycache__/weather.cpython-36.pyc


+ 107 - 0
smartfarming/api/views/weather/all_dict.py

@@ -0,0 +1,107 @@
+qxz_dict = {
+    '100':['未定义',],
+    '101':['101','空气温度','℃'],
+    '102':['102','空气湿度','%RH'],
+    '103':['103','气压','hpa'],
+    '104':['104','降雨量','mm'],
+    '105':['105','总辐射','w/㎡'],
+    '106':['106','土壤温度','℃'],
+    '107':['107','土壤含水率','%'],
+    '108':['108','风速','m/s'],
+    '109':['109','风向','°'],
+    '110':['110','蒸发量','mm'],
+    '111':['111','雪量','mm'],
+    '112':['112','光照度','LUX'],
+    '113':['113','日照时数','h'],
+    '114':['114','光合','w/㎡'],
+    '115':['115','降雨量累计','mm'],
+    '116':['116','辐射累计','MJ/㎡'],
+    '117':['117','有无雨雪',''],
+    '118':['118','噪声','分贝'],
+    '119':['119','水位','cm'],
+    '120':['120','二氧化碳','PPM'],
+    '121':['121','曝辐量','cal/cm2'],
+    '122':['122','液位','mm'],
+    '123':['123','光合有效辐射','W/m2'],
+    '124':['124','电压','V'],
+    '125':['125','紫外线','w/㎡'],
+    '126':['126','粉尘','ug/m3'],
+    '127':['127','气压','hpa'],
+    '128':['128','土壤PH值',''],
+    '129':['129','最大风速','m/s'],
+    '130':['130','平均风速','m/s'],
+    '131':['131','经度','°'],
+    '132':['132','纬度','°'],
+    '133':['133','海拔高度','m'],
+    '134':['134','TBQ总辐射','W/m2'],
+    '135':['135','直接辐射','W/m2'],
+    '136':['136','散射辐射','W/m2'],
+    '138':['138','紫外辐射','W/m2'],
+    '139':['139','贴片温度','℃'],
+    '140':['140','露点温度','℃'],
+    '141':['141','一氧化碳','PPM'],
+    '142':['142','电流','mA'],
+    '143':['143','超声波风速','m/s'],
+    '144':['144','水温','℃'],
+    '145':['145','PM2.5','ug/m3'],
+    '146':['146','PM10','ug/m3'],
+    '147':['147','土壤PH',' '],
+    '148':['148','溶解氧','mg/l'],
+    '149':['149','氨氮','mg/l'],
+    '150':['150','电导率','mS/cm'],
+    '151':['151','浊度','NTU'],
+    '152':['152','能见度',' m'],
+    '153':['153','氨气','ppm'],
+    '154':['154','盐分','mg/L'],
+    '155':['155','氮','mg/kg'],
+    '156':['156','磷','mg/kg'],
+    '157':['157','钾','mg/kg'],
+    '158':['158','热通量','W/m2'],
+    '159':['159','叶面温度','℃'],
+    '160':['160','叶面湿度','%RH'],
+    '161':['161','茎秆','mm'],
+    '162':['162','负氧离子','个/cm3'],
+    '164':['164','当前水位','mm'],
+    '165':['165','昨日水位','mm'],
+    '166':['166','今日雨量','mm'],
+    '167':['167','昨日雨量','mm'],
+    '168':['168','今日溢流','mm'],
+    '169':['169','昨日溢流','mm'],
+    '170':['170','今日蒸发','mm'],
+    '171':['171','昨日蒸发','mm'],
+    '172':['172','编码数据',''],
+    '173':['173','错误编码',''],
+    '174':['174','补水码',''],
+    '175':['175','溢流码',''],
+    '178':['178','电导率','uS/cm'],
+    '201':['201','土壤水势','KPA'],
+    '202':['202','露点温度','℃'],
+    '203':['203','PM100','ug/m3'],
+    '208':['208','光照度','Lux'],
+    '211':['211','电导率','μS/cm'],
+    '212':['212','净辐射','W/m2'],
+    '213':['213','流速','m/s'],
+    '214':['214','空高','m'],
+    '215':['215','瞬时流量','m3/s'],
+    '216':['216','累积流量','m3'],
+    '217':['217','热通量累计','MJ/m2'],
+    '218':['218','果实直径','mm'],
+    '219':['219','硫化氢','ppm'],
+    '220':['220','氧气','ppm'],
+    '221':['221','臭氧','ppm'],
+    '222':['222','茎流','ml/h'],
+    '223':['223','COD','mg/L'],
+    '224':['224','信号强度',''],
+    '225':['225','盐度','PSU'],
+    '226':['226','ORP','mV'],
+    '227':['227','光量子','W/m2'],
+    '228':['228','水质pH',''],
+    '229':['229','氨氮','ppm'],
+    '230':['230','水位','m'],
+    '251':['251','湿球温度','℃'],
+    '252':['252','最大阵风','m/s'],
+    '253':['253','平均风速','m/s'],
+    '255':['255','土壤张力','kpa'],
+    '231':['231','二氧化硫','ppm'],
+    '232':['232','二氧化氮','ppm']
+}

+ 409 - 0
smartfarming/api/views/weather/weather.py

@@ -0,0 +1,409 @@
+# -*- coding:utf-8 -*-
+# @Time    : 2020/5/22 2:22 下午
+# @Author  : Creat by Han
+import json
+
+import copy
+import datetime
+import time
+import os
+import requests
+from django.forms.models import model_to_dict
+from django.db.models import Q
+from django.conf import settings
+from kedong.decoration import kedong_deco, PortError
+from smartfarming.models.device import MongoDevice
+from smartfarming.models.weather import MongoQXZ_Base_Info, QXZdata_New, MongoQXZ_Conf, QXZstatus_New
+from smartfarming.api.views.weather.all_dict import qxz_dict
+
+config_dict = settings.CONFIG
+
+
+@kedong_deco(login_required=True)
+def qxz_page(request):
+    """
+    气象设备列表接口 :
+    参数:
+    page                    非必传(num)                     页码,默认为1
+    device_id               非必传(str)                     设备号
+    device_status           非必传(str)                     在线状态 1在线 0离线
+    device_name             非必传(str)                     设备名称
+    device_type             非必传(str)                      5气象站 8墒情站
+    返回值:
+    {
+        "data": {                       
+        "ids": [
+            {
+                "d_id":"",                              设备数据库ID
+                "equip_name":"",                        设备名称
+                "equip_id":12313456,                    设备ID
+                "is_online":1,                          在线状态   1在线 0离线
+                "rssi":10,                              信号强度
+                "volt":22,                              电压
+                "lng":113,                              经度
+                "lat":113,                              纬度
+                "off_time":""                           离线时间
+                "address":""                            设备地址
+                "device_expire_time": 1234444     设备到期时间
+                "device_expire": # 设备状态 0未到期,1已到期,2即将到期
+                "device_expire_days": 到期天数
+                }
+            ],                  
+        "nums": 0                                       设备总数
+        },
+        "formError": {},
+        "errorCode": 0,
+        
+        "message": "",
+        "params": {}
+    }
+
+    """
+    device_id = request.POST.get("device_id")
+    device_status = request.POST.get("device_status")
+    device_name = request.POST.get("device_name")
+    page = request.POST.get("page","")
+    page_size = request.POST.get("page_size","")
+    device_type = request.POST.get("device_type","5")
+    if not page and not page_size:
+        page = 1 
+        page_size = 8
+    else:
+        if not page.isdigit() and  not page_size.isdigit():
+            raise PortError("","字段类型有误")
+        else:
+            page = int(page)
+            page_size = int(page_size)
+    
+    if device_type not in ("5","8"):
+        raise PortError("","参数超出范围")
+
+
+    devices = MongoDevice.objects.filter(device_type_id=device_type).order_by('-device_status', '-uptime')
+    #设备状态查询
+    if device_status:
+        devices = devices.filter(device_status=int(device_status))
+    #设备号查询
+    if device_id:
+        devices = devices.filter(Q(device_id__icontains=device_id) | Q(device_name__icontains=device_id))
+    #设备名称查询
+    if device_name:
+        devices = devices.filter(device_name__icontains=device_name)
+
+    date = []
+    nums = devices.count()
+
+    result = devices[(page_size*(page-1)):(page*page_size)]
+    result_device_id_list = [item.device_id for item in result]
+    qxz_base_dict = {item.device_id: item for item in MongoQXZ_Base_Info.objects.filter(device_id__in=result_device_id_list)}
+    for i in result:
+        try:
+            qxz_base = qxz_base_dict[i.device_id]
+            rssi = qxz_base.rssi
+            volt = qxz_base.volt
+        except:
+            rssi = ""
+            volt = ""
+            
+        lng = i.lng
+        lat = i.lat
+        address = i.province+i.city+i.district
+        is_online = i.device_status
+        uptime = i.uptime
+
+        date.append({
+            "d_id":i.id,
+            "equip_name":i.device_name,
+            "equip_id":i.device_id,
+            "volt":volt,
+            "rssi":rssi,
+            "lng":lng,
+            "lat":lat,
+            "address":address,
+            "is_online":is_online,
+            "uptime":uptime,
+        })
+    
+    data = {'ids':date, 'nums': nums}
+    return data
+
+
+@kedong_deco(login_required=True)
+def qxz_detail(request):
+    """
+    气象历史数据接口 :
+    参数:
+    device_id               必传(string)
+    page                    非必传(num)                     页码,默认为1
+    start_time              非必传(string 时间戳)           开始时间    (用于时间搜索)
+    end_time                非必传(string 时间戳)           结束时间    (用于时间搜索)
+
+    返回值:
+    {
+        "data": {
+            "conf": {
+            "e1":x.e1,"e2":x.e2,"e3":x.e3,"e4":x.e4,"e5":x.e5,
+            "e6":x.e6,"e7":x.e7,"e8":x.e8,"e9":x.e9,"e10":x.e10,
+            "e11":x.e11,"e12":x.e12,"e13":x.e13,"e14":x.e14,
+            "e15":x.e15,"e16":x.e16,"e17":x.e17,"e18":x.e18,
+            "e19":x.e19,"e20":x.e20,"e21":x.e21,"e22":x.e22,
+            "e23":x.e23,"e24":x.e24,"e25":x.e25,"e26":x.e26,
+            "e27":x.e27,"e28":x.e28,"e29":x.e29,"e30":x.e30
+            },
+            "nums": 0,
+            "rainFall": 1              气象设备是否具有日雨量累计因子,有返回1,无返回0
+            "data": [
+                {
+                "e1":qxz_list.e1,"e2":qxz_list.e2,"e3":qxz_list.e3,"e4":qxz_list.e4,"e5":qxz_list.e5,
+                "e6":qxz_list.e6,"e7":qxz_list.e7,"e8":qxz_list.e8,"e9":qxz_list.e9,"e10":qxz_list.e10,
+                "e11":qxz_list.e11,"e12":qxz_list.e12,"e13":qxz_list.e13,"e14":qxz_list.e14,
+                "e15":qxz_list.e15,"e16":qxz_list.e16,"e17":qxz_list.e17,"e18":qxz_list.e18,
+                "e19":qxz_list.e19,"e20":qxz_list.e20,"e21":qxz_list.e21,"e22":qxz_list.e22,
+                "e23":qxz_list.e23,"e24":qxz_list.e24,"e25":qxz_list.e25,"e26":qxz_list.e26,
+                "e27":qxz_list.e27,"e28":qxz_list.e28,"e29":qxz_list.e29,"e30":qxz_list.e30, 
+                "upl_time":qxz_list.upl_time.strftime('%Y-%m-%d %H:%M:%S')
+                },
+                {
+                "e1":qxz_list.e1,"e2":qxz_list.e2,"e3":qxz_list.e3,"e4":qxz_list.e4,"e5":qxz_list.e5,
+                "e6":qxz_list.e6,"e7":qxz_list.e7,"e8":qxz_list.e8,"e9":qxz_list.e9,"e10":qxz_list.e10,
+                "e11":qxz_list.e11,"e12":qxz_list.e12,"e13":qxz_list.e13,"e14":qxz_list.e14,
+                "e15":qxz_list.e15,"e16":qxz_list.e16,"e17":qxz_list.e17,"e18":qxz_list.e18,
+                "e19":qxz_list.e19,"e20":qxz_list.e20,"e21":qxz_list.e21,"e22":qxz_list.e22,
+                "e23":qxz_list.e23,"e24":qxz_list.e24,"e25":qxz_list.e25,"e26":qxz_list.e26,
+                "e27":qxz_list.e27,"e28":qxz_list.e28,"e29":qxz_list.e29,"e30":qxz_list.e30, 
+                "upl_time":qxz_list.upl_time.strftime('%Y-%m-%d %H:%M:%S')
+                },...
+            ]
+            }
+        "params": {},
+        "formError": {},
+        "errorCode": 0,
+        "message": "",
+    
+    }
+
+    """
+    f_tbegin = request.POST.get('start_time')
+    f_tend = request.POST.get('end_time')
+    device_id = request.POST.get("device_id")
+    
+    try:
+        device = MongoDevice.objects.get(device_id=device_id)
+        device_expire = device.device_expire
+        device_expire_time = device.device_expire_time
+    except:
+        raise PortError('device_id',"暂无此设备")
+    
+    qxz_list = QXZdata_New.objects.filter(device_id=device_id)
+    
+    myuser_type = request.user_type
+    if not myuser_type == 1 and not myuser_type == 5:
+        if f_tbegin and int(f_tend) > int(device_expire_time):
+            f_tend = device_expire_time
+    if f_tbegin and f_tend:
+        qxz_list =qxz_list.filter(uptime__range=(int(f_tbegin),int(f_tend))).order_by('-id')
+    page = int(request.POST.get('page',1))
+    data = []
+    nums = qxz_list.count()
+    conf = {}
+    if nums:
+        for i in qxz_list[(10*(page-1)):(page*10)]:
+            dat = {}
+            for e in range(1, 31):
+                k = f'e{e}'
+                v = getattr(i, k)
+                dat[k] = v or ""
+            data.append({"dat": dat, "time": i.uptime})
+
+        try:
+            x = MongoQXZ_Conf.objects.get(device_id=device_id)
+            conf = {}
+            for e in range(1, 31):
+                k = f'e{e}'
+                v = getattr(x, k)
+                conf[k] = v or ""
+        except Exception as e:
+            conf = {}
+    rainFall = 0
+    for factor in conf.values():
+        if factor == "降雨量累计#mm":
+            rainFall = 1
+            break
+    data1 = {"data":data,"nums":nums,"conf":conf,"rainFall":rainFall}
+    return data1
+
+
+@kedong_deco(login_required=True)
+def qxz_status(request):
+    """
+    气象详情接口 :
+    参数:
+    device_id               必传(string)
+    返回值:
+    {
+    "data": {
+        'dat':{
+                "e1":qxz_list.e1,"e2":qxz_list.e2,"e3":qxz_list.e3,"e4":qxz_list.e4,"e5":qxz_list.e5,
+                "e6":qxz_list.e6,"e7":qxz_list.e7,"e8":qxz_list.e8,"e9":qxz_list.e9,"e10":qxz_list.e10,
+                "e11":qxz_list.e11,"e12":qxz_list.e12,"e13":qxz_list.e13,"e14":qxz_list.e14,
+                "e15":qxz_list.e15,"e16":qxz_list.e16,"e17":qxz_list.e17,"e18":qxz_list.e18,
+                "e19":qxz_list.e19,"e20":qxz_list.e20,"e21":qxz_list.e21,"e22":qxz_list.e22,
+                "e23":qxz_list.e23,"e24":qxz_list.e24,"e25":qxz_list.e25,"e26":qxz_list.e26,
+                "e27":qxz_list.e27,"e28":qxz_list.e28,"e29":qxz_list.e29,"e30":qxz_list.e30, 
+                "upl_time":qxz_list.upl_time.strftime('%Y-%m-%d %H:%M:%S')
+                },
+        'conf':{
+            "e1":x.e1,"e2":x.e2,"e3":x.e3,"e4":x.e4,"e5":x.e5,
+            "e6":x.e6,"e7":x.e7,"e8":x.e8,"e9":x.e9,"e10":x.e10,
+            "e11":x.e11,"e12":x.e12,"e13":x.e13,"e14":x.e14,
+            "e15":x.e15,"e16":x.e16,"e17":x.e17,"e18":x.e18,
+            "e19":x.e19,"e20":x.e20,"e21":x.e21,"e22":x.e22,
+            "e23":x.e23,"e24":x.e24,"e25":x.e25,"e26":x.e26,
+            "e27":x.e27,"e28":x.e28,"e29":x.e29,"e30":x.e30
+            },
+            "led":0,           0 无led点阵屏功能  1 有led点阵屏功能                                    
+            "ledinfo":"点阵屏内容"
+            },
+    "errorCode": 0,
+    "message": "",
+    "formError": {}
+    }
+
+    """
+    e_id = request.POST.get("device_id")
+    if not e_id:
+        raise PortError("","参数缺失")
+    qxz_list = QXZstatus_New.objects.filter(device_id=e_id).first()
+    if not qxz_list:
+        raise PortError("","未找到此设备")
+    data = []
+    dat = {"e1":qxz_list.e1,"e2":qxz_list.e2,"e3":qxz_list.e3,"e4":qxz_list.e4,"e5":qxz_list.e5,
+            "e6":qxz_list.e6,"e7":qxz_list.e7,"e8":qxz_list.e8,"e9":qxz_list.e9,"e10":qxz_list.e10,
+            "e11":qxz_list.e11,"e12":qxz_list.e12,"e13":qxz_list.e13,"e14":qxz_list.e14,
+            "e15":qxz_list.e15,"e16":qxz_list.e16,"e17":qxz_list.e17,"e18":qxz_list.e18,
+            "e19":qxz_list.e19,"e20":qxz_list.e20,"e21":qxz_list.e21,"e22":qxz_list.e22,
+            "e23":qxz_list.e23,"e24":qxz_list.e24,"e25":qxz_list.e25,"e26":qxz_list.e26,
+            "e27":qxz_list.e27,"e28":qxz_list.e28,"e29":qxz_list.e29,"e30":qxz_list.e30, "uptime":qxz_list.uptime}
+    try:
+        x = MongoQXZ_Conf.objects.get(device_id=e_id)
+        conf = {"e1":x.e1,"e2":x.e2,"e3":x.e3,"e4":x.e4,"e5":x.e5,
+                "e6":x.e6,"e7":x.e7,"e8":x.e8,"e9":x.e9,"e10":x.e10,
+                "e11":x.e11,"e12":x.e12,"e13":x.e13,"e14":x.e14,
+                "e15":x.e15,"e16":x.e16,"e17":x.e17,"e18":x.e18,
+                "e19":x.e19,"e20":x.e20,"e21":x.e21,"e22":x.e22,
+                "e23":x.e23,"e24":x.e24,"e25":x.e25,"e26":x.e26,
+                "e27":x.e27,"e28":x.e28,"e29":x.e29,"e30":x.e30}
+    except:
+        conf = {}
+    try:
+        led = MongoQXZ_Base_Info.objects.get(device_id=e_id).led
+    except:
+        led = "0"
+    try:
+        ledinfo = MongoQXZ_Base_Info.objects.get(device_id=e_id).ledinfo
+    except:
+        ledinfo = ""
+    data = {'dat':dat,'conf':conf, "led":led,"ledinfo":ledinfo}
+    return data
+
+
+@kedong_deco(login_required=True)
+def qxz_data_chart(request):
+    """
+    气象折线图接口 :
+    参数:
+    device_id               必传(string)
+
+    begin              必传(string 时间戳)             开始时间    (用于时间搜索)     默认近一个月
+    end                非必传(string 时间戳)           结束时间    (用于时间搜索)
+    返回值:
+    {
+        "data": {
+            "conf": {
+            "e1":x.e1,"e2":x.e2,"e3":x.e3,"e4":x.e4,"e5":x.e5,
+            "e6":x.e6,"e7":x.e7,"e8":x.e8,"e9":x.e9,"e10":x.e10,
+            "e11":x.e11,"e12":x.e12,"e13":x.e13,"e14":x.e14,
+            "e15":x.e15,"e16":x.e16,"e17":x.e17,"e18":x.e18,
+            "e19":x.e19,"e20":x.e20,"e21":x.e21,"e22":x.e22,
+            "e23":x.e23,"e24":x.e24,"e25":x.e25,"e26":x.e26,
+            "e27":x.e27,"e28":x.e28,"e29":x.e29,"e30":x.e30
+            },
+            "nums": 0,
+            "data": [
+                {
+                "e1":qxz_list.e1,"e2":qxz_list.e2,"e3":qxz_list.e3,"e4":qxz_list.e4,"e5":qxz_list.e5,
+                "e6":qxz_list.e6,"e7":qxz_list.e7,"e8":qxz_list.e8,"e9":qxz_list.e9,"e10":qxz_list.e10,
+                "e11":qxz_list.e11,"e12":qxz_list.e12,"e13":qxz_list.e13,"e14":qxz_list.e14,
+                "e15":qxz_list.e15,"e16":qxz_list.e16,"e17":qxz_list.e17,"e18":qxz_list.e18,
+                "e19":qxz_list.e19,"e20":qxz_list.e20,"e21":qxz_list.e21,"e22":qxz_list.e22,
+                "e23":qxz_list.e23,"e24":qxz_list.e24,"e25":qxz_list.e25,"e26":qxz_list.e26,
+                "e27":qxz_list.e27,"e28":qxz_list.e28,"e29":qxz_list.e29,"e30":qxz_list.e30, 
+                "upl_time":qxz_list.upl_time.strftime('%Y-%m-%d %H:%M:%S')
+                },
+                {
+                "e1":qxz_list.e1,"e2":qxz_list.e2,"e3":qxz_list.e3,"e4":qxz_list.e4,"e5":qxz_list.e5,
+                "e6":qxz_list.e6,"e7":qxz_list.e7,"e8":qxz_list.e8,"e9":qxz_list.e9,"e10":qxz_list.e10,
+                "e11":qxz_list.e11,"e12":qxz_list.e12,"e13":qxz_list.e13,"e14":qxz_list.e14,
+                "e15":qxz_list.e15,"e16":qxz_list.e16,"e17":qxz_list.e17,"e18":qxz_list.e18,
+                "e19":qxz_list.e19,"e20":qxz_list.e20,"e21":qxz_list.e21,"e22":qxz_list.e22,
+                "e23":qxz_list.e23,"e24":qxz_list.e24,"e25":qxz_list.e25,"e26":qxz_list.e26,
+                "e27":qxz_list.e27,"e28":qxz_list.e28,"e29":qxz_list.e29,"e30":qxz_list.e30, 
+                "upl_time":qxz_list.upl_time.strftime('%Y-%m-%d %H:%M:%S')
+                },...
+            ]
+            }
+        "params": {},
+        "formError": {},
+        "errorCode": 0,
+        "message": "",
+    
+    }
+
+    """
+    
+    device_id = request.POST.get("device_id")
+    data = []
+    f_tbegin = request.POST.get('begin')
+    f_tend = request.POST.get('end')
+
+    try:
+        device = MongoDevice.objects.get(device_id=device_id)
+        device_expire = device.device_expire
+        device_expire_time = device.device_expire_time
+    except:
+        raise PortError('device_id',"暂无此设备")
+    
+    qxz_list = QXZdata_New.objects.filter(device_id=device_id)
+    
+    myuser_type = request.user_type
+    if not myuser_type == 1 and not myuser_type == 5:
+        if f_tbegin and int(f_tend) > int(device_expire_time):
+            f_tend = device_expire_time
+    if f_tbegin and f_tend:
+        qxz_list =qxz_list.filter(uptime__range=(int(f_tbegin),int(f_tend))).order_by('-id')
+
+    conf = {}
+    for i in qxz_list:
+        data.append({"dat":{"e1":i.e1,"e2":i.e2,"e3":i.e3,"e4":i.e4,"e5":i.e5,
+                "e6":i.e6,"e7":i.e7,"e8":i.e8,"e9":i.e9,"e10":i.e10,
+                "e11":i.e11,"e12":i.e12,"e13":i.e13,"e14":i.e14,
+                "e15":i.e15,"e16":i.e16,"e17":i.e17,"e18":i.e18,
+                "e19":i.e19,"e20":i.e20,"e21":i.e21,"e22":i.e22,
+                "e23":i.e23,"e24":i.e24,"e25":i.e25,"e26":i.e26,
+                "e27":i.e27,"e28":i.e28,"e29":i.e29,"e30":i.e30},
+                "time":i.uptime})
+
+    try:
+        x = MongoQXZ_Conf.objects.get(device_id=device_id)
+        conf = {"e1":x.e1,"e2":x.e2,"e3":x.e3,"e4":x.e4,"e5":x.e5,
+                "e6":x.e6,"e7":x.e7,"e8":x.e8,"e9":x.e9,"e10":x.e10,
+                "e11":x.e11,"e12":x.e12,"e13":x.e13,"e14":x.e14,
+                "e15":x.e15,"e16":x.e16,"e17":x.e17,"e18":x.e18,
+                "e19":x.e19,"e20":x.e20,"e21":x.e21,"e22":x.e22,
+                "e23":x.e23,"e24":x.e24,"e25":x.e25,"e26":x.e26,
+                "e27":x.e27,"e28":x.e28,"e29":x.e29,"e30":x.e30}
+    except:
+        conf = {}
+
+    data1 = {"data":data,"conf":conf}
+    return data1

+ 5 - 0
smartfarming/apps.py

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

BIN
smartfarming/middleware/__pycache__/response.cpython-36.pyc


+ 71 - 0
smartfarming/middleware/response.py

@@ -0,0 +1,71 @@
+# coding:utf-8
+import logging
+import json
+from django.conf import settings
+from django.http.response import JsonResponse, HttpResponse
+from rest_framework.response import Response
+from rest_framework.exceptions import ErrorDetail
+from django.utils.deprecation import MiddlewareMixin
+
+logger = logging.getLogger('myapp')  # 获取自定义日志器
+
+
+class ResponseMiddleware:
+    def __init__(self, get_response):
+        self.get_response = get_response
+
+    def __call__(self, request):
+        response = self.get_response(request)
+        if isinstance(response, JsonResponse):
+            return response
+        status_code = response.status_code
+        rsp_data = response.data
+        if status_code == 200:
+            if not rsp_data:
+                rsp_data = {}
+            data = rsp_data
+            if 'page_size' not in rsp_data:
+                data = {'items': rsp_data}
+            response = JsonResponse(status=status_code, data={
+                'msg': '成功',
+                'code': 0,
+                'data': data
+            })
+        elif 400 <= status_code < 500:
+            if status_code in [403, 401]:
+                response = JsonResponse(
+                    status=200, 
+                    data={
+                        'msg': "无权限访问",
+                        'code': 403,
+                        'data': {}
+                        }
+                    )
+            elif status_code == 404:
+                response = JsonResponse(
+                    status=200, 
+                    data={
+                    'msg': "数据不存在",
+                    'code': 400,
+                    'data': {}
+                })
+            elif isinstance(rsp_data, dict):
+                if 'msg' in rsp_data:
+                    response = JsonResponse(
+                        status=200, 
+                        data={
+                        'msg': rsp_data['msg'],
+                        'code': 400,
+                        'data': {}
+                    })
+            else:
+                response = JsonResponse(
+                        status=200, 
+                        data={
+                        'msg': '其它错误',
+                        'code': 400,
+                        'data': {}
+                    })
+        return response
+
+

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1969 - 0
smartfarming/migrations/0001_initial.py


+ 0 - 0
smartfarming/migrations/__init__.py


BIN
smartfarming/migrations/__pycache__/0001_initial.cpython-36.pyc


BIN
smartfarming/migrations/__pycache__/__init__.cpython-36.pyc


+ 13 - 0
smartfarming/models/__init__.py

@@ -0,0 +1,13 @@
+from smartfarming.models.ascend import *
+from smartfarming.models.camera import *
+from smartfarming.models.device import *
+from smartfarming.models.green_house import *
+from smartfarming.models.nl_xy import *
+from smartfarming.models.pest_count import *
+from smartfarming.models.pests_bank import *
+from smartfarming.models.projection_screen import *
+from smartfarming.models.sf import *
+from smartfarming.models.sim_card import *
+from smartfarming.models.user import *
+from smartfarming.models.weather import *
+from smartfarming.models.worm_forecast import *

BIN
smartfarming/models/__pycache__/__init__.cpython-36.pyc


BIN
smartfarming/models/__pycache__/agriculture.cpython-36.pyc


BIN
smartfarming/models/__pycache__/ascend.cpython-36.pyc


BIN
smartfarming/models/__pycache__/camera.cpython-36.pyc


BIN
smartfarming/models/__pycache__/device.cpython-36.pyc


+ 0 - 0
smartfarming/models/__pycache__/green_house.cpython-36.pyc


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels