Commit a734c301 authored by pangjh's avatar pangjh

信号分析代码提交

parent b58d8c6f
......@@ -3,7 +3,6 @@ package com.esv.datacenter.iot.common.component;
import com.esv.datacenter.iot.common.util.DateUtils;
import com.esv.datacenter.iot.module.datamodel.entity.DataModelPropertyEntity;
import com.zaxxer.hikari.HikariDataSource;
import io.micrometer.core.instrument.util.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -175,7 +174,7 @@ public class TimescaleComponent {
sb.append(",");
sb.append(propertyEntity.getPropertyCode()).append(" ");
sb.append(fieldMap.get(propertyType)).append(" NULL");
if (Objects.nonNull(defaultValue)) {
if (Objects.nonNull(defaultValue) && !"array".equals(propertyType)) {
sb.append(" DEFAULT ");
switch (propertyType) {
case "boolean":
......
package com.esv.datacenter.iot.module.dashboard.controller;
import com.esv.datacenter.iot.common.response.EResponse;
import com.esv.datacenter.iot.module.dashboard.dto.DataPreviewDTO;
import com.esv.datacenter.iot.module.dashboard.req.DashboardReq;
import com.esv.datacenter.iot.module.dashboard.req.FrequencyDomainReq;
import com.esv.datacenter.iot.module.dashboard.req.HistoryDashboardReq;
import com.esv.datacenter.iot.module.dashboard.req.TimeDomainReq;
import com.esv.datacenter.iot.module.dashboard.service.DashboardService;
import com.esv.datacenter.iot.module.dashboard.service.PythonService;
import com.esv.datacenter.iot.module.dashboard.vo.FrequencyDomainVO;
import com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO;
import lombok.extern.slf4j.Slf4j;
import org.postgresql.jdbc.PgArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
......@@ -13,7 +19,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
/**
* @description:
......@@ -31,21 +39,80 @@ public class DashboardController {
private DashboardService dashboardService;
private PythonService pythonService;
@Autowired
public DashboardController(DashboardService dashboardService) {
public DashboardController(DashboardService dashboardService, PythonService pythonService) {
this.dashboardService = dashboardService;
this.pythonService = pythonService;
}
/**
* description 查询模型数据
* param [dashboardReqList]
* return com.esv.datacenter.iot.common.response.EResponse<java.util.List<com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO>>
* author chenfm
* createTime 2020/8/20 14:54
**/
@PostMapping("modelData")
public EResponse<List<ModelDataVO>> modelData(@RequestBody List<DashboardReq> dashboardReqList) {
List<ModelDataVO> list = dashboardService.modelData(dashboardReqList);
return EResponse.ok(list);
}
/**
* description 查询模型历史数据
* param [historyDashboardReq]
* return com.esv.datacenter.iot.common.response.EResponse<java.util.List<com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO>>
* author chenfm
* createTime 2020/8/20 14:55
**/
@PostMapping("modelHistory")
public EResponse<List<ModelDataVO>> modelHistory(@RequestBody @Validated HistoryDashboardReq historyDashboardReq) {
List<ModelDataVO> list = dashboardService.modelHistory(historyDashboardReq);
return EResponse.ok(list);
}
@PostMapping("dataPreview")
public EResponse<List<DataPreviewDTO>> dataPreview(@RequestBody TimeDomainReq timeDomainReq) {
long modelId = timeDomainReq.getModelId();
long deviceId = timeDomainReq.getDeviceId();
List<DataPreviewDTO> list = dashboardService.dataPreview(modelId, deviceId);
return EResponse.ok(list);
}
/**
* description 时域数据
* param []
* return com.esv.datacenter.iot.common.response.EResponse<com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO>
* author chenfm
* createTime 2020/8/20 14:57
**/
@PostMapping("timeDomainData")
public EResponse<Map<String, Object>> timeDomainData(@RequestBody @Validated TimeDomainReq timeDomainReq) {
Map<String, Object> data = dashboardService.timeDomainData(timeDomainReq);
for (Map.Entry<String, Object> entry : data.entrySet()) {
if (entry.getValue() instanceof PgArray) {
PgArray pgArray = (PgArray) entry.getValue();
log.info("pgArray: {}", pgArray);
try {
data.put(entry.getKey(), pgArray.getArray());
} catch (SQLException e) {
log.error(e.getMessage(), e);
}
}
}
return EResponse.ok(data);
}
@PostMapping("frequencyDomainData")
public EResponse frequencyDomainData(@RequestBody @Validated FrequencyDomainReq frequencyDomainReq) {
List<String> resultList = pythonService.calcFrequency(frequencyDomainReq);
// 振幅, 频率, 位移
FrequencyDomainVO frequencyDomainVO = dashboardService.processFrequencyDomain(resultList);
return EResponse.ok(frequencyDomainVO);
}
}
package com.esv.datacenter.iot.module.dashboard.dto;
import lombok.Data;
/**
* @description:
* @project: datacenter-iot-service
* @name: com.esv.datacenter.iot.module.dashboard.dto.DataPreviewDTO
* @author: chenfm
* @email: chenfengman@esvtek.com
* @createTime: 2020/8/21 16:25
* @version: 1.0
*/
@Data
public class DataPreviewDTO {
private long time;
private double samplingRate;
}
package com.esv.datacenter.iot.module.dashboard.req;
import lombok.Data;
/**
* @description:
* @project: datacenter-iot-service
* @name: com.esv.datacenter.iot.module.dashboard.req.FrequencyDomainReq
* @author: chenfm
* @email: chenfengman@esvtek.com
* @createTime: 2020/8/20 17:54
* @version: 1.0
*/
@Data
public class FrequencyDomainReq {
/**
* description 实例id
* param
* return
* author chenfm
* createTime 2020/8/3 20:20
**/
private Long deviceId;
/**
* 模型ID
*/
private Long modelId;
/**
* description
* author chenfm
* createTime 2020/8/20 17:55
**/
private Long time;
private String propertyCode;
}
package com.esv.datacenter.iot.module.dashboard.req;
import lombok.Data;
import java.util.List;
/**
* @description:
* @project: datacenter-iot-service
* @name: com.esv.datacenter.iot.module.dashboard.req.TimeDomainReq
* @author: chenfm
* @email: chenfengman@esvtek.com
* @createTime: 2020/8/20 15:10
* @version: 1.0
*/
@Data
public class TimeDomainReq {
/**
* description
* author chenfm
* createTime 2020/8/20 17:55
**/
private Long time;
/**
* description 实例id
* param
* return
* author chenfm
* createTime 2020/8/3 20:20
**/
private Long deviceId;
/**
* 模型ID
*/
private Long modelId;
/**
* description 属性列表
* param
* return
* author chenfm
* createTime 2020/8/3 20:20
**/
private List<String> propertyCodeList;
}
package com.esv.datacenter.iot.module.dashboard.service;
import com.esv.datacenter.iot.module.dashboard.dto.DataPreviewDTO;
import com.esv.datacenter.iot.module.dashboard.req.DashboardReq;
import com.esv.datacenter.iot.module.dashboard.req.HistoryDashboardReq;
import com.esv.datacenter.iot.module.dashboard.req.TimeDomainReq;
import com.esv.datacenter.iot.module.dashboard.vo.FrequencyDomainVO;
import com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO;
import java.util.List;
import java.util.Map;
/**
* @description:
......@@ -17,8 +21,35 @@ import java.util.List;
*/
public interface DashboardService {
/**
* description 查询模型数据
* param [dashboardReqList]
* return java.util.List<com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO>
* author chenfm
* createTime 2020/8/20 15:13
**/
List<ModelDataVO> modelData(List<DashboardReq> dashboardReqList);
/**
* description 查询模型历史数据
* param [historyDashboardReq]
* return java.util.List<com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO>
* author chenfm
* createTime 2020/8/20 15:13
**/
List<ModelDataVO> modelHistory(HistoryDashboardReq historyDashboardReq);
/**
* description 时域数据
* param [timeDomainReq]
* return com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO
* author chenfm
* createTime 2020/8/20 15:13
**/
Map<String, Object> timeDomainData(TimeDomainReq timeDomainReq);
FrequencyDomainVO processFrequencyDomain(List<String> resultList);
List<DataPreviewDTO> dataPreview(long modelId, long deviceId);
}
package com.esv.datacenter.iot.module.dashboard.service;
import com.esv.datacenter.iot.module.dashboard.req.FrequencyDomainReq;
import java.util.List;
/**
* @description:
* @project: datacenter-iot-service
* @name: com.esv.datacenter.iot.module.dashboard.service.PythonService
* @author: chenfm
* @email: chenfengman@esvtek.com
* @createTime: 2020/8/21 11:40
* @version: 1.0
*/
public interface PythonService {
List<String> calcFrequency(FrequencyDomainReq frequencyDomainReq);
}
package com.esv.datacenter.iot.module.dashboard.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.esv.datacenter.iot.common.component.TimescaleComponent;
import com.esv.datacenter.iot.common.constants.CommonConstants;
import com.esv.datacenter.iot.common.util.SqlUtils;
import com.esv.datacenter.iot.module.dashboard.dto.DataPreviewDTO;
import com.esv.datacenter.iot.module.dashboard.req.DashboardReq;
import com.esv.datacenter.iot.module.dashboard.req.HistoryDashboardReq;
import com.esv.datacenter.iot.module.dashboard.req.TimeDomainReq;
import com.esv.datacenter.iot.module.dashboard.service.DashboardService;
import com.esv.datacenter.iot.module.dashboard.vo.ChartVO;
import com.esv.datacenter.iot.module.dashboard.vo.FrequencyDomainVO;
import com.esv.datacenter.iot.module.dashboard.vo.FunctionVO;
import com.esv.datacenter.iot.module.dashboard.vo.ModelDataVO;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
......@@ -13,8 +20,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
......@@ -90,4 +100,94 @@ public class DashboardServiceImpl implements DashboardService {
return modelDataVOList;
}
@Override
public Map<String, Object> timeDomainData(TimeDomainReq timeDomainReq) {
Timestamp searchTime = new Timestamp(timeDomainReq.getTime());
Long modelId = timeDomainReq.getModelId();
String tableName = CommonConstants.MODEL_DATA_TABLE_PREFIX + modelId;
String sql = "select time"
+ SqlUtils.makeSqlParams(timeDomainReq.getPropertyCodeList())
+ " from "
+ tableName
+ " where device_id = ?"
+ " and time = ?"
+ " order by time desc"
+ " limit 1";
log.info("select modelData sql: {}", sql);
Map<String, Object> map = null;
try {
map = jdbcTemplate.queryForMap(sql, timeDomainReq.getDeviceId(), searchTime);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return map;
}
@Override
public FrequencyDomainVO processFrequencyDomain(List<String> resultList) {
String functionListStr = resultList.get(0);
String xDataStr = resultList.get(1);
String yDataStr = resultList.get(2);
DecimalFormat df = new DecimalFormat("#0.00");
JSONArray array = JSON.parseArray(functionListStr);
List<FunctionVO> functionList = new ArrayList<>(array.size());
for (Object o : array) {
JSONArray dataArray = (JSONArray) o;
FunctionVO functionVO = new FunctionVO();
functionVO.setAmplitude(df.format(dataArray.getDouble(1)));
functionVO.setFrequency(df.format(dataArray.getDouble(0)));
functionVO.setPhase(df.format(dataArray.getDouble(2)));
functionList.add(functionVO);
// if (functionList.size() >= 5) {
// break;
// }
}
ChartVO chartVO = new ChartVO();
List<Double> xList = new ArrayList<>();
for (String xStr : xDataStr.split(",")) {
xList.add(Double.parseDouble(xStr));
}
List<Double> yList = new ArrayList<>();
for (String yStr : yDataStr.split(",")) {
yList.add(Double.parseDouble(yStr));
}
chartVO.setXData(xList);
chartVO.setYData(yList);
Collections.sort(functionList);
FrequencyDomainVO frequencyDomainVO = new FrequencyDomainVO();
frequencyDomainVO.setChart(chartVO);
frequencyDomainVO.setFunctionList(functionList);
return frequencyDomainVO;
}
@Override
public List<DataPreviewDTO> dataPreview(long modelId, long deviceId) {
String tableName = CommonConstants.MODEL_DATA_TABLE_PREFIX + modelId;
String sql = "select time, sampling_rate"
+ " from "
+ tableName
+ " where device_id = ?"
+ " order by time desc";
log.info("select modelData sql: {}", sql);
List<DataPreviewDTO> list = new ArrayList<>();
try {
List<Map<String, Object>> mapList = jdbcTemplate.queryForList(sql, deviceId);
for (Map<String, Object> map : mapList) {
DataPreviewDTO dataPreviewDTO = new DataPreviewDTO();
Timestamp time = (Timestamp) map.get("time");
BigDecimal samplingRate = (BigDecimal) map.get("sampling_rate");
dataPreviewDTO.setTime(time.getTime());
dataPreviewDTO.setSamplingRate(samplingRate.doubleValue());
list.add(dataPreviewDTO);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return list;
}
}
package com.esv.datacenter.iot.module.dashboard.service.impl;
import com.esv.datacenter.iot.common.constants.CommonConstants;
import com.esv.datacenter.iot.module.dashboard.req.FrequencyDomainReq;
import com.esv.datacenter.iot.module.dashboard.service.PythonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
/**
* @description:
* @project: datacenter-iot-service
* @name: com.esv.datacenter.iot.module.dashboard.service.impl.PythonServiceImpl
* @author: chenfm
* @email: chenfengman@esvtek.com
* @createTime: 2020/8/21 11:41
* @version: 1.0
*/
@Slf4j
@Service("pythonService")
public class PythonServiceImpl implements PythonService {
@Value("${timescale.data-source.jdbc-url}")
private String timeScaleUrl;
@Value("${timescale.data-source.username}")
private String timeScaleUser;
@Value("${timescale.data-source.password}")
private String timeScalePassword;
@Value("${python.path.frequency}")
private String pythonFrequencyPath;
@Override
public List<String> calcFrequency(FrequencyDomainReq frequencyDomainReq) {
// jdbc:postgresql://192.168.31.248:5432/iot
String urlStr = timeScaleUrl.replaceFirst("jdbc:postgresql://", "");
String host = urlStr.split(":")[0];
String port = urlStr.split(":")[1].split("/")[0];
String database = urlStr.split(":")[1].split("/")[1];
String tableName = CommonConstants.MODEL_DATA_TABLE_PREFIX + frequencyDomainReq.getModelId();
String columnName = frequencyDomainReq.getPropertyCode();
double time = frequencyDomainReq.getTime() / 1000.0;
List<String> resultList = new ArrayList<>();
String pythonPath = "python";
String[] arguments = new String[] {pythonPath, pythonFrequencyPath,
host, port, database, timeScaleUser, timeScalePassword, tableName, columnName, String.valueOf(time)};
try {
Process process = Runtime.getRuntime().exec(arguments);
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(),"GBK");
BufferedReader in = new BufferedReader(inputStreamReader);
BufferedReader bufrError = new BufferedReader(new InputStreamReader(process.getErrorStream(), "GBK"));
String line = null;
boolean record = false;
while ((line = in.readLine()) != null) {
log.info(line);
if (line.startsWith("result_list:")) {
record = true;
line = line.replaceFirst("result_list:", "");
}
if (record) {
resultList.add(line);
}
}
in.close();
//输出错误信息
String error = null;
while ((error = bufrError.readLine()) != null) {
log.error(error);
}
bufrError.close();
//java代码中的process.waitFor()返回值为0表示我们调用python脚本成功,
//返回值为1表示调用python脚本失败,这和我们通常意义上见到的0与1定义正好相反
int re = process.waitFor();
log.info("python脚本调用结果: {}", re);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return resultList;
}
}
package com.esv.datacenter.iot.module.dashboard.vo;
import lombok.Data;
import java.util.List;
/**
* @description:
* @project: datacenter-iot-service
* @name: com.esv.datacenter.iot.module.dashboard.vo.ChartVO
* @author: chenfm
* @email: chenfengman@esvtek.com
* @createTime: 2020/8/21 13:45
* @version: 1.0
*/
@Data
public class ChartVO {
private List<Double> xData;
private List<Double> yData;
}
package com.esv.datacenter.iot.module.dashboard.vo;
import lombok.Data;
import java.util.List;
/**
* @description:
* @project: datacenter-iot-service
* @name: com.esv.datacenter.iot.module.dashboard.vo.FrequencyDomainVO
* @author: chenfm
* @email: chenfengman@esvtek.com
* @createTime: 2020/8/21 13:44
* @version: 1.0
*/
@Data
public class FrequencyDomainVO {
private ChartVO chart;
private List<FunctionVO> functionList;
}
package com.esv.datacenter.iot.module.dashboard.vo;
import lombok.Data;
/**
* @description:
* @project: datacenter-iot-service
* @name: com.esv.datacenter.iot.module.dashboard.vo.FunctionVO
* @author: chenfm
* @email: chenfengman@esvtek.com
* @createTime: 2020/8/21 13:45
* @version: 1.0
*/
@Data
public class FunctionVO implements Comparable<FunctionVO> {
/**
* 振幅
**/
private String amplitude;
/**
* 频率
**/
private String frequency;
/**
* 相位
**/
private String phase;
@Override
public int compareTo(FunctionVO functionVO) {
if (Double.parseDouble(functionVO.getFrequency()) == 0) {
return 1;
}
if (Double.parseDouble(this.getAmplitude()) > Double.parseDouble(functionVO.getAmplitude())) {
return -1;
} else if (Double.parseDouble(this.getAmplitude()) < Double.parseDouble(functionVO.getAmplitude())) {
return 1;
} else {
return 0;
}
}
}
......@@ -71,7 +71,7 @@ feign-base-service-name: datacenter-base-service
db:
dict:
table-field:
map: 1-string,2-number,3-integer,4-boolean,5-date,6-time,7-datetime
map: 1-string,2-number,3-integer,4-boolean,5-array
timescale:
data-source:
jdbc-url: jdbc:postgresql://192.168.31.248:5432/iot
......@@ -84,7 +84,7 @@ timescale:
maximum-pool-size: 10
max-lifetime: 0
table-field:
map: string-text,number-numeric,integer-int8,boolean-bit(1),date-date,time-int4,datetime-timestamptz
map: string-text,number-numeric,integer-int8,boolean-bit(1),date-date,time-int4,datetime-timestamptz,array-numeric[]
table-prefix: iot_data_model_
emq:
api:
......@@ -103,3 +103,6 @@ emq:
minimum-idle: 1
maximum-pool-size: 1
max-lifetime: 0
python:
path:
frequency: D:\IdeaProjects\iot-service\src\main\resources\python\frequency.py
......@@ -3,7 +3,9 @@ server:
servlet:
context-path: /iot
nacos:
# url: localhost:8848
url: 192.168.31.248:8848
# namespace: cdbdf903-f657-40bb-9b2b-f21f2a286ff3
namespace: 1697ea67-be4c-4d38-b00d-39392b9dee8f
group: DEFAULT_GROUP
spring:
......
import sys
import math
import psycopg2
import numpy as np
from scipy.fftpack import fft,ifft
np.set_printoptions(suppress=True)
np.set_printoptions(threshold=np.inf)
def search_data(host, port, database, user, password, table_name, column_name, time):
# database,user,password,host,port分别对应要连接的PostgreSQL数据库的数据库名、数据库用户名、用户密码、主机、端口信息,请根据具体情况自行修改
conn = psycopg2.connect(database=database, user=user, password=password, host=host, port=port)
cur = conn.cursor()
# 执行查询命令 1597916863.951
sql = 'SELECT sampling_rate, ' + column_name + ' FROM ' + table_name + ' where time = to_timestamp(' + time + ');'
print(sql)
cur.execute(sql)
# 获取结果集的每一行
rows = cur.fetchall()
print('查询结果数: ', len(rows))
row1 = rows[0]
samplingRate = row1[0]
displacement = row1[1]
# 关闭连接
conn.close()
return samplingRate, displacement
def computeRadian(opp, limb):
if limb < 0:
return math.atan(opp / limb) + np.pi
else:
return math.atan(opp / limb)
def calc_fft(sampling_rate, displacement):
#采样点选择1400个,因为设置的信号频率分量最高为600赫兹,根据采样定理知采样频率要大于信号频率2倍,所以这里设置采样频率为1400赫兹(即一秒内有1400个采样点,一样意思的)
length = len(displacement) / (sampling_rate * 1000000)
x = np.linspace(0., float(length), len(displacement))
#设置需要采样的信号,频率分量有180,390和600
# y=0.1 + 0.01*np.cos(2*np.pi*50*x-np.pi*60/180) + 5*np.cos(2*np.pi*100*x+np.pi*90/180) + 20*np.cos(2*np.pi*80*x+np.pi*90/180) + 24*np.cos(2*np.pi*40*x+np.pi*90/180)
y = displacement
yy = fft(y) # 快速傅里叶变换
yreal = yy.real # 获取实数部分
yimag = yy.imag # 获取虚数部分
yf = abs(fft(y)) # 取绝对值
halfsize = int(len(x) / 2)
yf2 = yf[range(halfsize)] # 由于对称性,只取一半区间
yf3 = yf2 / sum(yf2) # 归一化
result_list = []
throshold = float(0.1 / halfsize)
if yf3[0] > throshold:
frequency = yf3[0] * sum(yf2) / halfsize / 2
radian = computeRadian(yimag[0], yreal[0])
result_list.append([0, frequency, radian])
for i in range(1, len(yf3) - 1):
if (yf3[i] - yf3[i - 1]) > throshold and (yf3[i] - yf3[i + 1]) > throshold:
frequency = yf3[i] * sum(yf2) / halfsize
radian = computeRadian(yimag[i], yreal[i])
result_list.append([i, frequency, radian])
xf = np.arange(len(y)) # 频率
xf1 = xf
xf2 = xf[range(int(len(x)/2))] # 取一半区间
return result_list, xf2, yf3
def print_array(array, fixed):
i = 0
for x in array:
i += 1
if (fixed):
x = format(x, '.4f')
if (i < len(array)):
print(x, end=',')
else:
print(x, end='\n')
if __name__ == '__main__':
host = sys.argv[1]
port = sys.argv[2]
database = sys.argv[3]
user = sys.argv[4]
password = sys.argv[5]
table_name = sys.argv[6]
column_name = sys.argv[7]
time = sys.argv[8]
print('开始调用python ', host, port, database, user, password, table_name, column_name, time)
(sampling_rate, displacement) = search_data(host, port, database, user, password, table_name, column_name, time)
(result_list, xf, yf) = calc_fft(sampling_rate, displacement)
print('result_list:', result_list)
print_array(xf, False)
print_array(yf, True)
\ No newline at end of file
import sys
if __name__ == '__main__':
arg1 = sys.argv[1]
arg2 = sys.argv[2]
print('开始调用python ', arg1, arg2)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment