• [网络精度/性能调优] 采集Profiling 数据(acl.json 配置文件方式 ),无法产生PROF***目录
    参考:https://www.hiascend.com/doc_center/source/zh/canncommercial/504/devtools/auxiliarydevtool/CANN%205.0.4%20%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7%E6%8C%87%E5%8D%97%2001.pdf采用配置acl.json的方式采集数据,如上述文档描述应有PROF*** 目录,但实际没有,却有JOB**************目录CANN 5.0.4DIRVER:21.0.4acl.json 如下:{ "profiler":{ "switch": "on", "output": "output", "aicpu": "on" }}
  • [技术干货] python如何读取和存储dict()与.json格式文件【转载】
    目录读取和存储dict()与.json格式文件读取.json格式文件并将数据保存到字典中保存字典数据到.json文件中在命令行中输出字典时的乱码问题将字符串数据转化为字典数据将dict数据写入json文件中读取和存储dict()与.json格式文件读取.json格式文件并将数据保存到字典中数据文件:hg.json{"商家名称": "珍滋味港式粥火锅(工体店)", "评分": 27.0, "地址": "火锅工人体育场东路丙2号中国红街3号楼2层里", "人均消费": 174, "评论数量": 2307}{"商家名称": "井格老灶火锅(望京新世界店)", "评分": 26.2, "地址": "火锅望京广顺南大街路16号", "人均消费": 105, "评论数量": 1387}{"商家名称": "脸谱港式火锅(酒仙桥丽都店)", "评分": 24.5, "地址": "火锅芳园西路6号一层", "人均消费": 218, "评论数量": 39}针对上述数据,可以采用如下方法将json编码的字符串转换为python数据结构dict:12345678910# -*- coding: utf-8 -*-import jsonimport codecs data = []with codecs.open("hg.json", "r", "utf-8") as f:    for line in f:        dic = json.loads(line)        data.append(dic)        print(json.dumps(dic, indent=4, ensure_ascii=False, encoding='utf-8'))保存字典数据到.json文件中1234dic = {"商家名称": "井格老灶火锅(望京新世界店)", "评分": 26.2, "地址": "火锅望京广顺南大街路16号", "人均消费": 105, "评论数量": 1387}with codecs.open('hg.json','a', 'utf-8') as outf:    json.dump(dic, outf, ensure_ascii=False)    outf.write('\n')在命令行中输出字典时的乱码问题如果字典数据中有中文的话,print dic是无法正常显示中文的,可通过下面的方法格式化输出字典数据:12dic = {"北京": [446, 208.7, 110000], "天津": [454.2, 219.8, 120000], "上海": [498.6, 319.7, 310000]}print(json.dumps(dic, ensure_ascii=False, encoding='utf-8', indent=4))将字符串数据转化为字典数据两种转化方法123user = "{'name' : 'LiHua', 'sex' : 'male', 'age': 18}"dic1 = eval(user)exec("dic2="+user)补充一般来说,json解码时会从所提供的数据中创建出字典或者列表,如果想创建其它类型的对象,可以为json.loads()方法提供object_pairs_hook或者object_hook参数。下面的示例展示了我们应该如何将json数据解码为OrderedDict(有序字典),这样可以保持数据的顺序不变。123456>>> s = '{"name":"ACME", "SHARES":50, "PRICE":490}'>>> from collections import OrderedDict>>> data = json.load(s, object_pairs_hook=OrderedDict)>>> dataOrderedDict([('name', 'ACME'), ('shares', 50), ('price', 490)]>>>将dict数据写入json文件中现在获取一个医药网站的数据,最终转换成dict类型,需要将数据写入JSON文件中,以方便后面数据的使用12with open('./medical.json', 'w',encoding='utf-8') as fp:   json.dump(data, fp)但得到的最终数据却是这样:本来应该是正常的中文字符串,却是ASCII编码,因此在dump方法中添加一个ensure_ascii参数,原因是dump()方法将字典转化为字符串,会默认将其中unicode码以ascii编码的方式输入到字符串中12with open('./medical.json', 'w',encoding='utf-8') as fp:   json.dump(data, fp,ensure_ascii=False)
  • [其他问题] 【MindSpore Vision】【将分类模型部署到移动端】添加自定义模型时显示”文件不存在或json格式文件有误“
    【功能模块】将训练好的mobilenet模型部署到安卓手机,实现分类的功能。【操作步骤&问题现象】1、自主搭建模型,训练模型。2、将模型保存为MINDIR文件,通过MindSpore Lite conventer转换为.ms文件,传输到移动端。在电脑创建json文件(使用notepad++创建),并传输到移动端。3、下载安装MindSpore Vision apk4、手机打开MindSpore Vision应用,拍照后进入自定义界面,找到并选择json文件,显示”添加自定义模型成功“,title确实改变,但并未加载到ms文件,因为分类结果仍是通用模型的。【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [干货汇总] 透过实例demo带你认识gRPC
    本文分享自华为云社区《[gRPC介绍以及spring demo构架展示](https://bbs.huaweicloud.com/blogs/342879?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=paas&utm_content=content)》,作者:gentle_zhou。gRPC,即google Remote Procedure Call Protocol;在gRPC里,客户端可以直接调用不同机器上的服务应用的方法,就像本地对象一样,所以创建分布式应用和服务就变简单了。gRPC是基于定义一个服务,指定一个可以远程调用的带有参数和返回类型的的方法。在服务端,服务实现这个接口并且运行gRPC服务处理客户端调用。在客户端,有一个stub提供和服务端相同的方法。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653012226533359725.png)# 数据编码数据编码即将请求的内存对象转化成可以传输的字节流发送给服务端,并将收到的字节流在转化成内存对象。常见的数据编码方法有JSON,而gRPC则默认选用protobuf。为什么选用protobuf呢?一个是因为它是谷歌自己的产品,二是它作为一种序列化资料结构的协定,在某些场景下传输的效率比JSON高。一个.proto文件里的消息格式如下:!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653012247981492975.png)而一个典型的JSON格式如下所示:!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653012255295334975.png)我们可以看到在JSON里,内存方面,int字段的12345会占据5个字节,bool字段的true会占据4个字节,占据内存就会比较大,编码低效;还有一个缺点就是在JSON里,同一个接口同一个对象,只是int字段的值不同,每次却都还要传输int这个字段名。这样做的好处就是JSON的可读性很高,但同样在编码效率方面就会有所牺牲。而Protobuf则是选用了VarInts对数字进行编码(VarInts则是动态的,征用了每个字节的最高位MSB,如果是1表示还有后序字节,如果是0表示后面就没字节了,以此来确定表示长度所需要的字节数量,解决了效率问题),同时给每个字段指定一个整数编号,传输的时候只传字段编号(解决了效率和冗余问题)。但是只传字段编号的话,接收方如何知道各个编号对应哪个字段呢?那就需要靠提前约定了。Protobuf使用.proto文件当做密码本,记录字段和编号的对应关系。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653012264489474276.png) Protobuf 提供了一系列工具,为 proto 描述的 message 生成各种语言的代码。传输效率上去了,工具链也更加复杂了。# 请求映射IDL,Interactive Data Language的缩写,交互式数据语言。因为我们有.proto文件作为IDL,Protobuf就可以做到RPC描述。比如在.proto文件里定义一个Greeter服务,其中有一个 SayHello 的方法,接受 HelloRequest 消息并返回 HelloReply 消息。如何实现这个 Greeter 则是语言无关的,所以叫 IDL。gRPC 就是用了 Protobuf 的 service 来描述 RPC 接口的。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653012289102692991.png)gRPC 在底层使用的是 HTTP/2 协议。这个 HTTP 请求用的是 POST 方法,对应的资源路径则是根据 .proto 定义确定的。我们前面提到的 Greeter 服务对应的路径是/demo.hello.Greeter/SayHello 。一个 gRPC 定义包含三个部分,包名、服务名和接口名,连接规则如下**/${包名}. ${服务名}/ ${接口名}**SayHello的包名是demo.hello,服务名是Greeter,接口名是SayHello,所以对应的路径就是 /demo.hello.Greeter/SayHello。gRPC 支持三种流式接口,定义的办法就是在参数前加上 stream 关键字,分别是:请求流、响应流和双向流。第一种叫请求流,可以在 RPC 发起之后不断发送新的请求消息。此类接口最典型的使用场景是发推送或者短信。第二种叫响应流,可以在 RPC 发起之后不断接收新的响应消息。此类接口最典型的使用场景是订阅消息通知。最后一种是双向流。可以在 RPC 发起之后同时收发消息。此类接口最典型的使用场景是实时语音转字幕。如下就是普通接口和三种流式接口的结构样式:!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653012310100318117.png)最简单的gRPC(非流式调用,unary)请求内容和相应内容如下所示:!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653012318083189876.png)如果单看非流式调用,也就是 unary call,gRPC 并不复杂,跟普通的 HTTP 请求也没有太大区别。我们甚至可以使用 HTTP/1.1 来承载 gRPC 流量。但是gRPC 支持流式接口,这就有点难办了。我们知道,HTTP/1.1 也是支持复用 TCP 连接的。但这种复用有一个明显的缺陷,所有请求必须排队。也就是说一定要按照请求、等待、响应、请求、等待、响应这样的顺序进行。先到先服务。而在实际的业务场景中肯定会有一些请求响应时间很长,客户端在收到响应之前会一直霸占着TCP连接。在这段时间里别的请求要么等待,要么发起新的 TCP 连接。在效率上确实有优化的余地。一言以蔽之,HTTP/1.1 不能充分地复用 TCP 连接。后来,HTTP/2 横空出世!通过引入 stream 的概念,解决了 TCP 连接复用的问题。你可以把 HTTP/2 的 stream 简单理解为逻辑上的 TCP 连接,可以在一条 TCP 连接上并行收发 HTTP 消息,而无需像 HTTP/1.1 那样等待。所以 gRPC 为了实现流式接品,选择使用 HTTP/2 进行通信。所以,前文的 Greeter 调用的实际通信内容长这个样子。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20225/20/1653012328545131463.png)HTTP/2 的 header 和 data 使用独立的 frame(帧,简单来说也是一种 Length-Prefixed 消息,是 HTTP/2 通信的基本单位) 发送,可以多次发送。# springboot里的grpc demo整个项目可以分成三个project:1. grpc-springboot-demo-api:proto文件(syntax=“proto3”; 定义服务,定义请求体,定义回应内容)写好之后用maven-install来编译生成所需的类;2. grpc-springboot-demo-server:pom文件(springboot的启动依赖,grpc的依赖, api项目的依赖),springboot的启动类,GRPC服务器的启动类,提供服务的业务逻辑实现类3. grpc-springboot-demo-consumer:pom文件(springboot的启动依赖,grpc的依赖, api项目的依赖),springboot启动类(与服务端启动类无差异),gRPC 客户端(主要作用是监听 gRPC 服务端,开启通道)。对应MVC关系就是:- grpc-springboot-demo-api就是service(接口,为提供实现);- grpc-springboot-demo-server就相当于serviceImpl(service的实现类);- grpc-springboot-demo-consumer就是controller的角色。具体代码可以看:[grpc-java springboot 同步异步调用 demo_卤小蛋学编程的博客-CSDN博客_grpc java 异步](https://blog.csdn.net/Applying/article/details/115024675)拓展repeated限定修饰符repeated代表可重复,我们可以理解为数组。比如下面的代码:``` syntax = "proto3";//指定版本信息,不指定会报错 message Person //message为关键字,作用为定义一种消息类型 { string name = 1; //姓名 int32 id = 2; //id string email = 3; //邮件 } message AddressBook { repeated Person people = 1; }```编译器就会把Person认定为数组,而我们在使用Person,用add往里面添加信息,代码如下:AddressBook addBopookReq = AddressBook.newBuilder().addName("Lily").build();就不需要指定index了,直接往数组里添加了一个新的addressbook,它的名字属性则是Lily。# 参考资料1. https://developers.google.com/protocol-buffers/docs/overview2. https://taoshu.in/grpc.html3. https://grpc.io/4. https://grpc.io/docs/languages/java/quickstart/5. (https://blog.csdn.net/tennysonsky/article/details/73921025)
  • [技术干货] 详解npm脚本和package.json
    npm是什么npm是前端开发广泛使用的包管理工具,它让js开发者分享、复用代码更方便。可以重复的框架代码被称为包(package)或者模块(module),一个包可是是一个文件夹里放着几个文件夹,还有一个package.json文件。1、什么是npm脚本  在创建node.js项目如一个vue项目,或一个react项目时,项目都会生成一个描述文件package.json 。比如npm允许在package.json文件里面,使用scripts字段定义脚本命令。1234567891011{//..."scripts": { "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", "start": "npm run dev", "e2e": "node test/e2e/runner.js", "test": "npm run e2e", "lint": "eslint --ext .js,.vue src test/e2e/specs", "build": "node build/build.js" },}  上面代码是package.json文件的一个片段,里面的scripts字段是一个对象。它的每一个属性,对应一段脚本。比如,build命令对应的脚本是node build.js 。  命令行下使用npm run 命令,就可以执行这段脚本。$ npm run build  等同于执行:$ node build/build.js  同理,上面的那段scripts中, npm run test 等同于 npm run e2e , 等同于 node test/e2e/runner.js  这些定义在package.json里面的脚本,就称为npm脚本。项目的相关脚本,可以集中在一个地方;不同项目的脚本命令,只要功能相同,就可以有同样的对外接口。比如用户不需要知道怎么测试你的项目,只要运行 npm run dev 即可  查看当前项目的所有npm脚本命令,可以使用不带任何参数的 npm run 命令。$ npm run2、npm原理  npm脚本的原理非常简单。每当执行 npm run ,就会自动创建一个shell脚本, 在这个shell里面执行指定的脚本命令。因此,只需要是shell (一般是bash) 可以运行的命令,就可以写在npm脚本里面。  比较特别的是,npm run 新建的这个shell, 会将当前目录的node_modules/.bin 子目录加入PATH 变量,执行结束后,再将PATH变量恢复原样。还意味着,当前目录的node_modules/.bin 子目录里面的所有脚本,都可以直接用脚本名调用,而不必加上路径。比如,当前项目的依赖里面有Mocha, 只要直接写 mocha test 就可以了。"test": "mocha test"  而不用写成下面这样。"test": "./node_modules/.bin/mocha test"  由于npm脚本的唯一要求就是可以在shell中执行,因此它不一定是Node脚本,任何可执行文件都可以写在里面。npm脚本的退出码,也遵守shell脚本规则。如果退出码不是0,npm 就认为这个脚本执行失败。3、通配符  由于npm脚本就是shell脚本,因此可以使用shell通配符。12"lint": "jshint *.js""lint": "jshint **/*.js"  上面代码中,* 表示任意文件名,**表示任意一层子目录。如果要将通配符传入原始命令,防止被shell转义,要将*号转义。"test": "tap test/\*.js"4、传参  向npm脚本传入参数,要使用 -- 标明。"lint": "jshint **.js"  向上面的 npm run lint 命令传入参数,必须写成下面这样。1$ npm run lint -- --reporter checkstyle > checkstyle.xml 也可以再package.json里面封装一个命令。12"lint": "jshint **.js","lint:checkstyle": "npm run lint -- --reporter checkstyle > checkstyle.xml"5、执行顺序  如果npm脚本里面需要执行多个任务,那么需要明确它们的执行顺序。如果是并行执行(即同时的平行执行),可以使用 & 符号。$ npm run script1.js & npm run script2.js  如果是继发执行(即只有前一个任务成功,才能执行下一个任务),可以使用 && 符号。$ npm run script1.js && npm run script2.js6、默认值  一般来说,npm脚本由用户提供。但是,npm对两个脚本提供了默认值。也就是说,这两个脚本不用定义,就可以直接使用。12"start": "node server.js","install": "node-gyp rebuild"  上面代码中,npm run start 的默认值是 node server.js, 前提是项目根目录下有server.js这个脚本;npm run install 的默认值是node-gyp rebuild, 前提是项目根目录下有binding.gyp文件。7、钩子  npm脚本有pre何post两个钩子。举例来说,build脚本命令的钩子就是prebuild和postbuild。123"prebuild": "echo I run before the build script","build": "cross-env NODE_ENV=production webpack","postbuild": "echo I run after the build script"  用户执行npm run build的时候,会自动按照下面的顺序执行。1npm run prebuild && npm run build && npm run postbuild  因此,可以在这两个钩子里面,完成一些准备工作和清理工作。下面是一个例子:123"clean": "rimraf ./dist && mkdir dist","prebuild": "npm run clean","build": "cross-env NODE_ENV=production webpack" npm默认提供下面的这些钩子:12345678prepublish,postpublishpreinstall,postinstallpreuninstall,postuninstallpreversion,postversionpretest,posttestprestop,poststopprestart,poststartprerestart,postrestart  自定义的脚本命令也可以加上pre和post钩子。比如,myscript这个脚本命令,也有premyscript和postmyscript钩子。不过,双重的pre和post无效,比如prepretest和postposttest是无效的。  npm提供一个npm_lifecycle_event变量,返回当前正在运行的脚本命令,比如pretest、test、posttest等等。所以,可以利用这个变量,在同一个脚本文件里面,为不同的npm scripts命令编写代码。请看下面的例子:12345678910111213const TARGET = process.env.npm_lifecycle_event; if (TARGET === 'test') { console.log(`Running the test task!`);} if (TARGET === 'pretest') { console.log(`Running the pretest task!`);} if (TARGET === 'posttest') { console.log(`Running the posttest task!`);}  注意,prepublish这个钩子不仅会在npm publish 命令之前运行,还会在npm install (不带任何参数)命令之前运行。这种行为很容易让用户感到困惑,所以npm 4引入了一个新的钩子prepare, 行为等同于prepublish, 而从npm 5开始,prepublish 将只在npm publish命令之前运行。8、简写形式  四个常用的npm脚本有简写形式。npm start 是 npm run start 的简写 npm stop 是 npm run stop 的简写 npm test 是 npm run test 的简写 npm restart 是 npm run stop && npm run restart && npm run start 的简写  npm start 、npm stop、npm restart都比较好理解,而npm restart 是一个复合命令,实际上会执行三个脚本命令:stop、restart、start 。具体的执行顺序如下:prerestart prestop stop poststop restart prestart start poststart postrestart9、变量  npm脚本有一个非常强大的功能,就是可以使用npm的内部变量。首先,通过npm_package_ 前缀,npm脚本可以拿到package.json里面的字段。比如,下面是一个package.json。1234567{ "name": "foo",  "version": "1.2.5", "scripts": { "view": "node view.js" }}那么,变量npm_package_name返回foo, 变量npm_package_version返回 1.2.5 。123// view.jsconsole.log(process.env.npm_package_name); // fooconsole.log(process.env.npm_package_version); // 1.2.5  上面代码中,我们通过环境变量process.env 对象,拿到package.json 的字段值。如果是bash脚本,可以用$npm_package_name和$npm_package_version娶到这两个值。npm_package_ 前缀也支持嵌套的package.json字段。1234567"repository": {"type": "git","url": "xxx"},scripts: {"view": "echo $npm_package_repository_type"}  上面代码中,repository字段的type属性,可以通过 npm_package_repository_type取到。下面是另外一个例子:123"scripts": { "install": "foo.js"}  上面代码中,npm_package_scripts_install变量的值等于foo.js 。  然后,npm 脚本还可以通过npm_config_ 前缀,拿到npm的配置变量,即npm config get xxx 命令返回的值。比如,当前模块的发行标签,可以通过npm_config_tag取到。"view": "echo $npm_config_tag",  注意,package.json里面的config对象,可以被环境变量覆盖。12345{  "name" : "foo", "config" : { "port" : "8080" }, "scripts" : { "start" : "node server.js" }}  上面代码中,npm_package_config_port 变量返回的是8080。这个值可以用下面的方法覆盖。$ npm config set foo:port 80  最后,env命令可以列出所有环境变量。"env": "env"10、常用脚本示例1234567891011121314151617181920212223242526// 删除目录"clean": "rimraf dist/*", // 本地搭建一个 HTTP 服务"serve": "http-server -p 9090 dist/", // 打开浏览器"open:dev": "opener http://localhost:9090", // 实时刷新 "livereload": "live-reload --port 9091 dist/", // 构建 HTML 文件"build:html": "jade index.jade > dist/index.html", // 只要 CSS 文件有变动,就重新执行构建"watch:css": "watch 'npm run build:css' assets/styles/", // 只要 HTML 文件有变动,就重新执行构建"watch:html": "watch 'npm run build:html' assets/html", // 部署到 Amazon S3"deploy:prod": "s3-cli sync ./dist/ s3://example-com/prod-site/", // 构建 favicon"build:favicon": "node scripts/favicon.js",11、package.json其他配置项说明对于dependencies和devDependencies的一些说明:  使用npm安装依赖时,如果使用--save安装的依赖,会被写到dependencies模块里面去;  而使用--save-dev安装的依赖,则会被写到devDependencies模块里面去;如果什么都不写,则默认安装到dependencies里面去。  比如我们使用的一些构建工具例如glup、webpack这些只在开发环境中才用到的包,则只需要写到devDependencies中即可。  对于两种环境的指定方式,则是通过配置文件中的 process.env.NODE_ENV = 'development' 或 process.env.NODE_ENV = 'production' 来指定是开发还是生产环境。12、package.json中的bin属性  package.json中的bin是命令名和本地文件的映射。如果是全局安装,则会把文件映射到全局的bin里面去,安装后,在任意地方打开终端使用命令行执行该文件;如果是本地安装,则会把文件映射到本项目的./node_modules/.bin文件夹里面,安装后,在本工程目录里面使用命令行执行该文件。  举例说明:新建一个文件夹,打开终端,进入该文件夹,通过命令 npm init -y 创建一个package.json文件。然后在package.json文件同级目录下新建一个index.js文件,加上测试数据。注意,index.js文件的头部必须有这个 #!/usr/bin/env node 节点。在package.json中增加bin属性,设置命令名和index.js的映射关系。在终端当前目录中进行全局安装: npm install -g 安装成功后,则在电脑任意文件夹打开终端,执行package.json中bin中设置的命令,都会执行对应的index.js中的代码。 如下图
  • [干货汇总] 聊聊如何在华为云IoT平台进行产品开发
    本文分享自华为云社区《[如何基于华为云IoT物联网平台进行产品开发](https://bbs.huaweicloud.com/blogs/349684?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=iot&utm_content=content)》,作者: Super.雯 。华为云物联网平台承载着南北向数据互通的功能职责。在华为云物联网平台基础上实现端到端物联网业务的过程中,开发者需要基于该平台进行二次开发。本文先跟大家一起聊一聊产品开发。# 产品开发在物联网平台集成解决方案中,物联网平台作为承上启下的中间部分,向应用服务器开放API接口,向各种协议的设备提供API对接。为了提供更加丰富的设备管理能力,物联网平台需要理解接入设备具备的能力以及设备上报数据的消息格式,因此,用户需要在控制台上完成产品模型和编解码插件的开发。基于IoT平台去实现一个物联网解决方案时,需完成的详细操作如下表所示:!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651195992473808566.png)开通设备接入服务后,使用设备接入服务的完整流程主要分为产品开发、应用侧开发、设备侧开发和日常管理。**产品开发**:开发者在进行设备接入前,基于控制台进行相应的开发工作,包括创建产品、创建设备、在线开发产品模型、在线开发插件、在线调试、自助测试和发布产品。**设备侧开发**:设备侧可以通过集成SDK、模组或者原生协议接入物联网平台。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196014489389532.png)**应用侧开发**:通过API的形式对外开放物联网平台丰富的设备管理能力,应用开发人员基于API接口开发所需的行业应用,如智慧城市、智慧园区、智慧工业、车联网等行业应用,满足不同行业的需求。日常管理:真实设备接入后,基于控制台或者API接口,进行日常的设备管理。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196033909397518.png)# 产品模型介绍产品模型又称Profile,用于定义一款接入设备所具备的属性(如颜色、大小、采集的数据、可识别的指令或者设备上报的事件等信息),然后通过厂家、设备类型和设备型号,唯一标识一款设备,便于平台识别。产品模型可以在设备接入控制台进行无码化开发。产品模型是用来描述一款设备“是什么”、“能做什么”以及“如何控制该设备”的文件。开发者通过定义产品模型,在物联网平台构建一款设备的抽象模型,使平台理解该款设备支持的服务、属性、命令等信息,如颜色、开关等。当定义完一款产品模型后,在进行注册设备时,就可以使用在控制台上定义的产品模型。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196061747233784.png)在华为云物联网平台中,产品模型是设备接入的关键内容,里面包含了这个设备所提供的能力与服务,同时还包含了设备上下行的数据格式。例如,在设备上报数据到平台时,平台会根据上报数据的关键字进行产品模型匹配,并将数据格式与匹配上的产品模型文件进行校验,只有匹配成功的数据才会在平台上保存。如果匹配不成功,物联网平台会将上报的数据作为非法数据进行抛弃。**产品信息**:描述一款设备的基本信息,包括厂商ID、厂商名称、设备类型、协议类型。例如:水表的厂商名称为“HZYB”,厂商ID为“TestUtf8ManuId”,设备类型为“WaterMeter”,协议类型为“CoAP”。**服务能力**:描述设备具备的业务能力。将设备业务能力拆分成若干个服务后,再定义每个服务具备的属性、命令以及命令的参数。以水表为例,水表具有多种能力,如上报水流、告警、电量、连接等各种数据,并且能够接受服务器下发的各种命令。产品模型文件在描述水表的能力时,可以将水表的能力划分五个服务,每个服务都需要定义各自的上报属性或命令。**产品模型案例:智能水表**!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196111245341758.png)!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196120523811661.png)华为云物联网平台提供了多种定义产品模型的方法,开发者可以根据自己需求,选择对应的方法定义产品模型:- 导入库模型(平台预置产品模型)- 上传模型文件(离线开发)- Excel导入- 自定义功能(在线开发)# 设备编解码插件## 编解码插件简介什么是编解码插件?编解码插件能够将终端上报的数据(二进制格式)解码为应用服务器所能“阅读”的数据(JSON格式),将服务器端下行命令数据(JSON格式)编码为终端设备所能“理解执行”的数据(二进制格式)。为什么要使用编解码插件?NB-IoT设备采用二进制格式或者tlv格式数据。NB-IoT设备和IoT平台之间采用的是CoAP协议通讯,CoAP消息的payload为应用层协议数据,应用层数据的格式由设备自行定义。鉴于NB-IoT设备一般对省电要求较高,所以应用层数据一般不采用JSON格式数据。应用服务器端并不理解二进制格式或者tlv格式数据。如何开发编解码插件?编解码插件的开发手段有图形化开发、离线开发和脚本化开发三种,由于插件离线开发较为复杂,且耗时比较长,推荐使用图形化开发编解码插件。图形化开发是指在设备接入控制台,通过可视化的方式快速开发一款产品的编解码插件。离线开发是指使用编解码插件的Java代码Demo进行二次开发,实现编解码功能、完成插件打包和质检等。脚本化开发是指使用JavaScript脚本实现编解码的功能。华为云物联网平台图形化编解码插件开发采用了将原有的插件开发代码进行抽象封装技术,开发者无需了解java编程语言,只需在开发界面将设备码流的格式完成定义,并将码流与profile中的属性关系通过拖拽的方式完成映射,点击部署后Portal会根据开发者的设计自动生成插件并打包部署到物联网平台。对于设备发来的上行消息,首先解析CoAP报文得到应用层数据,然后调用设备厂商提供的插件解码,从而将消息发送到应用平台;对于来自应用平台的下行消息,需要调用设备厂商提供的编解码插件,组装CoAP消息发送到设备,如下图所示。此外编解码插件还负责对平台下发命令和对上报数据的响应进行编码。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196167669498388.png)**数据上报**消息处理流程包括数据上报处理流程和命令下发处理流程,数据上报处理流程如下图所示。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196181000651919.png)当设备和物联网平台完成对接后,一旦设备上电,设备基于在设备上定义的业务逻辑进行数据采集和上报,可以是基于周期或者事件触发。设备可通过以下方式发送数据到物联网平台:**设备消息上报**:设备可以通过消息上报接口将设备的自定义数据上报到平台,平台对设备上报的消息不进行解析和存储,通过数据转发规则转发到华为云其他云服务上进行存储和处理,然后通过其他云服务的控制台或者API接口进行进一步的数据处理。**设备原始数据(二进制)上报**:设备可以通过二进制上报接口上报设备的原始码流,平台通过编解码插件将设备原始数据解析为产品模型定义的JSON格式,解析后的数据上报给设备接入服务进行相关业务处理。**设备属性上报**:设备通过属性上报接口,将产品模型中定义的属性数据上报给平台,平台解析后的数据上报给设备接入服务进行相关业务处理。**网关批量属性上报**:网关设备将批量设备的数据一次性上报到平台,平台解析后的数据上报给设备接入服务进行相关业务处理。在数据上报处理流程中,有两处需要用到编解码插件。1. 将设备上报的二进制码流的数据解码成JSON格式的数据,发送给应用服务器。2. 将应用服务器响应的JSON格式数据编码成二进制码流格式的数据,下发给设备。**命令下发**命令下发是指平台将命令下发到设备,设备响应并执行命令,从而达到平台到设备远程控制的效果。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196226205730612.png)!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196238080734258.png)这里分别列举了LwM2M/CoAP和MQTT这两种协议的立即下发和缓存下发的流程,如图所示。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196249676371979.png)应用下发命令到物联网平台,平台会根据对应的产品信息找到对应的编解码插件,对命令请求进行编码,将命令下发给设备;下发命令成功或失败,会根据下发结果更新命令状态,若设备对命令做出了响应,会将命令状态更新为“执行成功”或“执行失败”。!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196258122705049.png)由于使用MQTT是不需要编解码插件的,直接使用透传的形式,当命令立即下发时,应用下发命令到物联网平台,平台将命令下发至设备,返回执行结果,消息执行结果通知。应用缓存下发命令,当设备不在线时,将命令写入缓存队列,更新消息状态,直到设备上报数据,设备上线,订阅消息下发Topic,消息下发,更新消息状态。设备编解码插件示例:!(https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/29/1651196268445426714.png)
  • [数据加载及处理] 【MindSpore易点通】MindSpore怎么用?第二期:数据加载和处理
    概述本帖的内容包括跟随官方初级课程内容,复现数据集的加载过程。实现了数据集对象的初始化,并定义了对象的成员函数对数据内容进行了批处理。另外通过对coco数据集json文件的解析,理清了数据集的内容,写了一个切分数据集的小脚本,分享给大家。本次学习的课程是 MindSpore手把手安装与体验,视频讲解的非常细致,将常用的公开数据集Cifar10, VOC, COCO等都涉及到了。跟着视频非常轻松就可以使用MindSpore完成数据集的加载。贴一下视频链接:数据加载和处理1 数据集准备使用coco数据为例,基于官网下载数据集的图片(jpg格式)使用官网地址下载annotation文件(json格式)下载完成后,coco数据集的目录结构如下2 数据集对象的初始化所有的数据集对象的初始化都需要用到dataset这个接口,dataset接口内提供了几乎所有常用数据集的生成器(MnistDataset, CocoDataset, Cifar10Dataset,...),如果需要对不常见或自定义的数据集,还可以使用GeneratorDataset进行补充。下面是对coco2017数据集对象的初始化使用了验证集图片和不同的json文件进行实例化,可以用于不同分支的任务3 定义成员函数,内容批处理因为是自定义的内容,所以用到了上面提及的GeneratorDataset接口应用成员函数后的效果如下,列表内每个元素都做了+2的操作4 拓展部分不知道小伙伴有没有遇到过这样的情况,使用coco数据集进行训练或推理的过程,因为网络结果较为复杂,以及coco数据集的精度计算过程本就比较耗时。在前期的调试阶段每次完整的跑完整个训练/验证集,往往大半天就过去了。这让调参数的过程变得异常痛苦,会想要对coco数据集进行裁剪。另一方面,coco数据集的图片文件名并不是连续的,其精度计算过程也和json文件密切相关,单纯的提取出部分图片,后处理的逻辑就不完整了。借着本次学习数据集加载接口的机会,我仔细阅读了一下json文件的内容,发现coco数据用于目标检测的annotation文件(instances_val2017.json)主要包含了以下几个方面内容['info', 'license', 'images', 'annotation', 'categories']其中'images'和‘annotations’和数据集图片关系最为密切'images'内包含有['license', 'file_name', 'coco_url', 'height', 'width', 'date_captured', 'flickr_url', 'id']'annotations'内包含有['segmentation', 'area', 'iscrowd', 'image_id', 'bbox', 'category_id', 'id']只要对这两部分内容进行切分,就可实现json文件的分割,然后用分割后的json文件取提取相应的图片。下面附上我的切分代码import sysimport argparseimport jsonparser = argparse.ArgumentParser(description = "json split for cocodataset")parser.add_argument("--start", type=int, default=0)parser.add_argument("--end", type=int, default=500)parser.add_argument("--ann_file", type=str, default='instances_val2017.json')args_opt = parser.parse_args()start_ids = args_opt.startend_ids = args_opt.endif end_ids < start_ids: print("the index of image end < start.") sys.exit(1) file = open(args_opt.ann_file, encoding='utf-8')js_image_full = json.load(file)images = js_image_full['images'][start_ids:end_ids]annotations = js_image_full['annotations']image_id_list = []for image in images: image_id_list.append(image['id']) ann_new_list = []for ann in annotations: if ann['image_id'] in image_id_list: ann_new_list.append(ann) dict_new = js_image_fulldict_new['images'] = imagesdict_new['annotations'] = ann_new_listprint(f"image lengh: {len(dict_new['images'])}, annotations lengh: {len(dict_new['annotations'])}")json_name = args_opt.ann_filejson_name = json_name.split('.')[0]json_name = json_name + '_' + str(start_ids) + '_to_' + str(end_ids) + '_image.json'print("file name is ", json_name)with open(json_name, 'w') as file_obj: json.dump(dict_new, file_obj)import os, shutilimport argparseimport jsonparser = argparse.ArgumentParser(description = "json split for cocodataset")parser.add_argument("--dataset_path", type=str, default='val2017')parser.add_argument("--ann_file", type=str, default='instances_val2017.json')args_opt = parser.parse_args()file = open(args_opt.ann_file, encoding='utf-8')js_image = json.load(file)images = js_image['images']new_dataset_dir = os.path.join(os.getcwd(), "dataset_collected")os.mkdir(new_dataset_dir)name_list = []for image in images: file_name = image['file_name'] name_list.append(file_name) file_path = os.path.join(args_opt.dataset_path, file_name) assert os.path.exists(file_path) shutil.copyfile(file_path, os.path.join(new_dataset_dir, file_name))
  • [问题求助] 小程序发布出来未找到sitemap,json文件,怎么处理
  • [技术干货] 解析policy.json-原创
    openstack 通过 keystone 用来完成 authenticate 和 authorize 是在每一个模板都要做的,具体的每个模板中都有policy文件也都定义了rules 角色权限“Context is_admin":"role:admin",policy.json 有行和列的俩种写的方法在行的写法中每一行:前都四action 也就是用户执行的操作是什么冒号后面的叫rule 角色用来根据当前上下文来判断当前的 action 是否能让当前的用户执行policv的工作就是来解析rule的要把这个rule解析为相应的对象obiect在外部调用权限认证时根据action 映射到rule中判断是否执行 action role在这里是权限的集合将role中的权限赋予特定的用户拥有特定的权限也方便用户管理但是咱们第一行context_is_admin:role:admin设置的默认角色只有admin 若需其他用户需要自行创建这样就不难理解了其实 policy 就是来控制用户的权限的含义如代码中的含义:{ "context_is_admin":  "role:admin",      上下文为一个用户分配一个admin角色(一个用户可以有多个角色)    "default": "role:admin",                   默认为admin角色     "add_image": "",                            允许创建镜像    "delete_image": "",                          允许删除镜像    "get_image": "",                             允许获取镜像    "get_images": "",                            允许获取多个镜像    "modify_image": "",                          允许修改镜像    "publicize_image": "role:admin",                仅admin角色的用户才能传输镜像    "communitize_image": "",                      允许公开镜像    "copy_from": "",                             允许拷贝从某个地方     "download_image": "",                        允许下载镜像    "upload_image": "",                           允许上传镜像     "delete_image_location": "",                    允许删除特定位置的镜像    "get_image_location": "",                       允许获取特定位置的镜像    "set_image_location": "",                       允许设置特定位置的镜像     "add_member": "",                            允许增加成员    "delete_member": "",                          允许删除成员    "get_member": "",                             允许获取成员    "get_members": "",                            允许获取多个成员    "modify_member": "",                          允许修改成员 "manage_image_cache": "role:admin",  #只有admin角色的用户管理员才可以管理镜像缓存     "get_task": "role:admin",               只有admin角色的用户才可以获取任务    "get_tasks": "role:admin",             只有admin角色的用户才可以获取多个任务    "add_task": "role:admin",             只有admin角色的用户才可以增加任务    "modify_task": "role:admin",        只有admin角色的用户才可以修改任务     "deactivate": "",                            允许关闭所有     "reactivate": "",                             允许激活所有     "get_metadef_namespace": "",         允许获取元数据命名空间    "get_metadef_namespaces":"",        允许获取元数据多个命名空间    "modify_metadef_namespace":"",      允许修改元数据命名空间    "add_metadef_namespace":"",         允许增加元数据命名空间     "get_metadef_object":"",                  允许获取元数据对象    "get_metadef_objects":"",                允许获取元数据多个对象    "modify_metadef_object":"",              允许修改元数据对象    "add_metadef_object":"",                 允许增加元数据对象     "list_metadef_resource_types":"",    允许列出元数据资源类型     "get_metadef_resource_type":"",     允许获取元数据资源类型    "add_metadef_resource_type_association":"",       允许增加元数据资源类型关联     "get_metadef_property":"",             允许获取元数据属性    "get_metadef_properties":"",          允许获取元数据多个属性    "modify_metadef_property":"",       允许修改元数据属性    "add_metadef_property":"",            允许增加元数据属性     "get_metadef_tag":"",                      允许获取元数据标签    "get_metadef_tags":"",                    允许获取元数据多个标签    "modify_metadef_tag":"",                允许修改元数据标签    "add_metadef_tag":"",                     允许增加元数据标签    "add_metadef_tags":""                    允许增加元数据多个标签 }
  • [技术干货] 缓动动画函数的封装方法
    这篇文章主要为大家详细介绍了JavaScript缓动动画函数的封装方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下本文实例为大家分享了JavaScript缓动动画函数的封装代码,供大家参考,具体内容如下本文将从封装缓动动画的以下几个部分进行封装(1、单个属性,2、多个属性,3、缓动框架之回调函数,4、缓动框架之层级与透明度)首先:获取元素样式的兼容方式123456function getStyle(ele,attr){      //获取任意类型的CSS样式的属性值  if(window.getComputedStyle){        return window.getComputedStyle(ele,null)[attr];  }  return ele.currentStyle[attr];}封装单个属性123456789101112131415function animate(ele,attr,target){   //元素(box) 样式(left) 目标值(400)  clearInterval(ele.timer);     //使用定时器时,先清除定时器,防止多个定时器并行  ele.timer = setInterval(function(){    //先定义一个当前值    var leader = parseInt(getStyle(ele,attr)) || 0;   //当这个样式为空时设置为0,获取来的样式值要取整。    var step = (target - leader)/10;    step = step > 0 ? Math.ceil(step) : Math.floor(step);    leader = leader + step;    ele.style[attr] = leader + "px";     //注意设置元素样式,注意加单位    if(Math.abs(target-leader) <= Math.abs(step)){      ele.style[attr] = target + "px";      clearInterval(ele.timer);    }  },25);}封装多个属性12345678910111213141516171819202122232425262728293031function animate(ele,json){   //把样式和目标值放在json中,如:var json = {"left":10,"top":200,"width":300,"height":200}    clearInterval(ele.timer);  ele.timer = setInterval(function(){    //开闭原则,目的保证所有样式都到达目标值    var bool = true;    // 分别单独处理json;    for(k in json){      var attr = k;  //这里的k即上文中的样式      var target = json[k];  //这里的json[k]即上文中的目标值,熟练后直接写k,json[k]。      var leader = parseInt(getStyle(ele,attr)) || 0;      var step = (target - leader) / 10;      step = step > 0 ? Math.ceil(step) : Math.floor(step);      leader = leader + step;      ele.style[attr] = leader + "px";       //如果使用上文中清除定时器的方式,则完成了一个json内容就清除了定时器,显然不能这么做      // if(Math.abs(target - leader) <= Math.abs(step)){        // ele.style[attr] = target + "px";        // clearInterval(ele.timer);      // }      if(target !== leader){  //依据上文定义的bool,遍历json时当有一个样式未完成,则bool值依旧为false。        bool = false;      }    }     //只有所有属性样式都到了指定位置,bool值才变成true    if(bool){        clearInterval(ele.timer);    }  },25);       }缓动框架之回调函数1234567891011121314151617181920212223242526272829function animate(ele,json,fn){    clearInterval(ele.timer);    ele.timer = setInterval(function(){        var bool = true;        for(k in json){                   var leader = parseInt(getStyle(ele,k)) || 0;              var step = (json[k] - leader) / 10;            step = step > 0 ? Math.ceil(step) : Math.floor(step);            leader = leader + step;            ele.style[k] = leader + "px";            if(json[k] !== leader){                bool = false;            }        }        if(bool){            clearInterval(ele.timer);            if(fn){     //此处如果有函数,则掉用,如果没有则自动不执行,当然也可加个判断,if(typeof fn == "function"),当fn类型为函数时。                fn();            }        }    },25);} //调用animate(box,json,function(){      //这里的function是一整个函数体,所以上文中的fn要加();    animate(box,json1,function(){     //当执行完第一个缓动动画时,有function则继续执行。        animate(box,json);    });});缓动框架之层级与透明度123456789101112131415161718192021222324252627282930313233343536function animate(ele,json,fn){  clearInterval(ele.timer);  ele.timer = setInterval(function(){    var bool = true;    for(k in json){      var leader;      if(k === "opacity"){   //如果属性为opacity        leader = getStyle(ele,k) * 100 || 1;  //不能取整,先把它乘100      }else{        leader = parseInt(getStyle(ele,k)) || 0;        }                var step = (json[k] - leader) / 10;       step = step > 0 ? Math.ceil(step) : Math.floor(step);      leader = leader + step;      if(k === "opacity"){         ele.style[k] = leader/100;   //如果是opacity,赋值时在除以100        ele.style.filter = "alpha(opacity="+leader+")";   //兼容IE      }else if(k === "zIndex"){        ele.style[k] = leader;   //直接赋值就是了,不用加单位      }else{        ele.style[k] = leader + "px";      }      if(json[k] !== leader){        bool = false;        console.log(leader);      }    }    if(bool){      clearInterval(ele.timer);      if(fn){        fn();      }    }  },30);}**//注意这里赋值的opacity要乘以100,如:30,100等**以上就是本文的全部内容,希望对大家的学习有所帮助转载自https://www.jb51.net/article/200603.htm
  • [技术干货] VUE package.json属性说明详解
    属性介绍description字符串。用来描述当前项目的大致功能。name此项目包的名称。在不确定自己的包名能否使用之前,请先npm registry 一下,看看当前你喜欢的包名是否已经被占用。version当前项目包的版本号。每一次项目改动时,在即将发布时,都要同步的去更改项目的版本号。一般格式为:x.y.z。意思是:大版本.中版本.小版本keywords放简介,字符串。方便屌丝们在 npm search中搜索homepage项目官网的urlbugs你项目的提交问题的url和(或)邮件地址。这对遇到问题的屌丝很有帮助。{ "url" : "http://github.com/owner/project/issues" , "email" : "project@hostname.com" }你可以指定一个或者指定两个。如果你只想提供一个url,那就不用对象了,字符串就行。如果提供了url,它会被npm bugs命令使用。license你应该要指定一个许可证,让人知道使用的权利和限制的。最简单的方法是,假如你用一个像BSD或者MIT这样通用的许可证,就只需要指定一个许可证的名字,像这样:{ "license" : "BSD" }author项目作者。可以指定name,email,url字段信息。也可以单独使用字符串来表示。{“ author ”: { "name" : "Barney Rubble" , "email" : "b@rubble.com" , "url" : "http://barnyrubble.tumblr.com/" } }contributors项目相关贡献者。是数组。用于罗列对应的贡献人。可以是单独的字符串,也可以分别指定name,email,url等属性。{"contributors ":[ { "name" : "Barney Rubble" , "email" : "b@rubble.com" , "url" : "http://barnyrubble.tumblr.com/" } ]}filesfiles是一个包含项目中的文件的数组。如果命名了一个文件夹,那也会包含文件夹中的文件。(除非被其他条件忽略了)你也可以提供一个.npmignore文件,让即使被包含在files字段中得文件被留下。其实就像.gitignore一样。{ "files": [ "bin/", "templates/", "test/" ]}mainmain字段是一个模块ID,它是一个指向你程序的主要项目。就是说,如果你包的名字叫foo,然后用户安装它,然后require("foo"),然后你的main模块的exports对象会被返回。这应该是一个相对于根目录的模块ID。对于大多数模块,它是非常有意义的,其他的都没啥。{ "main": "bin/index.js"}bin很多包都有一个或多个可执行的文件希望被放到PATH中。(实际上,就是这个功能让npm可执行的)。要用这个功能,给package.json中的bin字段一个命令名到文件位置的map。初始化的时候npm会将他链接到prefix/bin(全局初始化)或者./node_modules/.bin/(本地初始化)。{ "bin" : { "npm" : "./cli.js" } }当你初始化npm,它会创建一个符号链接到cli.js脚本到/usr/local/bin/npm。如果你只有一个可执行文件,并且名字和包名一样。那么你可以只用一个字符串,比如{ "name": "my-program" , "version": "1.2.5" , "bin": "./path/to/program" }// 等价于{ "name": "my-program" , "version": "1.2.5" , "bin" : { "my-program" : "./path/to/program" } }man指定一个单一的文件或者一个文件数组供man程序使用。如果只提供一个单一的文件,那么它初始化后就是man 的结果,而不管实际的文件名是神马,比如:{ "name" : "foo" , "version" : "1.2.3" , "description" : "A packaged foo fooer for fooing foos" , "main" : "foo.js" , "man" : "./man/doc.1" }这样man foo就可以用到./man/doc.1文件了。如果文件名不是以包名开头,那么它会被冠以前缀,下面的:{ "name" : "foo" , "version" : "1.2.3" , "description" : "A packaged foo fooer for fooing foos" , "main" : "foo.js" , "man" : [ "./man/foo.1", "./man/bar.1" ] }会为man foo和man foo-bar创建文件。man文件需要以数字结束,然后可选地压缩后以.gz为后缀。{ "name" : "foo" , "version" : "1.2.3" , "description" : "A packaged foo fooer for fooing foos" , "main" : "foo.js" , "man" : [ "./man/foo.1", "./man/foo.2" ] }会为man foo和man 2 foo创建。repository指定你的代码存放的地方。这个对希望贡献的人有帮助。如果git仓库在github上,那么npm docs命令能找到你。scripts“scripts”是一个由脚本命令组成的hash对象,他们在包不同的生命周期中被执行。key是生命周期事件,value是要运行的命令。config"config" hash可以用来配置用于包脚本中的跨版本参数。在实例中,如果一个包有下面的配置{ "name" : "foo" , "config" : { "port" : "8080" } }然后有一个“start”命令引用了npm_package_config_port环境变量,用户可以通过npm config set foo:port 8001来重写他。dependencies依赖是给一组包名指定版本范围的一个hash。这个版本范围是一个由一个或多个空格分隔的字符串。依赖还可以用tarball或者git URL。请不要将测试或过渡性的依赖放在dependencies。对于引用包的版本号格式,以下都是合法的:{ "dependencies" :   { "foo" : "1.0.0 - 2.9999.9999"   , "bar" : ">=1.0.2 <2.1.2"   , "baz" : ">1.0.2 <=2.3.4"   , "boo" : "2.0.1"   , "qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0"   , "asd" : "http://asdf.com/asdf.tar.gz"   , "til" : "~1.2"   , "elf" : "~1.2.3"   , "two" : "2.x"   , "thr" : "3.3.x"  ,"vue":"*", "element-ui":"" } }devDependencies如果有人要用你的模块,但他们可能不需要你开发所使用的外部测试或者文档框架。在这种情况下,最好将这些附属的项目列在devDependencies中。这些东西会在根目录执行npm link或者npm install的时候初始化,并可以像其他npm配置参数一样管理。peerDependencies你的模块可能要暴露一个特定的接口,并由host文档来预期和指定。比如:{   "name": "tea-latte",   "version": "1.3.5"   "peerDependencies": {     "tea": "2.x"   } }这能保证你的package可以只和tea的2.x版本一起初始化。试图初始化另一个有会冲突的依赖的插件将导致一个错误。因此,确保你的插件的需求约束越弱越好,而不要去把它锁定到一个特定的版本。此属性尽量避免使用bundledDependencies一组包名,他们会在发布的时候被打包进去engines指定项目工作的环境。除非用户设置engine-strict标记,这个字段只是建议值。{ "engines" : { "node" : ">=0.10.3 <0.12", "npm" : "~1.0.20" } }engineStrict如果你确定你的模块一定不会运行在你指定版本之外的node或者npm上,你可以在package.json文件中设置"engineStrict":true。它会重写用户的engine-strict设置。除非你非常非常确定,否则不要这样做。如果你的engines hash过度地限制,很可能轻易让自己陷入窘境。慎重地考虑这个选择。如果大家滥用它,它会再以后的npm版本中被删除。os可以指定你的模块要运行在哪些操作系统中"os" : [ "darwin", "linux" ]你也可以用黑名单代替白名单,在名字前面加上“!”就可以了:"os" : [ "!win32" ]操作系统用process.platform来探测。虽然没有很好地理由,但它是同时支持黑名单和白名单的。cpu如果你的代码只能运行在特定的cpu架构下,你可以指定一个"cpu" : [ "x64", "ia32" ]就像os选项,你也可以黑一个架构:"cpu" : [ "!arm", "!mips" ]cpu架构用process.arch探测。preferGlobal如果包主要是需要全局安装的命令行程序,就设置它为true来提供一个warning给只在局部安装的人。它不会真正的防止用户在局部安装,但如果它没有按预期工作它会帮助防止产生误会。{" preferGlobal ":true}private如果你设置"private": true,npm就不会发布它。这是一个防止意外发布私有库的方式。如果你要确定给定的包是只发布在特定registry(如内部registry)的,用publishConfighash的描述来重写registry的publish-time配置参数。publishConfig这是一个在publish-time使用的配置集合。当你想设置tag或者registry的时候它非常有用,所以你可以确定一个给定的包没有打上“lastest”的tag或者被默认发布到全局的公开registry。任何配置都可以被重写,但当然可能只有“tag”和“registry”与发布的意图有关。
  • [问题求助] AppCube标准页面-组件-上传,文件存储在obs,上传成功后用预置库XLSX转Json 报错?
    【功能模块】【操作步骤&问题现象】1、上传excel文件,上传成功后用预置库XLSX转json报错,上传组件返回的数据不满足XLSX方法的入参要求?2、之前发过贴在,按照反馈更改后,还是报错!麻烦再看下【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [问题求助] atlas200dk profiling导致Init失败
    如题,当做profiling时,aclInit()初始化会失败;aclInit() 的config参数是json文件,正常内容为空: {}; 运行没有问题;用msprof工具和acl.json做profiling会出现同样的问题;用msprof工具如下,报错:100000/usr/local/Ascend/driver/tools/msprof --output=./profile --application="/usr/local/atlas/main /usr/local/atlas/models"   --sys-hardware-mem=on --environment="LD_LIBRARY_PATH=/usr/local/atlas/lib/:$LD_LIBRARY_PATH直接运行没有问题:/usr/local/Ascend/driver/tools/msprof --output=./profile --sys-devices=0 --sys-period=100 --sys-hardware-mem=on在acl.json中配置如下时,报同样的错误100000:设备信息如下,cann版本5.0.3alpha002:
  • [问题求助] 训练数据集的标签txt格式文件如何转换成json格式
  • [技术干货] JS 获取焦点失去焦点时修改输入框的样式【不写代码浑身难受】
    随着大数据的时代,用户体验让我们对操作本身简答逻辑不在陌生,而一些特效让操作元素更加直观,当然对直观的就是输入框的一些特效。简直是玩花了,为了让用户更加清除自己输入的是那一项,我们可以在获取焦点和失去焦点时添加一些样式。核心代码 const enter = document.querySelector('.enter') const fCss = enter.getAttribute("data-fCss") const bCss = enter.getAttribute('data-bCss') const bClass = enter.getAttribute('data-bClass') const fClass = enter.getAttribute('data-fClass') //getAttribute() 返回的是指定属性的值 //console.log(bCss, bCss, bClass, fClass); {"backgroundColor":"blue"} {"backgroundColor":"pink"} bborder footer //将字符串转化为JSON对象 function strToJson(str) { //JSON.parse方法用于将JSON字符串转化成对象:这种方式能将字符串解析成json对象 return typeof str == 'object' ? JSON.parse(str) : (new Function('return' + str))(); } //设置样式 function setCss(_this, Cssoption) { if (!_this || _this.nodeType === 3 || _this.nodeType === 8 || !_this.style) { return } for (let cs in Cssoption) { _this.style[cs] = Cssoption[cs] console.log(Cssoption, cs); } return _this } //获取焦点添加样式 function foceshandle() { fCss && setCss(this, strToJson(fCss)) fClass && (this.className = fClass) } //失去焦点添加样式 function blurhandle() { bCss && setCss(this, strToJson(bCss)) bClass && (this.className = bClass) } enter.addEventListener('focus', foceshandle) enter.addEventListener('blur', blurhandle)逻辑说明:getAttribute() 返回的是指定属性的值console.log(bCss, bCss, bClass, fClass);    {"backgroundColor":"blue"} {"backgroundColor":"pink"} bborder footer 代码可以通过  fCss && setCss(this, strToJson(fCss))   and     fClass && (this.className = fClass)   实现修改元素的行内样式与class的修改通过逻辑 ’与‘ 来判断 fCss   与  setCss(this, strToJson(fCss))  是否为空 ,代码理解比较简单,但是代码逻辑时很好模板。
总条数:114 到第
上滑加载中