-
Notifications
You must be signed in to change notification settings - Fork 4
custom device _system
With version 2.0 the '_system' device has undergone refactoring and now is a device, in a separate flow. The goal of this SW-only custom device is to group some useful extra functionalities. Here an overview of the _system
features, for details see the standard documentation.
This _system property (and the related start_DEAMON node) is SET only one time, some seconds after a node-red restart. Used to do some delayed startup operations on custom devices or to check the devices' status.
_This system property implements the message exchange between tuyaDAEMON instances on lan. It uses the REST interface to connect a remote tuyaDAEMON server. A map of the URLs for the existing tuyaDAMON instances is in CORE, in config 'global' node, named 'remotemap'. _name returns the user-friendly name of this tuyaDAEMON instance.
The user doesn't use directly this property, enough to extend the tuyaDAEMON standard messages so:
{
"remote": "ANDROID",
"device": "switch module #1",
"property": "switch",
"value": "OFF"
}
The global.tuyastatus
variable is the storage of all last values got from devices, structured in device.property.value
, plus some pseudoDP (_t
, _connected
).
The tuyastatus
is automatically updated any GET
and SET
. Some _system
functions allow more control over it.
-
_tuyastatus(std_cmd) Alternative and indirect access to the
global.tuyastatus
structure, regardless of dp capabilities. We can get:- the device list (if
std_cmd
is empty{}
) - the SCHEMA for a device, if
std_cmd.property
is undefined - to GET the last value of a property if
std_cmd.value
is undefined - an unconditioned SET (take care: potentially dangerous) if the
std_cmd
is full.
- the device list (if
-
_doSCHEMA(device) Uses native SCHEMA (if available) or does a SCHEMA simulation for any device (real, virtual, fake) sending ALL GETs available (from
alldevices
definitions), and updating tuyastatus. Returns a list of all DPs tested. -
_doUPDATE(NULL|real|virtual|fake) For all devices connected, does a 'doSCHEMA' command. That can fully update
tuyastatus
, e.g. after a startup. Returns a list of devices.This can be a good check for 'alldevices' definitions: it must run without 'warning messages.
Runs a system command and returns its output.
Any used DB can be controlled via _system
, for DB maintenance and DB data access:
-
_sqlDBlocal(SQL) allows to send a sql-string to a DB and get the answer
- more _sqlDBxxxx properties can be user-defined for all DB used. See core.
The timer functions are build around the 'node-red-contrib-jsontimer'. This implementation allows to define a temporized start for any task (local or remote tuyaDAEMON standard command) using a standard command or a share. The timer itself is simple: it has only one function, to send a stored message at a specific time. The time can be defined in three ways: timeout
(in ms), time
(as 22:13:36.010), and datetime
(unixtimestamp).
The timer doesn't offer any kind of repetitions. But it can handle many timers, identified by an 'id'.
-
_timerON ((id,) timeout:xx|time:yy|datetime:zz, alarmPayload:{<std_cmd>|<share>}) sets a new timer.
-
alarmPayload
can be a standard command (more simple) or a share (more powerful). -
id
is mandatory only if you use_timerOFF
elseid
is auto.
-
-
_timerOFF(id) deletes an existing timer selected by
id
, mandatory. - _timerList() gets the list of all active timers.
A timer can be used also inside a standard share, to have a delay effect on a task triggered by an event, see _system._beep_loop
implementation in global.alldevices
.
Use of _timerON: this command sets a timer to send a TRIGGER5000 to Tuya-cloud, 100 seconds later.
{
"device": "_system",
"property": "_timerON",
"value": {
"timeout": 100000, // or time|datetime
"alarmPayload": { // the delayed command
"device": "_system",
"property": "_doTrigger",
"value": 5000
}
}
}
(obsolete, since 2.2.0 moved to core_TRIGGER)
Benchmarks can be done by repeatedly running a task in free-run and counting the number of runs performed by tuyaDAEMON in a given time.
Some _system
properties simplify the benchmarks:
- _zeroTask: the fastest SW only task, does nothing, and it is without any logging (no debug pad, no DB).
- _zeroLog: like _zeroTask, but with logging (debug pad and DB).
- _benchmark: to SET/GET the tested task (default _zeroTask) and the benchmark duration (default 10000 ms).
- _doBenchmark: SET: trigger to execute a benchmark.
To do a benchmark, choose the task (device
and property
), then:
- To retrigger in free-run the chosen task, add to
global.alldevice.<device&gr;.<<property&gr;
theshare
:
"share": [{
"action": [{
"device": "_system",
"property": "_benchmark_step"
}]}]
note: the _benchmark_step
does is retrigger action only inside a running benchmark, so this share
can be permanent (see global.alldevices._system._zeroTask
and global.alldevices._system._zeroTask
), or you can delete it after the benchmark.
- Use the
_benchmark
property to SET the task:
"payload":{
"device": "_system",
"property": "_benchmark",
"value" {
"device":"_system", // the chosen task GET _system._zeroTask
"property":"_zeroTask",
"value": if_required, // GET/SET
"timeout": 20000 // optional, default 10000 ms
}}
- Use
_doBenchmark
(SET: trigger) to start the benchmark.
In my test server (i7-4777, 3.40 GHz, Win 10) I get 15300/20s for _zeroTask
, 11700/20s for _zeroLog
, and a good 480/20s for a GET from the tuya_bridge real device. Nevertheless, I have set very conservative limits: 1000/10s for output (and SW tasks), and 30/10s for real devices.
note on _zeroLog
SET _zeroLog(value)
returns the value
encoded (see alldevicesnote[8]) using the default
or _zeroLog.type
rules: this allows to do tests changing the _zeroLog.type
in alldevices
.
note
Also _doUPDATE
, with all trace enabled, is a good stress test: if you get any warning, fine-tune global.alldevices
, if you miss any message on debug pad, reduce limits
Some _system
features are about the UI:
-
_toDebug(string|obj)
The
string|obj
is printed on the debug pad by adebug
node. To share results and info between tuyaDAEMON servers. -
_toWarn(string|obj)
The
string|obj
is printed on the debug pad by anode.warn()
call. To share alarms between tuyaDAEMON servers. - **_play(WAV|string) ** Play a sound (WAV) or does text-to-speech function (browser dependent: set language on interface)
- **_beep **
Plays the short beep stored in globals.beep64 as WAV code64. - **_beep_loop(count, interval) **
Example of tuyaDAEMON-chain : repeats 'beep'
count
times, with aninterval
in ms.
A group of properties is present to help the user to build robust and fault-tolerant applications. This is one strong motivation for the tuyaDAEMON project.
Random or malicious events can cause serious problems. Here some accident scenarios:
- _DBase and DB_ALARM node control the MySQL connections (note: this is placed in the CORE flow).
- loss of remote connection: tuya-cloud is out. Also the user control from remote. Only tuyaDAEMON works. _LANnet (and the related LAN_ALARM node) are triggered by this event.
- local WiFi down: all devices are offline. Only the cabled LAN and devices (a siren?) can works. _WiFinet, WiFi_ALARM and _WiFiunconnected (a list of unconnected devices, includes 'disabled' devices) can handle this event.
- AC power off: blackout or external action? Only the UPS devices are available. Good to provide for the WiFi router, one tuyaDEAMON server, the siren, also the IP cams... _ACpower, AC_ALARM and _ACunconnected are triggered by this event.
It is now common for apartment thieves to interrupt the AC power and to use a jammer to disrupt communications. If you build your own security alarm think carefully to choose a good solution.
These are some low-level properties that offer access to CORE functions via messages. This way allows meta-Programmation and can be useful for applications that use REST
or for remote control:
- _doTrigger(number) Offers an alternative way to send TRIGGERs to tuya-cloud. Useful used in 'share' structures (see timer example).
-
_toLowIN(toDev, dev-msg)
The
dev-msg
is sent directly to the tuya-smart-device node, selected bytoDev
(see 'core.low_level_IN' node). To test new device functions. -
_toFastIN(std_msg)
The
standard message
is sent to the 'core.fast_cmds' node to be executed. -
_toStdCmd(std_msg)
The
standard message
is sent to the 'core.std_cmd' node to be executed. -
_toShare(share)
The
share
structure is sent to the 'core.share_IN' node to be processed. -
_toLogging(out_msg)
The
out_msg
(see 'core.logging' node) is processed like any device event.
This _system v 2.0 is now a collection of heterogeneous and basic utilities. It can be extended to meet the user's application needs. Better, it can be split into many SW-only devices, by application fields, to become specialized user's "libraries".