123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import base64
- import time
- import itsdangerous
- import requests
- import logging
- from django.conf import settings
- from apps.web.api.ft_north.models import FengTuTechnologyNorther
- from apps.web.constant import DeviceOnlineStatus
- from apps.web.device.models import Device, Group
- from apps.web.api.ft_north.constant import PORT_WORK_STATUS
- from apps.web.api.utils import bd09_to_gcj02, get_coordinates_and_nums
- logger = logging.getLogger(__name__)
- def get_coding_info_by_device(devNo):
- dev = Device.get_dev(devNo)
- box = dev.deviceAdapter
- try:
- devStatusDict = box.get_port_status()
- except:
- return
- codingInfos = list()
- for k,v in devStatusDict.items():
- codingInfo = {}
- codingInfo['coding'] = k
- if v['status'] != PORT_WORK_STATUS.PORT_WORKING and v['status'] != PORT_WORK_STATUS.PORT_WORKING:
- v['status'] = PORT_WORK_STATUS.PORT_FAULT
- codingInfo['status'] = v['status']
- codingInfos.append(codingInfo)
- return codingInfos
- def get_coding_info(devNo):
- """
- 获取端口状态,先找缓存,缓存中没有直接从设备里拿
- :param devNo:
- :return:
- """
- ctrInfo = Device.get_dev_control_cache(devNo)
- codingInfo = []
- if 'allPorts' not in ctrInfo:
- ctrInfo = get_coding_info_by_device(devNo)
- if ctrInfo:
- return ctrInfo
- else:
- return [{"coding":"0","status":0}]
- else:
- allPorts = ctrInfo.get('allPorts', 10)
- # allPorts 有的时候会为0, 这个时候强制设置为10
- if allPorts == 0:
- allPorts = 10
- for ii in range(allPorts):
- statusDict = {}
- tempDict = ctrInfo.get(str(ii + 1), {})
- if tempDict.has_key('status'):
- statusDict['coding'] = str(ii + 1)
- statusDict['status'] = tempDict.get('status')
- elif tempDict.has_key('isStart'):
- if tempDict['isStart']:
- statusDict['coding'] = str(ii + 1)
- statusDict['status'] = PORT_WORK_STATUS.PORT_WORKING
- else:
- statusDict['coding'] = str(ii + 1)
- statusDict['status'] = PORT_WORK_STATUS.PORT_IDLE
- else:
- statusDict['coding'] = str(ii + 1)
- statusDict['status'] = PORT_WORK_STATUS.PORT_IDLE
- codingInfo.append(statusDict)
- return codingInfo
- def get_device_status(devNo):
- """
- 获取设备状态
- :param devNo:
- :return:
- """
- dev = Device.get_dev(devNo)
- devOnline = dev.online
- if devOnline == DeviceOnlineStatus.DEV_STATUS_ONLINE:
- devStatus = '1'
- elif devOnline == DeviceOnlineStatus.DEV_STATUS_OFFLINE:
- devStatus = '0'
- else:
- devStatus = '-1'
- return devStatus
- def get_station_Info(groupIds):
- """
- 推送站点信息
- :param groupIds:
- :return:
- """
- stationInfoList = list()
- groups = Group.get_groups_by_group_ids(groupIds)
- for group in groups.values():
- # 获取经纬度 获取设备数量 经纬度使用火星坐标系转换
- lng, lat, count = get_coordinates_and_nums(group.groupId)
- lng, lat = bd09_to_gcj02(lng, lat)
- stationInfoDict = {
- "stationId" : group.groupId, # 厂商站点ID
- "name" : group.groupName, # 充电站名称
- "brand" : "", # 品牌名称
- "longitude" : "{:.6f}".format(float(lng)), # 经度(6位小数),
- "latitude" : "{:.6f}".format(float(lat)), # 维度(6位小数)
- "address" : group.address, # 具体地址
- "socketNumber" : 0, # 设备路数
- "hasRainshed" : "", # 是否有雨棚
- "hasMonitor" : "", # 是否覆盖视频监控
- "fireFacilities" : "", # 是否配置消防设施
- "buildingTime" : group.get('dateTimeAdded').get('val').split(" ")[0], # 建设时间
- "picture" : "", # 站点图片
- "deviceList" : get_dev_info([group.groupId],group), # 站点下的设备列表
- }
- stationInfoList.append(stationInfoDict)
- return stationInfoList
- def get_dev_info(groupIds,group):
- devices = Device.get_devices_by_group(groupIds)
- deviceInfo = list()
- for devNo,devInfo in devices.items():
- devDict = {
- 'stationId':groupIds[0], # 厂商站点ID
- 'deviceNo':devNo, # 设备编号
- 'deviceType':devInfo['devType']["majorDeviceType"], # 设备类型:充电柜、充电桩、桩柜一体、摄像头、烟感、消防器(栓)、喷淋
- 'simCardNo':"", # SIM卡号
- 'wateringPortNum':"", # 浇水口数量
- 'brand':devInfo['devType']["name"], # 品牌名称
- 'useStationInfo':1, # 是否与充电站公用一个位置: 0.否, 1.是
- 'deviceLocation':group.address, # 设备地址,省市区街道+详细地址
- 'longitude':devInfo['lng'], # 径度
- 'latitude':devInfo['lat'], # 纬度
- 'socketNumber':Device.get_dev_control_cache(devNo).get('allPorts'), # 设备路数,充电口数量
- 'buildingYear':devInfo['dateTimeAdded'].split('-')[0] # 建设年份,格式:yyyy
- }
- deviceInfo.append(devDict)
- return deviceInfo
- def send_request(url,mode='POST',**kwargs):
- """
- 主动发送HTTP请求获取数据 密钥及签名
- :return:
- """
- headers = {"Content-Type": "application/json;charset=utf-8"}
- token = kwargs.pop("token", None)
- if token:headers.update({"Authorization": "Basic {}".format(token)})
- timeout = kwargs.pop("timeout", 5)
- data = kwargs
- try:
- if mode == 'POST':
- response = requests.post(url=url, json=data, headers=headers, timeout=timeout)
- else:
- response = requests.get(url=url, headers=headers, timeout=timeout)
- except requests.Timeout:
- return dict()
- except Exception as e:
- logger.exception(e)
- return dict()
- if response.status_code != 200:
- return dict()
- return response.json()
- def get_token(norther):
- # if norther.token and norther.tokenExpiredTime > int(time.time()) * 1000:
- # return norther.token
- timestamp = int(time.time()*1000)
- url = norther.join_url("getToken")
- sign = norther.get_sig(timestamp)
- result = send_request(url,appid=norther.appId,timestamp=timestamp,sign=sign)
- ret = result.get("code")
- logger.info(ret)
- if ret != 200:
- return
- responseJson = result.get("data")
- tokenAvailableTime = responseJson.get("expireTime", 120)
- token = responseJson.get("token", "")
- # 数据库更新
- # norther.update(
- # token=token,
- # tokenExpiredTime=tokenAvailableTime
- # )
- #
- # norther.save()
- return token
- def get_station_Info_manage(groupId):
- """
- 推送站点信息
- :param groupId:
- :return:
- """
- group = Group.get_group(groupId)
- # 获取经纬度 获取设备数量 经纬度使用火星坐标系转换
- lng, lat, count = get_coordinates_and_nums(group.groupId)
- lng, lat = bd09_to_gcj02(lng, lat)
- stationInfoDict = {
- "stationId" : group.groupId, # 厂商站点ID
- "name" : group.groupName, # 充电站名称
- "chargingType":"", # 充电站类型
- "brand":"",
- "longitude":lng,
- "latitude":lat,
- "address":group.address,
- "socketNumber":0,
- "hasRainshed":"",
- "hasMonitor":"",
- "fireFacilities":"",
- "buildingTime":group.get('dateTimeAdded').strftime('%Y-%m-%d'),
- "picture":"",
- }
- return stationInfoDict
- def get_device_info_manage(devNo):
- dev = Device.get_dev(devNo)
- deviceInfo = {
- "stationId":dev["groupId"], # 厂商站点ID
- "deviceNo":devNo, # 设备编号
- "deviceType":dev['devType']["majorDeviceType"], # 设备类型
- "brand":dev['devType']["name"], # 品牌名称
- "deviceLocation":Group.get_group(dev["groupId"]).get("address"), # 设备地址
- "longitude":dev['lng'], # 经度
- "latitude":dev['lat'], # 纬度
- "socketNumber":Device.get_dev_control_cache(devNo).get('allPorts',10), # 设备路数
- }
- return deviceInfo
- def get_alarm_report(devNo,alarmType):
- dev = Device.get_dev(devNo)
- data = {
- "stationId":dev.get('groupId'), # 充电站编号
- "deviceNo" : devNo,
- "codingNo" : "",
- "eventId" : base64.b64encode(dev.get('groupId')+devNo+str(time.time())),
- "outSourceId" : "",
- "alarmType":alarmType
- }
- return data
- def generate_json_token(data, expire=None):
- salt = settings.FENG_TU_TOKEN_SECRET
- its = itsdangerous.TimedJSONWebSignatureSerializer(salt, expire)
- return its.dumps(data)
- def parse_json_token(s, expire=None):
- salt = settings.FENG_TU_TOKEN_SECRET
- its = itsdangerous.TimedJSONWebSignatureSerializer(salt, expire)
- try:
- result = its.loads(s)
- except itsdangerous.BadData:
- return dict()
- return result
- def batchStationInfoReport(groupIds):
- """
- 主动推送站点信息
- :param groupIds:
- :return:
- """
- try:
- north = FengTuTechnologyNorther.objects.filter().first()
- data = get_station_Info(groupIds)
- url = north.join_url("batchStationInfo")
- token = get_token(north)
- return send_request(url=url, token=token, stationInfoList=data)
- except Exception as e:
- logger.exception(e)
- def addStationReport(groupId):
- try:
- north = FengTuTechnologyNorther.objects.filter().first()
- data = get_station_Info_manage(groupId)
- url = north.join_url("station/add")
- token = get_token(north)
- return send_request(url=url, token=token, **data)
- except Exception as e:
- logger.exception(e)
- def deleteStationReport(groupId):
- try:
- north = FengTuTechnologyNorther.objects.filter().first()
- data = groupId
- url = north.join_url("station/delete/{}".format(data))
- token = get_token(north)
- return send_request(url=url, mode='GET', token=token)
- except Exception as e:
- logger.exception(e)
- def updateStationReport(groupId):
- try:
- north = FengTuTechnologyNorther.objects.filter().first()
- data = get_station_Info_manage(groupId)
- url = north.join_url("station/update")
- token = get_token(north)
- return send_request(url=url, token=token, **data)
- except Exception as e:
- logger.exception(e)
- def addDeviceReport(devNo):
- try:
- north = FengTuTechnologyNorther.objects.filter().first()
- data = get_device_info_manage(devNo)
- url = north.join_url("device/add")
- token = get_token(north)
- return send_request(url=url, token=token, **data)
- except Exception as e:
- logger.exception(e)
- def deleteDeviceReport(devNo):
- try:
- north = FengTuTechnologyNorther.objects.filter().first()
- groupId = Device.get_dev(devNo).get("groupId")
- url = north.join_url("device/delete/{}/{}".format(groupId,devNo))
- token = get_token(north)
- return send_request(url=url, mode='GET', token=token)
- except Exception as e:
- logger.exception(e)
- def updateDeviceReport(devNo):
- try:
- north = FengTuTechnologyNorther.objects.filter().first()
- data = get_device_info_manage(devNo)
- url = north.join_url("device/update")
- token = get_token(north)
- return send_request(url=url, token=token, **data)
- except Exception as e:
- logger.exception(e)
- def devHeartbeatReport(devNo):
- try:
- data = {
- "deviceNo":devNo,
- "deviceStatus":get_device_status(devNo),
- "codings":get_coding_info(devNo),
- "eventId": base64.b64encode(devNo+str(time.time()))
- }
- north = FengTuTechnologyNorther.objects.filter().first()
- url = north.join_url("device/heartbeat")
- token = get_token(north)
- send_request(url=url, token=token, **data)
- except Exception as e:
- logger.exception(e)
- def alarmReport(devNo,faultName):
- try:
- north = FengTuTechnologyNorther.objects.filter().first()
- data = get_alarm_report(devNo,faultName)
- url = north.join_url("alarm")
- token = get_token(north)
- send_request(url=url, token=token, **data)
- except Exception as e:
- logger.exception(e)
|