first
This commit is contained in:
commit
5387def012
|
@ -0,0 +1,3 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
|
@ -0,0 +1,33 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<value>
|
||||
<list size="9">
|
||||
<item index="0" class="java.lang.String" itemvalue="transformers" />
|
||||
<item index="1" class="java.lang.String" itemvalue="fastapi" />
|
||||
<item index="2" class="java.lang.String" itemvalue="typing_extensions" />
|
||||
<item index="3" class="java.lang.String" itemvalue="tokenizers" />
|
||||
<item index="4" class="java.lang.String" itemvalue="sentencepiece" />
|
||||
<item index="5" class="java.lang.String" itemvalue="streamlit" />
|
||||
<item index="6" class="java.lang.String" itemvalue="torch" />
|
||||
<item index="7" class="java.lang.String" itemvalue="huggingface_hub" />
|
||||
<item index="8" class="java.lang.String" itemvalue="starlette" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||
<option name="ignoredErrors">
|
||||
<list>
|
||||
<option value="N801" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="ReassignedToPlainText" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="ShellCheck" enabled="true" level="ERROR" enabled_by_default="true">
|
||||
<shellcheck_settings value="SC2239" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
|
@ -0,0 +1,6 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="jdk" jdkName="chatchat" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.8" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="chatchat" project-jdk-type="Python SDK" />
|
||||
</project>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/lot_manager2.iml" filepath="$PROJECT_DIR$/.idea/lot_manager2.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -0,0 +1,48 @@
|
|||
import json
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from tool import push_stream, close_stream, update, exec_sh
|
||||
|
||||
|
||||
class MQTT:
|
||||
def on_connect(self, client, userdata, flags, rc):
|
||||
if rc == 0:
|
||||
client.subscribe('lot_mqtt')
|
||||
|
||||
# Message receiving callback
|
||||
def on_message(self, client, userdata, msg):
|
||||
data = json.loads(msg.payload.decode('utf-8'))["msg"]
|
||||
if data == "push_stream":
|
||||
# 启动推流视频
|
||||
push_stream()
|
||||
client.publish('success', payload='push_stream success', qos=0)
|
||||
elif data == "close_stream":
|
||||
# 关闭推流视频
|
||||
close_stream()
|
||||
client.publish('success', payload='close_stream success', qos=0)
|
||||
elif data == "exec":
|
||||
# 执行命令
|
||||
exec_sh(msg)
|
||||
client.publish('success', payload='exec_sh success', qos=0)
|
||||
elif data == "update":
|
||||
# git更新项目和配置文件
|
||||
update()
|
||||
client.publish('success', payload='update success', qos=0)
|
||||
else:
|
||||
client.publish('error', payload='No Such Type', qos=0)
|
||||
|
||||
def __init__(self):
|
||||
self.client = mqtt.Client()
|
||||
self.client.username_pw_set("demo", "123456")
|
||||
# Specify callback function
|
||||
self.client.on_connect = self.on_connect
|
||||
self.client.on_message = self.on_message
|
||||
# Establish a connection
|
||||
self.client.connect('ceshi-mqtt.lihaink.cn', 1883)
|
||||
# Publish a message
|
||||
self.client.loop_forever(retry_first_connection=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
mq = MQTT()
|
|
@ -0,0 +1,33 @@
|
|||
import os
|
||||
import subprocess
|
||||
|
||||
import uvicorn
|
||||
from db.models.base import BaseResponse
|
||||
from db.models.log_data_model import LOT_DATA, LOT_DATA_MODEL
|
||||
from db.repository import add_kb_to_db, get_kb_detail, get_kb_detail_by_time, delete_kb_detail_by_time
|
||||
|
||||
from fastapi import FastAPI
|
||||
|
||||
|
||||
def add(data: LOT_DATA):
|
||||
try:
|
||||
add_kb_to_db(data)
|
||||
return BaseResponse()
|
||||
except Exception as e:
|
||||
return BaseResponse(code=500, msg=e)
|
||||
|
||||
|
||||
def delete(start_time, end_time):
|
||||
try:
|
||||
delete_kb_detail_by_time(start_time, end_time)
|
||||
return BaseResponse()
|
||||
except Exception as e:
|
||||
return BaseResponse(code=500, msg=e)
|
||||
|
||||
|
||||
def get_data():
|
||||
try:
|
||||
data = get_kb_detail()
|
||||
return BaseResponse(data=data)
|
||||
except Exception as e:
|
||||
return BaseResponse(code=404, msg=e)
|
|
@ -0,0 +1,413 @@
|
|||
# cd demo/ceshi-1/
|
||||
# python ceshi.py
|
||||
|
||||
import serial
|
||||
import time
|
||||
import struct
|
||||
import json
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from api import add
|
||||
from db.models.log_data_model import LOT_DATA
|
||||
|
||||
|
||||
def hex_to_float(hex_str):
|
||||
hex_int = int(hex_str, 16)
|
||||
return struct.unpack('!f', struct.pack('!I', hex_int))[0]
|
||||
|
||||
|
||||
def print_json(data):
|
||||
print(json.dumps(data, sort_keys=True, indent=4, separators=(', ', ': '), ensure_ascii=False))
|
||||
|
||||
|
||||
def run_with_client(client):
|
||||
temp_send = '06 03 01 F4 00 02 85 B2 ' # 温湿度查询指令
|
||||
co2_send = '06 03 01 F7 00 02 75 B2 ' # 二氧化碳查询指令
|
||||
pressure_send = '06 03 01 F9 00 02 14 71 ' # 气压查询指令
|
||||
sun_send = '06 03 01 FA 00 02 E4 71 ' # 光照查询指令
|
||||
|
||||
soil_send = '02 03 00 00 00 04 44 3A' # 土壤查询指令
|
||||
danlinjia_send = '02 03 00 04 00 03 44 39' # 氮磷钾查询指令
|
||||
|
||||
rainfall_send = '03 03 00 00 00 01 85 E8' # 雨量查询指令
|
||||
|
||||
windspeed_send = '04 03 00 00 00 02 C4 5E' # 风速查询指令
|
||||
winddirection_send = '05 03 00 00 00 02 C5 8F' # 风向查询指令
|
||||
|
||||
ser = serial.Serial("/dev/ttyS2", 9600)
|
||||
|
||||
# 发送的数据转为2进制b'\x01\x03\x00\x00\x00\x02\xc4\x0b'
|
||||
temp_send = bytes.fromhex(temp_send)
|
||||
co2_send = bytes.fromhex(co2_send)
|
||||
pressure_send = bytes.fromhex(pressure_send)
|
||||
sun_send = bytes.fromhex(sun_send)
|
||||
soil_send = bytes.fromhex(soil_send)
|
||||
danlinjia_send = bytes.fromhex(danlinjia_send)
|
||||
rainfall_send = bytes.fromhex(rainfall_send)
|
||||
windspeed_send = bytes.fromhex(windspeed_send)
|
||||
winddirection_send = bytes.fromhex(winddirection_send)
|
||||
|
||||
while True:
|
||||
# if ser.is_open:
|
||||
ser.write(temp_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
tempbuffer_data = ser.in_waiting
|
||||
if tempbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(tempbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# 对返回的数据进行解析,获取温度和湿度数据
|
||||
airtemp_data = int(return_data_hex[6:10], 16) / 10
|
||||
airhumi_data = int(return_data_hex[10:14], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(co2_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
co2buffer_data = ser.in_waiting
|
||||
if co2buffer_data:
|
||||
return_data = ser.read(co2buffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# 对返回的数据进行解析,获取温度和湿度数据
|
||||
co2_data = int(return_data_hex[6:10], 16)
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(pressure_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
pressurebuffer_data = ser.in_waiting
|
||||
if pressurebuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(pressurebuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# 对返回的数据进行解析,获取温度和湿度数据
|
||||
pressure_data = int(return_data_hex[6:10], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(sun_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
sunbuffer_data = ser.in_waiting
|
||||
if sunbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(sunbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
sun_data = int(return_data_hex[6:14], 16)
|
||||
time.sleep(5)
|
||||
|
||||
# print('send soil directives')
|
||||
ser.write(soil_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
soilbuffer_data = ser.in_waiting
|
||||
# print(buffer_data, 'buffer_data')
|
||||
if soilbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(soilbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# 对返回的数据进行解析,获取温度和湿度数据
|
||||
humidity_data = int(return_data_hex[6:10], 16) / 10
|
||||
temperature_data = int(return_data_hex[10:14], 16) / 10
|
||||
electrical_data = int(return_data_hex[14:18], 16) / 10
|
||||
PH_data = int(return_data_hex[18:22], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
# print('send danlinjia directives')
|
||||
ser.write(danlinjia_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
danlinjiabuffer_data = ser.in_waiting
|
||||
# print(buffer_data, 'buffer_data')
|
||||
if danlinjiabuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(danlinjiabuffer_data)
|
||||
# print('返回的数据2进制:', return_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# # 对返回的数据进行解析,获取温度和湿度数据
|
||||
dan_data = int(return_data_hex[6:10], 16) / 10
|
||||
lin_data = int(return_data_hex[10:14], 16) / 10
|
||||
jia_data = int(return_data_hex[14:18], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
# print('send rainfall directives')
|
||||
ser.write(rainfall_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
rainfallbuffer_data = ser.in_waiting
|
||||
# print(buffer_data, 'buffer_data')
|
||||
if rainfallbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(rainfallbuffer_data)
|
||||
# print('返回的数据2进制:', return_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# print('返回的数据转换为16进制:', return_data_hex)
|
||||
# # 对返回的数据进行解析,获取温度和湿度数据
|
||||
# print("当前雨量值为:", int(return_data_hex[6:10], 16)/10)#单位mm
|
||||
rainfall_data = int(return_data_hex[6:10], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(windspeed_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
windspeedbuffer_data = ser.in_waiting
|
||||
# print(buffer_data, 'buffer_data')
|
||||
if windspeedbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(windspeedbuffer_data)
|
||||
# print('返回的数据2进制:', return_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# print('返回的数据转换为16进制:', return_data_hex)
|
||||
# print("当前风速为:", int(return_data_hex[6:10], 16)/10)#单位mm
|
||||
speedwind_data = int(return_data_hex[6:10], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
# print('send winddirection directives')
|
||||
ser.write(winddirection_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
winddirectionbuffer_data = ser.in_waiting
|
||||
# print(buffer_data, 'buffer_data')
|
||||
if winddirectionbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(winddirectionbuffer_data)
|
||||
# print('返回的数据2进制:', return_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# print('返回的数据转换为16进制:', return_data_hex)
|
||||
# print("当前风向为:", int(return_data_hex[10:14], 16))#单位mm
|
||||
winddirection_data = int(return_data_hex[10:14], 16)
|
||||
time.sleep(5)
|
||||
# print('{"name":"%d","name1":"%d"}', 123,456)
|
||||
# data = [{'ngvhgv': airtemp_data}, {'nvjgvjvj':airhumi_data}]
|
||||
data = {'ambient_temperature': airtemp_data,
|
||||
'ambient_humidity': airhumi_data,
|
||||
'carbon_dioxide': co2_data,
|
||||
'ambient_air_pressure': pressure_data,
|
||||
'ambient_lighting': sun_data,
|
||||
'soil_moisture': humidity_data,
|
||||
'soil_temperature': temperature_data,
|
||||
'soil_conductivity': electrical_data,
|
||||
'soil_PH': PH_data,
|
||||
'soil_potassium_phosphate_nitrogen': dan_data,
|
||||
'soil_potassium_phosphate_phosphorus': lin_data,
|
||||
'soil_potassium_phosphate_potassium': jia_data,
|
||||
'rainfall': rainfall_data,
|
||||
'wind_speed': speedwind_data,
|
||||
'wind_direction': winddirection_data,
|
||||
'create_time': int(time.time())
|
||||
}
|
||||
t = LOT_DATA(**data)
|
||||
# TODO 判断数据是否正常
|
||||
# 发送给服务器
|
||||
client.publish('demo', payload=json.dumps(data, ensure_ascii=False), qos=0)
|
||||
add(t)
|
||||
|
||||
|
||||
def run_no_client():
|
||||
temp_send = '06 03 01 F4 00 02 85 B2 ' # 温湿度查询指令
|
||||
co2_send = '06 03 01 F7 00 02 75 B2 ' # 二氧化碳查询指令
|
||||
pressure_send = '06 03 01 F9 00 02 14 71 ' # 气压查询指令
|
||||
sun_send = '06 03 01 FA 00 02 E4 71 ' # 光照查询指令
|
||||
|
||||
soil_send = '02 03 00 00 00 04 44 3A' # 土壤查询指令
|
||||
danlinjia_send = '02 03 00 04 00 03 44 39' # 氮磷钾查询指令
|
||||
|
||||
rainfall_send = '03 03 00 00 00 01 85 E8' # 雨量查询指令
|
||||
|
||||
windspeed_send = '04 03 00 00 00 02 C4 5E' # 风速查询指令
|
||||
winddirection_send = '05 03 00 00 00 02 C5 8F' # 风向查询指令
|
||||
|
||||
ser = serial.Serial("/dev/ttyS2", 9600)
|
||||
|
||||
# 发送的数据转为2进制b'\x01\x03\x00\x00\x00\x02\xc4\x0b'
|
||||
temp_send = bytes.fromhex(temp_send)
|
||||
co2_send = bytes.fromhex(co2_send)
|
||||
pressure_send = bytes.fromhex(pressure_send)
|
||||
sun_send = bytes.fromhex(sun_send)
|
||||
soil_send = bytes.fromhex(soil_send)
|
||||
danlinjia_send = bytes.fromhex(danlinjia_send)
|
||||
rainfall_send = bytes.fromhex(rainfall_send)
|
||||
windspeed_send = bytes.fromhex(windspeed_send)
|
||||
winddirection_send = bytes.fromhex(winddirection_send)
|
||||
|
||||
while True:
|
||||
ser.write(temp_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
tempbuffer_data = ser.in_waiting
|
||||
if tempbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(tempbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# 对返回的数据进行解析,获取温度和湿度数据
|
||||
airtemp_data = int(return_data_hex[6:10], 16) / 10
|
||||
airhumi_data = int(return_data_hex[10:14], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(co2_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
co2buffer_data = ser.in_waiting
|
||||
if co2buffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(co2buffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# 对返回的数据进行解析,获取温度和湿度数据
|
||||
co2_data = int(return_data_hex[6:10], 16)
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(pressure_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
pressurebuffer_data = ser.in_waiting
|
||||
if pressurebuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(pressurebuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# 对返回的数据进行解析,获取温度和湿度数据
|
||||
pressure_data = int(return_data_hex[6:10], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(sun_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
sunbuffer_data = ser.in_waiting
|
||||
if sunbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(sunbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
sun_data = int(return_data_hex[6:14], 16)
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(soil_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
soilbuffer_data = ser.in_waiting
|
||||
if soilbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(soilbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# 对返回的数据进行解析,获取温度和湿度数据
|
||||
humidity_data = int(return_data_hex[6:10], 16) / 10
|
||||
temperature_data = int(return_data_hex[10:14], 16) / 10
|
||||
electrical_data = int(return_data_hex[14:18], 16) / 10
|
||||
PH_data = int(return_data_hex[18:22], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(danlinjia_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
danlinjiabuffer_data = ser.in_waiting
|
||||
if danlinjiabuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(danlinjiabuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# # 对返回的数据进行解析,获取温度和湿度数据
|
||||
dan_data = int(return_data_hex[6:10], 16) / 10
|
||||
lin_data = int(return_data_hex[10:14], 16) / 10
|
||||
jia_data = int(return_data_hex[14:18], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(rainfall_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
rainfallbuffer_data = ser.in_waiting
|
||||
if rainfallbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(rainfallbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
# # 对返回的数据进行解析,获取温度和湿度数据
|
||||
rainfall_data = int(return_data_hex[6:10], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(windspeed_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
windspeedbuffer_data = ser.in_waiting
|
||||
if windspeedbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(windspeedbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
speedwind_data = int(return_data_hex[6:10], 16) / 10
|
||||
time.sleep(5)
|
||||
|
||||
ser.write(winddirection_send)
|
||||
time.sleep(1)
|
||||
# 获取返回的缓冲data,获取的是buffer_data的长度 9
|
||||
winddirectionbuffer_data = ser.in_waiting
|
||||
if winddirectionbuffer_data:
|
||||
# 返回的数据为2进制:b'\x01\x03\x04\x01\x08\x022\xfa\xb8'
|
||||
return_data = ser.read(winddirectionbuffer_data)
|
||||
# 二进制转换为16进制:010304010802307b79
|
||||
return_data_hex = str(return_data.hex())
|
||||
winddirection_data = int(return_data_hex[10:14], 16)
|
||||
time.sleep(5)
|
||||
data = {'ambient_temperature': airtemp_data,
|
||||
'ambient_humidity': airhumi_data,
|
||||
'carbon_dioxide': co2_data,
|
||||
'ambient_air_pressure': pressure_data,
|
||||
'ambient_lighting': sun_data,
|
||||
'soil_moisture': humidity_data,
|
||||
'soil_temperature': temperature_data,
|
||||
'soil_conductivity': electrical_data,
|
||||
'soil_PH': PH_data,
|
||||
'soil_potassium_phosphate_nitrogen': dan_data,
|
||||
'soil_potassium_phosphate_phosphorus': lin_data,
|
||||
'soil_potassium_phosphate_potassium': jia_data,
|
||||
'rainfall': rainfall_data,
|
||||
'wind_speed': speedwind_data,
|
||||
'wind_direction': winddirection_data}
|
||||
data = LOT_DATA(**data, create_time=int(time.time()))
|
||||
# TODO 判断数据是否正常
|
||||
add(data)
|
||||
|
||||
|
||||
class UPLOAD:
|
||||
def __init__(self):
|
||||
self.times = 3
|
||||
self.client = mqtt.Client(transport="websockets")
|
||||
self.client.username_pw_set("demo", "123456")
|
||||
# Specify callback function
|
||||
self.client.on_connect = self.on_connect
|
||||
# Establish a connection
|
||||
self.client.connect('ceshi-mqtt.lihaink.cn', 8083)
|
||||
# Publish a message
|
||||
self.client.loop_forever()
|
||||
|
||||
def on_connect(self, client, userdata, flags, rc):
|
||||
from threading import Thread
|
||||
if rc == 0:
|
||||
print("连接成功,执行数据推送和本地存储")
|
||||
nt1 = Thread(target=self.t1)
|
||||
nt1.start()
|
||||
else:
|
||||
if self.times != 0:
|
||||
self.times -= 1
|
||||
client.reconnect()
|
||||
else:
|
||||
print("3次失败,执行本地存储")
|
||||
nt2 = Thread(target=self.t2)
|
||||
nt2.start()
|
||||
|
||||
def t2(self):
|
||||
run_no_client()
|
||||
|
||||
def t1(self):
|
||||
run_with_client(self.client)
|
|
@ -0,0 +1,13 @@
|
|||
[program:data_upload]
|
||||
directory=/home/pi/lot_manager
|
||||
command=/usr/bin/python ceshi.py
|
||||
user=pi
|
||||
;是否随开机自启 或者reload自启动
|
||||
autostart=true
|
||||
;失败重启
|
||||
autorestart=true
|
||||
;重启次数
|
||||
restart_times=3
|
||||
redirect_stderr=true
|
||||
stopsignal=TERM
|
||||
stopasgroup=True
|
|
@ -0,0 +1,9 @@
|
|||
[program:push_stream]
|
||||
directory=/home/pi/lot_manager
|
||||
command=/usr/bin/ffmpeg -rtsp_transport tcp -re -i rtsp://admin:123456@192.168.0.226:554/mpeg4 -c:v copy -c:a aac -preset ultrafast -r 20 -flvflags no_duration_filesize -f rtsp -rtsp_transport tcp rstp://192.168.1.27:554/live/test
|
||||
user=pi
|
||||
autostart=false
|
||||
autorestart=true
|
||||
redirect_stderr=true
|
||||
stopsignal=TERM
|
||||
stopasgroup=True
|
|
@ -0,0 +1,13 @@
|
|||
[program:test]
|
||||
directory=/home/pi/lot_manager
|
||||
command=/usr/bin/python test.py
|
||||
user=pi
|
||||
;是否随开机自启 或者reload自启动
|
||||
autostart=false
|
||||
;失败重启
|
||||
autorestart=true
|
||||
;重启次数
|
||||
restart_times=3
|
||||
redirect_stderr=true
|
||||
stopsignal=TERM
|
||||
stopasgroup=True
|
|
@ -0,0 +1,19 @@
|
|||
import os
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
import json
|
||||
KB_ROOT_PATH = "./"
|
||||
DB_ROOT_PATH = os.path.join(KB_ROOT_PATH, "lot_data.db")
|
||||
SQLALCHEMY_DATABASE_URI = f"sqlite:///{DB_ROOT_PATH}"
|
||||
|
||||
engine = create_engine(
|
||||
SQLALCHEMY_DATABASE_URI,
|
||||
json_serializer=lambda obj: json.dumps(obj, ensure_ascii=False),
|
||||
)
|
||||
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
Base: DeclarativeMeta = declarative_base()
|
|
@ -0,0 +1,25 @@
|
|||
from datetime import datetime
|
||||
from typing import Any, List
|
||||
|
||||
import pydantic
|
||||
from pydantic import BaseModel
|
||||
from sqlalchemy import Column, DateTime, String, Integer
|
||||
|
||||
from db.models.log_data_model import LOT_DATA_MODEL, LOT_DATA
|
||||
|
||||
|
||||
class BaseResponse(BaseModel):
|
||||
code: int = 200
|
||||
msg: str = "success"
|
||||
data: Any = None
|
||||
|
||||
|
||||
class BaseModel:
|
||||
"""
|
||||
基础模型
|
||||
"""
|
||||
id = Column(Integer, primary_key=True, index=True, comment="主键ID")
|
||||
create_time = Column(DateTime, default=datetime.utcnow, comment="创建时间")
|
||||
update_time = Column(DateTime, default=None, onupdate=datetime.utcnow, comment="更新时间")
|
||||
create_by = Column(String, default=None, comment="创建者")
|
||||
update_by = Column(String, default=None, comment="更新者")
|
|
@ -0,0 +1,49 @@
|
|||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy import *
|
||||
from db.base import Base
|
||||
|
||||
|
||||
class LOT_DATA(BaseModel):
|
||||
create_time: int = Field(None, description='创建时间(时间戳) ')
|
||||
wind_speed: float = Field(None, description='风速:(0到30)m/s ')
|
||||
wind_direction: float = Field(None, description='风向:0~360°')
|
||||
ambient_temperature: float = Field(None, description='环境温度:℃')
|
||||
ambient_humidity: float = Field(None, description='环境湿度:%RH')
|
||||
carbon_dioxide: float = Field(None, description='二氧化碳:0~5000ppm')
|
||||
ambient_air_pressure: float = Field(None, description='环境气压:0~120KPa')
|
||||
rainfall: float = Field(None, description='雨量:mm')
|
||||
ambient_lighting: float = Field(None, description='环境光照:0-65535Lux;0-20万Lux')
|
||||
soil_temperature: float = Field(None, description='土壤温度:-40~80℃')
|
||||
soil_moisture: float = Field(None, description='土壤湿度:0-100%RH')
|
||||
soil_conductivity: float = Field(None, description='土壤电导率:0-20000μS/cm')
|
||||
soil_PH: float = Field(None, description='土壤PH:3~9PH')
|
||||
soil_potassium_phosphate_nitrogen: float = Field(None, description='土壤磷酸钾:氮的标准值在140-225mg/kg')
|
||||
soil_potassium_phosphate_phosphorus: float = Field(None, description='土壤磷酸钾:磷的标准值在57-100mg/kg,')
|
||||
soil_potassium_phosphate_potassium: float = Field(None, description='土壤磷酸钾:钾的标准值在106-150mg/kg')
|
||||
|
||||
|
||||
class LOT_DATA_MODEL(Base):
|
||||
"""
|
||||
物联网数据模型
|
||||
"""
|
||||
__tablename__ = 'LOT_DATA_MODEL'
|
||||
id = Column(Integer, primary_key=True, autoincrement=True, comment='ID')
|
||||
create_time = Column(Integer, comment="创建时间")
|
||||
wind_speed = Column(Float, comment='风速:(0到30)m/s ')
|
||||
wind_direction = Column(Float, comment='风向:0~360°')
|
||||
ambient_temperature = Column(Float, comment='环境温度:℃')
|
||||
ambient_humidity = Column(Float, comment='环境湿度:%RH')
|
||||
carbon_dioxide = Column(Float, comment='二氧化碳:0~5000ppm')
|
||||
ambient_air_pressure = Column(Float, comment='环境气压:0~120KPa')
|
||||
rainfall = Column(Float, comment='雨量:mm')
|
||||
ambient_lighting = Column(Float, comment='环境光照:0-65535Lux;0-20万Lux')
|
||||
soil_temperature = Column(Float, comment='土壤温度:-40~80℃')
|
||||
soil_moisture = Column(Float, comment='土壤湿度:0-100%RH')
|
||||
soil_conductivity = Column(Float, comment='土壤电导率:0-20000μS/cm')
|
||||
soil_PH = Column(Float, comment='土壤PH:3~9PH')
|
||||
soil_potassium_phosphate_nitrogen = Column(Float, comment='土壤磷酸钾:氮的标准值在140-225mg/kg')
|
||||
soil_potassium_phosphate_phosphorus = Column(Float, comment='土壤磷酸钾:磷的标准值在57-100mg/kg,')
|
||||
soil_potassium_phosphate_potassium = Column(Float, comment='土壤磷酸钾:钾的标准值在106-150mg/kg')
|
||||
|
||||
def __repr__(self):
|
||||
return f"LOT_DATA_MODEL(id={self.id}, wind_speed={self.wind_speed}, wind_direction={self.wind_direction}, ambient_temperature={self.ambient_temperature}, ambient_humidity={self.ambient_humidity}, carbon_dioxide={self.carbon_dioxide}, ambient_air_pressure={self.ambient_air_pressure}, rainfall={self.rainfall}, ambient_lighting={self.ambient_lighting}, soil_temperature={self.soil_temperature}, soil_moisture={self.soil_moisture}, soil_conductivity={self.soil_conductivity}, Soil_PH={self.soil_PH}, soil_potassium_phosphate_nitrogen={self.soil_potassium_phosphate_nitrogen}, soil_potassium_phosphate_phosphorus={self.soil_potassium_phosphate_phosphorus}, soil_potassium_phosphate_potassium={self.soil_potassium_phosphate_potassium})"
|
|
@ -0,0 +1 @@
|
|||
from .lot_data_repository import *
|
|
@ -0,0 +1,51 @@
|
|||
import time
|
||||
|
||||
from db.models.log_data_model import LOT_DATA_MODEL, LOT_DATA
|
||||
from db.session import with_session
|
||||
|
||||
|
||||
@with_session
|
||||
def add_kb_to_db(session, data: LOT_DATA):
|
||||
# 创建知识库实例
|
||||
kb = LOT_DATA_MODEL(**data.__dict__)
|
||||
session.add(kb)
|
||||
|
||||
|
||||
@with_session
|
||||
def delete_kb_from_db(session, id):
|
||||
kb = session.query(LOT_DATA_MODEL).filter_by(id=id).first()
|
||||
if kb:
|
||||
session.delete(kb)
|
||||
return True
|
||||
|
||||
|
||||
# 直接查询所有数据
|
||||
@with_session
|
||||
def get_kb_detail(session):
|
||||
all_data = session.query(LOT_DATA_MODEL).all()
|
||||
data = [LOT_DATA(**d.__dict__) for d in all_data]
|
||||
return data
|
||||
|
||||
|
||||
# 根据时间查询数据
|
||||
@with_session
|
||||
def get_kb_detail_by_time(session, start_time, end_time):
|
||||
all_data = session.query(LOT_DATA_MODEL).filter(
|
||||
start_time <= LOT_DATA_MODEL.create_time, LOT_DATA_MODEL.create_time <= end_time).all()
|
||||
data = [LOT_DATA(**d.__dict__) for d in all_data]
|
||||
return data
|
||||
|
||||
|
||||
# 删除数据
|
||||
@with_session
|
||||
def delete_kb_detail_by_time(session, start_time, end_time):
|
||||
d = session.query(LOT_DATA_MODEL).filter(start_time <= LOT_DATA_MODEL.create_time, LOT_DATA_MODEL.create_time <= end_time).delete()
|
||||
return d
|
||||
|
||||
|
||||
# 查询数据
|
||||
@with_session
|
||||
def get_data_by_field(session, field, value):
|
||||
query = session.query(LOT_DATA_MODEL).filter(getattr(LOT_DATA_MODEL, field) == value)
|
||||
result = query.all()
|
||||
return result
|
|
@ -0,0 +1,46 @@
|
|||
from functools import wraps
|
||||
from contextlib import contextmanager
|
||||
from db.base import SessionLocal
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
|
||||
@contextmanager
|
||||
def session_scope() -> Session:
|
||||
"""上下文管理器用于自动获取 Session, 避免错误"""
|
||||
session = SessionLocal()
|
||||
try:
|
||||
yield session
|
||||
session.commit()
|
||||
except:
|
||||
session.rollback()
|
||||
raise
|
||||
finally:
|
||||
session.close()
|
||||
|
||||
|
||||
def with_session(f):
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
with session_scope() as session:
|
||||
try:
|
||||
result = f(session, *args, **kwargs)
|
||||
session.commit()
|
||||
return result
|
||||
except:
|
||||
session.rollback()
|
||||
raise
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def get_db() -> SessionLocal:
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def get_db0() -> SessionLocal:
|
||||
db = SessionLocal()
|
||||
return db
|
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
pydantic~=1.10.13
|
||||
sqlalchemy~=2.0.19
|
||||
uvicorn~=0.23.2
|
||||
fastapi~=0.95.1
|
||||
paho-mqtt~=1.6.1
|
||||
requests~=2.31.0
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
supervisorctl start push_stream
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
supervisorctl stop push_stream
|
|
@ -0,0 +1,30 @@
|
|||
import datetime
|
||||
import time
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
while (True):
|
||||
print(time.time())
|
||||
time.sleep(10.0)
|
||||
# data = {
|
||||
# "wind_speed": 26,
|
||||
# "wind_direction": 6,
|
||||
# "ambient_temperature": 66,
|
||||
# "ambient_humidity": 78,
|
||||
# "carbon_dioxide": 94,
|
||||
# "ambient_air_pressure": 48,
|
||||
# "rainfall": 3,
|
||||
# "ambient_lighting": 59,
|
||||
# "soil_temperature": 71,
|
||||
# "soil_moisture": 19,
|
||||
# "soil_conductivity": 62,
|
||||
# "soil_PH": 49,
|
||||
# "soil_potassium_phosphate_nitrogen": 5,
|
||||
# "soil_potassium_phosphate_phosphorus": 5,
|
||||
# "soil_potassium_phosphate_potassium": 86
|
||||
# }
|
||||
# data = LOT_DATA(**data, create_time=int(time.time()))
|
||||
# add(data)
|
||||
# print(data)
|
||||
# requests.post("http://192.168.1.27:8000/add/lot_data", json=data)
|
|
@ -0,0 +1,19 @@
|
|||
import json
|
||||
import subprocess
|
||||
|
||||
|
||||
def push_stream():
|
||||
subprocess.Popen(['/bin/bash start_push.sh'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
|
||||
def close_stream():
|
||||
subprocess.Popen(['/bin/bash stop_push.sh'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
|
||||
def exec_sh(msg):
|
||||
cmd = json.loads(msg.payload.decode('utf-8'))["data"]
|
||||
subprocess.Popen([cmd], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
|
||||
|
||||
def update():
|
||||
subprocess.Popen(['/bin/bash update.sh'], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
Loading…
Reference in New Issue