博客 页面 5

为什么wifi接入app显示设备离线

blinker会自动获取设备状态,通常用户不需要做任何处理,但当你错误编写程序时,可能会造成状态反馈失败或者不及时的问题,这时blinker App就会显示该设备 离线。为了帮助开发者更好的调试程序,这里我对blinker app的判断逻辑,及调试方法做一些讲解。

blinker App如何判断设备是否在线?  
blinker App在 App打开时、进入设备页面时、在设备页面中每隔一定时间 会向设备发送心跳请求,内容为{“get”:”state”}。  
设备收到请求后,会返回{“state”:”online”},app接收到这个返回,即会显示设备在线。

app中显示设备离线,并不等于设备没有连接上mqtt,但可以肯定的是:你的设备没有响应或者错误响应了app发出的心跳请求。

哪些情况可能照成显示离线?
1. 程序没有成功上传到开发板  
解决办法:重新上传,上传后打开串口监视器,确认程序正确运行  

2. 程序中没有设置正确的ssid和密码,导致没有连接上网络  
解决办法:设置后再重新上传程序,上传后打开串口监视器,确认程序正确运行  

3. 程序错误,导致程序运行不正确  
解决办法:先使用并理解blinker例程,再自由发挥  

4. 开发板供电不足   
解决办法:换电源、换USB口 或者 在vcc和gnd间并电容

对于程序错误造成的离线,如何调试?
在程序初始化时添加debugAll,获取更详细的调试信息。
arduino程序如下:

void setup()
{
    Serial.begin(115200);
    BLINKER_DEBUG.stream(Serial);
    BLINKER_DEBUG.debugAll();
}

然后通过串口调试,查看设备是否正确接收到{“get”:”state”}并响应{“state”:”online”}

如何修复错误?
笨办法:逐句注释掉自己写的代码,看看是那一句造成的反馈错误  
正常的办法:理解blinker程序逻辑,通过调试信息,分析程序哪里造成了反馈错误或不及时  

摇杆组件使用说明

应一些重要用户要求,在blinker app 2.4.4中我们恢复了摇杆组件的使用权限。

因为摇杆控制,会发送较多消息,直接提高了我们服务运行成本,因此我们目前只面向付费用户提供该组件。
关于摇杆组件使用说明如下:

1.在mqtt通信状态下,触摸停顿即会发送摇杆数据;
2.如需提高摇杆组件通信频率,你可以使用局域网通信(wifi接入后,让设备和app在同一局域网中运行,即会切换到局域网通信) 或 使用蓝牙接入设备;
3.你可以添加一个调试组件,方便查看摇杆组件发送了什么数据;
4.设备请不要频繁向app反馈信息,可能会照成通信锁死,或app卡顿;

Mqtt连接返回码

 Connect Return code values
ValueReturn Code ResponseDescription
00x00 Connection AcceptedConnection accepted
10x01 Connection Refused, unacceptable protocol versionThe Server does not support the level of the MQTT protocol requested by the Client
20x02 Connection Refused, identifier rejectedThe Client identifier is correct UTF-8 but not allowed by the Server
30x03 Connection Refused, Server unavailableThe Network Connection has been made but the MQTT service is unavailable
40x04 Connection Refused, bad user name or passwordThe data in the user name or password is malformed
50x05 Connection Refused, not authorizedThe Client is not authorized to connect
6-255 Reserved for future use

ionic Native插件封装

在项目升级到ionic5/angular9后,发现部分cordova插件用不了了。

添加ngzone.run后解决了部分插件的报错。

猜测是ivy编译造成,最好的解决办法还是按ionic标准封装cordova插件。

ionic Native插件本质上是对cordova插件的封装,其不实现功能,更多的只是提供ts和ngx的支持。

官方文档

1.创建插件封装器

First, let’s start by creating a new plugin wrapper from template.

// Call this command, and replace PluginName with the name of the plugin you wish to add
// Make sure to capitalize the first letter, or use CamelCase if necessary.

gulp plugin:create -n PluginName

// add -m flag to get a minimal template to start with
gulp plugin:create -m -n PluginName

Running the command above will create a new directory src/@ionic-native/plugins/plugin-name/ with a single file in there: index.ts. This file is where all the plugin definitions should be.

Let’s take a look at the existing plugin wrapper for Geolocation to see what goes into an Ionic Native plugin (comments have been removed for clarity):

@Plugin({
  plugin: 'cordova-plugin-geolocation',
  pluginRef: 'navigator.geolocation'
})
@Injectable()
export class Geolocation {

  @Cordova()
  getCurrentPosition(options?: GeolocationOptions): Promise<Geoposition> { return; }

  @Cordova({
    callbackOrder: 'reverse',
    observable: true,
    clearFunction: 'clearWatch'
  })
  watchPosition(options?: GeolocationOptions): Observable<Geoposition> { return; }
}

First and foremost, we want to create a class representing our plugin, in this case Geolocation.

@Injectable()
class Geolocation {

}

Class Metadata

Next, we need to specify some information about this plugin. Ionic Native is written in TypeScript and makes use of a feature called decorators. Long story short, decorators allow us to modify or add info to classes and properties using a declarative syntax.

For example, the @Plugin decorator adds information about the plugin to our Geolocation class:

@Plugin({
  plugin: 'cordova-plugin-geolocation',
  pluginRef: 'navigator.geolocation'
})
@Injectable()
export class Geolocation {

}

Here, plugin is the name of the plugin package on npm and used when calling cordova plugin add.

pluginRef refers to the where on window the underlying Cordova plugin is normally exposed. For example, in the case of the Cordova Geolocation plugin, normally you would make calls like window.navigator.geolocation.getCurrentPosition({}, success, error), so the pluginRef in this case is navigator.geolocation.

Class Methods

Now all that’s left is to add the plugin methods, in this case getCurrentPosition and watchPosition.

Let’s take a look at getCurrentPosition first.

  @Cordova()
  getCurrentPosition(options?: GeolocationOptions): Promise<Geoposition> { return }

It’s just a stub. The return is only there to keep the TypeScript type-checker from complaining since we indicate that getCurrentPosition returns a Promise<Geoposition>.

By default, the @Cordova decorator wraps the plugin callbacks in a Promise that resolves when the success callback is called and rejects when the error callback is called. It also ensures that Cordova and the underlying plugin are available, and prints helpful diagnostics if they aren’t.

Next, let’s look at the watchPosition method.

  @Cordova({
    callbackOrder: 'reverse',
    observable: true,
    clearFunction: 'clearWatch'
  })
  watchPosition(options?: GeolocationOptions): Observable<Geoposition> { return }

The @Cordova decorator has a few more options now.

observable indicates that this method may call its callbacks multiple times, so @Cordova wraps it in an Observable instead of a Promise.

callbackOrder refers to the method signature of the underlying Cordova plugin, and tells Ionic Native which arguments are the callbacks to map to the wrapping Promise or Observable. In this case, the signature is watchPosition(success, error, options), so we need to tell @Cordova that the callbacks are the first arguments, not the last arguments. For rare cases, you can also specify the options successIndex and errorIndex to indicate where in the argument list the callbacks are located.

clearFunction is used in conjunction with the observable option and indicates the function to be called when the Observable is disposed.

Testing your changes

You need to run npm run build in the ionic-native project, this will create a dist directory. The dist directory will contain a sub directory @ionic-native with all the packages compiled in there. Copy the package(s) you created/modified to your app’s node_modules under the @ionic-native directory. (e.g. cp -r dist/@ionic-native/plugin-name ../my-app/node_modules/@ionic-native/).

Cleaning the code

You need to run npm run lint to analyze the code and ensure its consistency with the repository style. Fix any errors before submitting a PR.

‘Wrapping’ Up

That’s it! The only thing left to do is rigorously document the plugin and its usage. Take a look at some of the other plugins for good documentation styles.

Commit Message Format

We have very precise rules over how our git commit messages can be formatted. This leads to more readable messages that are easy to follow when looking through the project history. But also, we use the git commit messages to generate the our change log. (Ok you got us, it’s basically Angular’s commit message format).

type(scope): subject

Type

Must be one of the following:

  • fix: A bug fix
  • feat: A new feature
  • docs: Documentation only changes
  • style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
  • refactor: A code change that neither fixes a bug nor adds a feature
  • perf: A code change that improves performance
  • test: Adding missing tests
  • chore: Changes to the build process or auxiliary tools and libraries such as documentation generation

Scope

The scope could be anything specifying place of the commit change. For example, the name of the plugin being changed

Subject

The subject contains succinct description of the change:

  • use the imperative, present tense: “change” not “changed” nor “changes”
  • do not capitalize first letter
  • do not place a period (.) at the end
  • entire length of the commit message must not go over 50 characters

Ionic Native Decorators

Plugin

A decorator to wrap the main plugin class, and any other classes that will use @Cordova or @CordovaProperty decorators. This decorator accepts the following configuration:

  • pluginName: Plugin name, this should match the class name
  • plugin: The plugin’s NPM package, or Github URL if NPM is not available.
  • pluginRef: The plugin object reference. Example: ‘cordova.file’.
  • repo: The plugin’s Github Repository URL
  • install: (optional) Install command. This is used in case a plugin has a custom install command (takes variables).
  • platforms: An array of strings indicating the supported platforms.

Cordova

Checks if the plugin and the method are available before executing. By default, the decorator will wrap the callbacks of the function and return a Promise. This decorator takes the following configuration options:

  • observable: set to true to return an Observable
  • clearFunction: an optional name of a method to clear the observable we returned
  • clearWithArgs: This can be used if clearFunction is set. Set this to true to call the clearFunction with the same arguments used in the initial function.
  • sync: set to true if the method should return the value as-is without wrapping with Observable/Promise
  • callbackOrder: set to reverse if the success and error callbacks are the first two arguements of the method
  • callbackStyle: set to node if the plugin has one callback with a node style (e.g: function(err, result){}), or set to object if the callbacks are part of an object
  • successName: Success function property name. This must be set if callbackStyle is set to object.
  • errorName: Error function property name. This must be set if callbackStyle is set to object.
  • successIndex: Set a custom index for the success callback function. This doesn’t work if callbackOrder or callbackStyle are set.
  • errorIndex: Set a custom index for the error callback function. This doesn’t work if callbackOrder or callbackStyle are set.
  • eventObservable: set to true to return an observable that wraps an event listener
  • event: Event name, this must be set if eventObservable is set to true
  • element: Element to attach the event listener to, this is optional, defaults to window
  • otherPromise: Set to true if the wrapped method returns a promise
  • platforms: array of strings indicating supported platforms. Specify this if the supported platforms doesn’t match the plugin’s supported platforms.

Example:

@Cordova()
someMethod(): Promise<any> { return; }

@Cordova({ sync: true })
syncMethod(): number { }

CordovaProperty

Checks if the plugin and property exist before getting/setting the property’s value

Example:

@CordovaProperty()
someProperty: string;

CordovaCheck

Checks if the plugin exists before performing a custom written method. By default, the method will return a promise that will reject with an error if the plugin is not available. This wrapper accepts two optional configurations:

  • observable: set to true to return an empty Observable if the plugin isn’t available
  • sync: set to true to return nothing if the plugin isn’t available

Example:

@CordovaCheck()
someMethod(): Promise<any> {
  // anything here will only run if the plugin is available
}

CordovaFunctionOverride

Wrap a stub function in a call to a Cordova plugin, checking if both Cordova and the required plugin are installed.

Example:

@CordovaFunctionOverride()
someMethod(): Observable<any> { return; }

deno与ts-node的区别

Deno is more like Node than like ts-node, i.e. it is a JS runtime based on V8. Unlike Node, Deno contains the TypeScript compiler. Deno is not part of the Node/npm ecosystem.

ts-node on the other hand is a Node.js module that uses the TypeScript compiler to transpile TypeScript code and run it in Node. ts-node is part of the Node/npm ecosystem.

Deno is fast. See below.

Deno and ts-node similarities

  • They both run TypeScript code
  • They both run on Linux, Mac and Windows (but ts-node also on SmartOS and AIX)
  • They both use the Google V8 JavaScript engine (ts-node via node that it uses under the hood)

Deno and ts-node differences

ts-node

  • ts-node is a Node.js module
  • it is written in Node.js
  • it’s installed with npm
  • it uses the TypeScript compiler as a peer dependency
  • it installs its own dependencies
  • as a runtime it uses Node which is written in C++ using libuv

Deno

  • deno is a standalone executable
  • it doesn’t use Node.js
  • it is distributed as a single binary
  • it contains the TypeScript compiler as a V8 snapshot
  • it has no dependencies
  • it is a runtime written in Rust using Tokio

Maturity

ts-node

ts-node relies on the Node.js runtime so it is fair to include it here:

  • Node.js was released in 2009, the latest LTS version is 10.15.3
  • npm was released in 2010, version included in Node LTS is 6.4.1
  • ts-node was released in 2015, the latest version is 8.0.3

Deno

Deno is itself a runtime so it doesn’t use anything else:

  • Deno was released in 2018, the latest version is 0.3.6

Popularity

GitHub:

Stack Overflow:

Libraries

ts-node

You can use all Node libraries available on npm

(currently there are 955,263 packages on npm, not all of them for Node but still a lot)

The Node libraries that are available on npm even if they were originally written in TypeScript are usually published in a form transpiled to JavaScript with additional type definitions in *.d.ts files (included in the npm package or installed separately from the @types namespace).

Deno

There are 55 third-party modules on https://deno.land/x/ and 56 libraries and tools on https://github.com/denolib/awesome-deno#modules (I didn’t check if all are the same)

The Deno libraries are just TypeScript files.

Installation difference

ts-node

  • you install Node.js
  • you install typescript and ts-node with their dependencies with npm
    • npm install typescript ts-node
    • it installs 10 npm modules and puts 44MB in 212 files into node_modules

Deno

Your code differences

ts-node

  • your code works the same as if it were transpiled with tsc and run with node (because it is under the hood)
  • you can use the Node API
  • you can use all built-in Node modules
  • you can use modules from npm
  • you can import files using relative paths (usually without .ts suffix)
  • you can import the dependencies installed with npm (or yarn) in node_modules

Deno

  • your code doesn’t work the same as in Node (because it isn’t run with Node)
  • you use the Deno API
  • you can use the Deno built-in modules
  • you can use other Deno modules that are available
  • you can import files using relative paths (always with .ts suffix!)
  • you can import URLs directly from the Web (no need for npm install)

Examples

Here is an example of publishing a minimal library written in TypeScript and using it.

Creating and using a TypeScript library with Node and ts-node

This is what I am doing right now with an example project on:

https://github.com/rsp/node-ts-hello

Creating library:

  1. find a name that is free on npm (no longer enough, see below)
  2. create repo on GitHub
  3. create package.json with npm init
  4. install TypeScript compiler with npm install typescript
  5. decide if you’re keeping package-lock.json in the repo (there are pros and cons)
  6. create a src dir where you will keep TypeScript files
  7. add hello.ts to src
  8. add tsconfig.json file and make sure to:
    • add "src/**/*" to "include"
    • add dependencies and your own types to "paths"
    • add "outDir": "dist" to put the JS files in a known place
    • add the dist directory to .gitignore so that compiled files are not in git
    • add the same as in .gitignore but without dist in .npmignore
      (or otherwise you will not publish the most important files, see below)
    • add "declaration": true so you have *.d.ts files generated
  9. add "main": "dist/hello.js" in package.json (note the “js” suffix)
  10. add "types": "dist/hello.d.ts" in package.json (note the “ts” suffix)
  11. add "build": "tsc" to package.json (watch out for redundant files, see below)
  12. login with npm login (you shouldn’t be logged in all the time – see: Now Pushing Malware: NPM package dev logins slurped by hacked tool popular with coders)
  13. compile the project with npm run build
  14. publish the package with npm publish
    • when you get npm ERR! publish Failed PUT 401 you need to login with npm login
    • when you get npm ERR! publish Failed PUT 403 your package may be “too similar to existing packages” – try renaming it in package.json, rename the repo and update all liks to readme, issues itp. in package.json
  15. logout from npm with npm logout
  16. see your ~/.npmrc and make sure you have nothing like this left:
    • //registry.npmjs.org/:_authToken=...

Using the library in other project using ts-node

  1. create a new directory
  2. create a package.json file with npm init
    • (so that you can install dependencies locally for your new program)
  3. install our library with npm install node-ts-hello
  4. optionally install ts-node with npm install typescript ts-node
    • (unless it’s installed globally)
  5. add hi.ts file that imports our library with:
    • import { hello } from 'node-ts-hello';
    • hello('TS');
  6. run it with npx ts-node hi.ts (if ts-node was installed locally) or ts-node hi.ts (if ts-node was installed globally)
    • if you get errors, see below

Potential problems: I simplified the above a little bit, my actual process of creating that library is described here.

Creating and using a TypeScript library with Deno

This is what I am doing right now with an example project on:

https://github.com/rsp/deno-hello

Creating library:

  1. create repo on GitHub
  2. put hello.ts in the repo

Using library:

  1. Create a file hi.ts with the contents:
    • import { hello } from 'https://raw.githubusercontent.com/rsp/deno-hello/master/hello.ts';
    • hello('TS');
  2. Run your program with deno run hi.ts

The first run will print:

$ deno run hi.ts 
Compiling file:///Users/rsp/talks/deno/hello-deno-test/hi.ts
Downloading https://raw.githubusercontent.com/rsp/deno-hello/master/hello.ts
Compiling https://raw.githubusercontent.com/rsp/deno-hello/master/hello.ts
Hello, TS!

The second run:

$ deno run hi.ts 
Hello, TS!

If you change hi.ts it will be recompiled but the dependencies will not get downloaded again:

$ deno run hi.ts 
Compiling file:///Users/rsp/talks/deno/hello-deno-test/hi.ts
Hello, TS!

(Note that touch hi.ts will not be enough, you need to make the actual changes because Deno checks the file checksum, not the timestamp.)

Speed

ts-node

The speed of starting the ts-node version of our hi.ts from the examples above:

$ time npx ts-node hi.ts 
Hello, TS!

real    0m0.904s
user    0m1.300s
sys     0m0.083s

This is after the dependencies are already installed and after running several times to make sure that all of the caching works. Almost one second.

Deno

The speed of starting the Deno version of our hi.ts from the examples above:

$ time deno run hi.ts 
Hello, TS!

real    0m0.028s
user    0m0.010s
sys     0m0.015s

This is also after the dependencies are already installed and after running several times to make sure that all of the caching works.

More than 32x speed improvement.

Summary

Deno should be compared more with Node than with ts-node because Deno is an entirely new runtime while ts-node is a module for Node so your program run with ts-node really use the Node runtime.

It is a very young project but has already got a lot of traction. It doesn’t have as much documentation or libraries as Node but it means that it may be the best time to get involved because when it gets more popular, and I think it will for many reasons that are beyond the scope of this answer, people who already have experience with it will be needed on the market, like it was with Node.

The program startup speed is already very impressive and I expect more improvements there.

The development speed of using single files with no need for configuration like package.json or node_modules together with a possibility to import dependencies directly from URLs (like on the frontend) will make it possible to work in a different way both for the end user code and for the libraries. We’ll see how it all works in practice but it already looks promising.

原文 https://stackoverflow.com/questions/53428120/deno-vs-ts-node-whats-the-difference

编写了一道逻辑题

单选题,请听题:

夏天到了,你居住的小区垃圾处理不及时,垃圾房外爬蛆飞苍蝇了,你在业主群说物业管理垃圾的人处理的不好。
然后出来了几个业主代表艾特你。
业主甲:虽然我们小区垃圾回收做的不好,但安全啊,至今没有发生过盗窃,谢谢物业人员?。
业主乙:隔壁小区管理的更烂,你看他们垃圾一月才处理一次,所以我们小区很好了?。
业主丙:你经常说我们小区不好,你就是恨我们小区,不喜欢我们小区,就滚去别的小区买房子啊?。
业主丁:觉得物业不好,就去应聘物业,加入他们,让物业变得更好?。

问,哪个业主可以代表你?