-
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) 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 + the output for any GET. -
_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'. The running timers are maintained with the 'Deploy' and 'Restart flows' operations.
-
_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>.<property>
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 old test server (i7-4777, 3.40 GHz, Win 10) and tuyaDAEMON 2.0 I get 15300/20s for _zeroTask
, 11700/20s for _zeroLog
, and a good 480/20s for a GET from the tuya_bridge real device. Now, using ver. tuyaDAEMON 2.2.0 (i9-11900, 2.50 GHz, win 11) zeroTask more than 2000 run/s and zeroLog more than 1400 run/s.
Using MQTTExplorer, the benchmark results are visible in a chart (In the example zeroTask, min:12148/5s, max:12595/5s):
On ANDROID 11 (H96 Max-V11, CPU RK3319 1.5 GHz 4core) I get 448/10s (zeroTask) and 309/10s (zeroLog). Nevertheless, I impose the very conservative limit of 30/10s MQTT messages for all real devices, to keep low the Tuya-cloud stress.
note on _zeroLog
SET _zeroLog(value)
returns the user value
encoded (see alldevicesnote[8]) using the default
or _zeroLog.type
or _zeroLog.typefield
rules: this allows to do encoding tests changing the _zeroLog
definitions in alldevices
.
about tests
_Also _doUPDATE
, with all trace enabled, is a good stress test: if you get any warning, fine-tune global.alldevices
.
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".