Achronite / node-red-contrib-energenie-ener314rt

Node Red nodes for Energenie ENER314-RT Raspberry Pi board
MIT License
12 stars 3 forks source link

Add MiHome thermostat support #36

Closed red-kooga closed 9 months ago

red-kooga commented 4 years ago

hi, i have some data from debug for the thermostat MIHO069, the debug messages are not as consistent as the radiator valves, it shows the set temperature more often than the room temperature.

openThings_devicePut() device added: 1:14499461 openThings_receive: Returning: {"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776900,"UNKNOWN_0x59":0} test.js-cb: received OTmsg={"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776900,"UNKNOWN_0x59":0} @openThings_receive: Returning: {"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776906,"MOTION_DETECTOR":2,"UNKNOWN_0x2a":0} test.js-cb: received OTmsg={"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776906,"MOTION_DETECTOR":2,"UNKNOWN_0x2a":0} test.js: switching 1:1:false

openThings_receive: Returning: {"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776992,"UNKNOWN_0x59":0} test.js-cb: received OTmsg={"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776992,"UNKNOWN_0x59":0} @openThings_receive: Returning: {"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776997,"REL_HUMIDITY":74,"MOTION_DETECTOR":3,"UNKNOWN_0x2a":1,"UNKNOWN_0x4b":18.000000} //this is the set temperature

*openThings_receive: Returning: {"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602777265,"REL_HUMIDITY":74,"UNKNOWN_0x2a":1}

test.js-cb: received OTmsg={"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602778445,"TEMPERATURE":21.187500,"REL_HUMIDITY":74,"MOTION_DETECTOR":3,"UNKNOWN_0x2a":1,"UNKNOWN_0x4b":18.500000}

openThings_receive: Returning: {"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776227,"BATTERY_LEVEL":3.068848,"UNKNOWN_0x2a":1} test.js-cb: received OTmsg={"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602776227,"BATTERY_LEVEL":3.068848,"UNKNOWN_0x2a":1}

Achronite commented 4 years ago

That's great. So it looks like the new OpenThings parameters sent are:

You should be able to use the 'UNKNOWN_' names as is for now in your flow; I will use this bug to create a mapping of 0x59 to TARGET_C, this can override the cached version needed for the eTRVs.

Any ideas what params 0x2a and 0x59 could be?

I will also map productId 18 (0x12) to "Thermostat" - I guessed wrong at 0x0E :)

DrOwl commented 4 years ago

Hi, nice to see some more working happening, thanks very much for your work. I'm sure this will not be of much help but I have been logging the output from my MIHO069 to a text file for a while.

"UNKNOWN_0x59" only appears on its own log line and only has the value 0

# cat  test-mon.text | jq -c '. | select(.deviceId==14531843) | select(.UNKNOWN_0x59==0) | { BATTERY_LEVEL: .BATTERY_LEVEL, MOTION_DETECTOR: .MOTION_DETECTOR, REL_HUMIDITY: .REL_HUMIDITY, SWITCH_STATE: .SWITCH_STATE, TEMPERATURE: .TEMPERATURE, UNKNOWN_0x2a: .UNKNOWN_0x2a, UNKNOWN_0x4b: .UNKNOWN_0x4b, UNKNOWN_0x59: .UNKNOWN_0x59}' | sort | uniq -c

  13455 {"BATTERY_LEVEL":null,"MOTION_DETECTOR":null,"REL_HUMIDITY":null,"SWITCH_STATE":null,"TEMPERATURE":null,"UNKNOWN_0x2a":null,"UNKNOWN_0x4b":null,"UNKNOWN_0x59":0}

"UNKNOWN_0x2a" cat appear on log line with other parameters and has the values 0, 1 or 2

# cat test-mon.text | jq -c '. | select(.deviceId==14531843) | { UNKNOWN_0x2a: .UNKNOWN_0x2a}' | grep -v ":null" | sort | uniq -c                                                 
  14760 {"UNKNOWN_0x2a":0}
    534 {"UNKNOWN_0x2a":1}
    630 {"UNKNOWN_0x2a":2}

If I can help with any debugging please let me know.

red-kooga commented 4 years ago

That's great. So it looks like the new OpenThings parameters sent are:

  • 0x2a - ?
  • 0x59 - ?
  • 0x4b - TARGET_C

You should be able to use the 'UNKNOWN_' names as is for now in your flow; I will use this bug to create a mapping of 0x59 to TARGET_C, this can override the cached version needed for the eTRVs.

Any ideas what params 0x2a and 0x59 could be?

I will also map productId 18 (0x12) to "Thermostat" - I guessed wrong at 0x0E :)

i am not sure what 0x2a and 0x59 are, i did have a node report it as temperature {"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602858174,"UNKNOWN_0x59":18.5625} \ current temperature i also had control popup in debug {"mfrId":4,"productId":18,"deviceId":14499461,"control":1,"product":"Unknown","joined":1}, i will keep trying different settings on the thermostat

red-kooga commented 4 years ago

almost forgot i had this in debug {"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602858104,"TEMPERATURE":18.5625,"REL_HUMIDITY":75,"UNKNOWN_0x2a":1} only once shown temperature and humidity together in node-red

red-kooga commented 4 years ago

0x2a follows SWITCH_STATE, i haven't seen 0x2a show 2 yet, mihome app keeps crashing, i'll try when it settles

{"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602861707,"UNKNOWN_0x2a":0,"SWITCH_STATE":0}

{"deviceId":14499461,"mfrId":4,"productId":18,"timestamp":1602861837,"REL_HUMIDITY":65,"UNKNOWN_0x2a":1,"SWITCH_STATE":1}

Achronite commented 4 years ago

It looks like it may require a new specific node creating to support the thermostat properly.

Have either of you tried setting the temperature using the eTRV node? I would like to know if it needs to use the command caching approach (like the eTRV node) or it 'listens' for commands constantly (like the control & monitor node).

Achronite commented 4 years ago

Also the 0x2a parameter - looking at the manual could it be eco/comfort or seasonal mode?

It seems that either 4b or 59 could be the target temperature. It would be good to confirm...

red-kooga commented 4 years ago

I tried the trv node for the thermostat, it reports most things fine, but ignores commands. I will check the different modes when I get a chance

On Sat, 17 Oct 2020, 10:56 Achronite, notifications@github.com wrote:

Also the 0x2a parameter - looking at the manual https://energenie4u.co.uk/res/pdfs/MIHO069%20Full%20User%20GuideV2.0.pdf could it be eco/comfort or seasonal mode?

It seems that either 4b or 59 could be the target temperature. It would be good to confirm...

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Achronite/node-red-contrib-energenie-ener314rt/issues/36#issuecomment-710787668, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZG6S6NTBHAFXJ5G5ZEUFDSLFS4XANCNFSM4SSGZISA .

DrOwl commented 4 years ago

I mailed the Energenie Technical Team,

"Thank you for getting in touch the parameters are:

0x2a is the On/Off mode

0x59 is the Wake up message "

Achronite commented 4 years ago

The TRV node is not going to work, it uses command caching, and that only works with an eTRV productId.

There are 2 things I could try:

1) Make the eTRV node also send commands when it receives a TEMPERATURE message from thermostat (very easy change).

2) Enable advanced parameter passing for the 'control & monitor' node; this sends requests immediately. This would confirm that the thermostat continuously listens, and also which commands could be sent to the thermostat.

If all goes well a new specific node could be added for the thermostat.

DrOwl commented 4 years ago

Some more details from the Energenie Technical Team,

Thank you for your patience. I haven't found much in the way of details for 0x59, only a single character, Y is shown for the wakeup integer.

For 0x2a, the modes are as follows:

0 The Thermostat is set to standby, it will report the temperature but will not turn the boiler on if the temperature is low.

1 The Thermostat is set to ON, it will report the temperature and will turn the boiler on if the temperature is low.

2 The thermostat is set to Always ON, it will report the temperature but will not turn the boiler off if the temperature is high.

Achronite commented 4 years ago

Just to let you know I'm working on this. I've built a new node capable of sending any immediate commands to an OpenThings device, including the thermostat. I would like to release an early beta for some testing. Are you OK to help with this? (it would mean downloading and installing the node manually from github).

DrOwl commented 4 years ago

Sure no problem happy to test the beta

DrOwl commented 4 years ago

Just a quick update, i did a clone of the develop branch and have installed them on my testing system... one problem not sure why but i get the below error:

drowl@raspberrypi:~/.node-red $ npm install  ../code/node-red-contrib-energenie-ener314rt/
npm ERR! code ETARGET
npm ERR! notarget No matching version found for energenie-ener314rt@^0.4.0.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.
npm ERR! notarget 
npm ERR! notarget It was specified as a dependency of 'node-red-contrib-energenie-ener314rt'
npm ERR! notarget 

for now I just hacked the package.json to energenie-ener314rt@^0.3.0.

When I try to send a message on the new "Control/Monitor" node I get "TypeError: ener314rt.openThingsCmd is not a function"

Achronite commented 4 years ago

Hi @DrOwl , the reason you have this error is that I have also updated the dependent node.js library to add core functionality that this package then depends upon. To fix this you will also need to clone the develop branch of the dependent package: energenie-ener314rt into the node_modules directory of node-red-contrib-energenie-ener314rt, replacing the 0.3.x version of the dependent library (this is usually auto installed for you, but it hasn't been released yet!).

You can compile the C code by using the command node-gyp rebuild.

So in summary, commands will be something like this:

$ cd node-red-contrib-energenie-ener314rt/node_modules
$ git clone --branch develop https://github.com/Achronite/energenie-ener314rt.git
$ cd energenie-ener314rt
$ node-gyp rebuild
$ node-red-start

EDIT: I've enabled tracing in the develop branch so that we can see params etc

DrOwl commented 4 years ago

I have installed the module as per your instructions... last time i had installed the energenie-ener314rt dev version but it was outside of node-red-contrib-energenie-ener314rt!

I now see logs such as {"deviceId":14531843,"mfrId":4,"productId":18,"timestamp":1604329962,"TEMPERATURE":18.875,"REL_HUMIDITY":65,"ON_OFF_MODE":1}

I can send messages such as "Set temp" without error but it does not actually set the temperature.

If i try to set on or off I get an error:

Device currently unknown, retry later

That is with a message.payload of

{
    "command": 170,
    "data": 0
}
Achronite commented 4 years ago

Are you using the new Control/Monitor node? It should have the thermostat as the default icon.

Can you send more debug info? You should be getting things like:

@calling openThings_cmd(2,8294,243,0,20)
openThings_cmd(): deviceId=8294, cmd=243, data=0
openThings_build_msg: productId=2, deviceId=8294, cmd=243, data=0 cmd=OTCP_SWITCH_STATE msglen=14
Built payload (unencrypted): 13,4,2,124,1...
Built payload (encrypted): 13,4,2,12...
openThings_cmd(): sending...
radio_send_payload(): 20 tx payloads
openThings_cmd(): sent
openThings_cmd() returned 0

If you can't see these messages, it could be you downloaded before I updated trace.h. You may need a full recompile node-gyp configure build. There is also a mode FULLTRACE which gives a ton more info. (file: node-red-contrib-energenie-ener314rt/node_modules/energenie-ener314rt/C/energenie/trace.h)

// uncomment next line to enable trace debug
#define TRACE_POSIX
//#define FULLTRACE
DrOwl commented 4 years ago

I did the clone today...

two example messages: Change temperature

Nov 02 20:00:44 raspberrypi Node-RED[21642]: calling openThings_cmd(18,14531843,244,28,20)
Nov 02 20:00:44 raspberrypi Node-RED[21642]: openThings_cmd(): deviceId=14531843, cmd=244, data=28
Nov 02 20:00:44 raspberrypi Node-RED[21642]: openThings_build_msg: productId=18, deviceId=14531843, cmd=244, data=28 cmd=OTCP_TEMP_SET msglen=15
Nov 02 20:00:44 raspberrypi Node-RED[21642]: Built payload (unencrypted): 14,4,18,124,194,221,189,3,244,146,28,0,0,29,186,
Nov 02 20:00:44 raspberrypi Node-RED[21642]: Built payload (encrypted): 14,4,18,124,194,200,32,133,152,63,86,151,208,109,95,
Nov 02 20:00:44 raspberrypi Node-RED[21642]: openThings_cmd(): sending...
Nov 02 20:00:44 raspberrypi Node-RED[21642]: radio_send_payload(): 20 tx payloads
Nov 02 20:00:45 raspberrypi Node-RED[21642]: openThings_cmd(): sent
Nov 02 20:00:45 raspberrypi Node-RED[21642]: openThings_cmd() returned 0

Power off

Nov 02 20:00:50 raspberrypi Node-RED[21642]: calling openThings_cmd(18,14531843,170,0,20)
Nov 02 20:00:50 raspberrypi Node-RED[21642]: openThings_cmd(): deviceId=14531843, cmd=170, data=0
Nov 02 20:00:50 raspberrypi Node-RED[21642]: openThings_build_msg: productId=18, deviceId=14531843, cmd=170, data=0 cmd=openThings_cmd() returned -1
Nov 02 20:00:50 raspberrypi Node-RED[21642]: 2 Nov 20:00:50 - [error] [openThings-cmd:themo-test2] Device currently unknown, retry later

Ill try some full trace...

Maybe we can arrange access for you ;)

DrOwl commented 4 years ago

With FullTrace Change temp

Nov 02 20:06:50 raspberrypi Node-RED[22396]: calling openThings_cmd(18,14531843,244,28,20)
Nov 02 20:06:50 raspberrypi Node-RED[22396]: openThings_cmd(): deviceId=14531843, cmd=244, data=28
Nov 02 20:06:50 raspberrypi Node-RED[22396]: openThings_build_msg: productId=18, deviceId=14531843, cmd=244, data=28 cmd=OTCP_TEMP_SET msglen=15
Nov 02 20:06:50 raspberrypi Node-RED[22396]: Built payload (unencrypted): 14,4,18,103,198,221,189,3,244,146,28,0,0,29,186,
Nov 02 20:06:50 raspberrypi Node-RED[22396]: Built payload (encrypted): 14,4,18,103,198,98,131,72,186,7,93,8,108,160,29,
Nov 02 20:06:50 raspberrypi Node-RED[22396]: openThings_cmd(): sending...
Nov 02 20:06:50 raspberrypi Node-RED[22396]: radio_mod_transmit()
Nov 02 20:06:50 raspberrypi Node-RED[22396]: writereg 1 12
Nov 02 20:06:50 raspberrypi Node-RED[22396]: _wait_ready
Nov 02 20:06:50 raspberrypi Node-RED[22396]: _wait_txready
Nov 02 20:06:50 raspberrypi Node-RED[22396]: radio_send_payload(): writereg 60 14
Nov 02 20:06:50 raspberrypi Node-RED[22396]: 20 tx payloads
Nov 02 20:06:51 raspberrypi Node-RED[22396]: *|**|***|***|**|***|**|***|***|**|***|**|***|***|**|***|***|**|***|**|***irqflags1,2=176,8
Nov 02 20:06:51 raspberrypi Node-RED[22396]: writereg 1 16
Nov 02 20:06:51 raspberrypi Node-RED[22396]: _wait_ready
Nov 02 20:06:51 raspberrypi Node-RED[22396]: *openThings_cmd(): sent
Nov 02 20:06:51 raspberrypi Node-RED[22396]: openThings_cmd() returned 0

Power off

Nov 02 20:07:06 raspberrypi Node-RED[22396]: calling openThings_cmd(18,14531843,170,0,20)
Nov 02 20:07:06 raspberrypi Node-RED[22396]: openThings_cmd(): deviceId=14531843, cmd=170, data=0
Nov 02 20:07:06 raspberrypi Node-RED[22396]: openThings_build_msg: productId=18, deviceId=14531843, cmd=170, data=0 cmd=openThings_cmd() returned -1
Nov 02 20:07:06 raspberrypi Node-RED[22396]: 2 Nov 20:07:06 - [error] [openThings-cmd:themo-test2] Device currently unknown, retry later
DrOwl commented 4 years ago

Arr okay, so I dont see a type for "170 / aa" in "openThings_build_msg"

Achronite commented 4 years ago

So it looks like the 'Device currently unknown' error is mis-reported. It should be 'command unknown' for the command node.

I've added support for command 170 (0xAA), I'm assuming it is unsigned int for data = 0,1,2

I've also added 'generic' support for any other unknown parameter, so that you can play. I have had to assume an unsigned integer as 'data' type for UNKNOWN commands; if the type is wrong it will probably fail. You should be able to try different commands to see what works. The OpenThings spec states that a command parameter is usually the response param code + 0x80. I have not fixed the 'command unknown' error message yet, so you only need to re-clone energenie-ener314rt.

On the other point, It must using a different command for SET_TEMP or it may be a different data type (the eTRV had a REALLY weird 0x92 data type!) for this.

Achronite commented 4 years ago

I've fixed the node-red code as well now, but don't bother cloning it for now; it shouldn't be generating the error anymore anyways.

DrOwl commented 4 years ago

Hi Sorry i have been delayed in further testing, we are in the process of moving house. ill test again more as soon as i can.

Achronite commented 3 years ago

@DrOwl Any news on testing updates? I would like to get a release done soon, and it would be good to check all is well.

FYI: I've npm released v0.4.0 of dependency 'energenie-ener314rt' with some debug for now, so you shouldn't get any more dependency failures if you install the develop branch of the node-red-contrib-energenie-ener314rt module.

red-kooga commented 3 years ago

hi, i have installed the development branch but i don't have the thermostat icon is there something else i should be doing?

Achronite commented 3 years ago

Use the new purple 'Control&Monitor' node for now, this is the one that should support the thermostat. I have created an icon for it, you can select it using the node properties 'Appearance' tab.

I'm planning to create new specific nodes for the thermostat and motion sensor in the full v4 release; as there is no way of dynamic changing the icon automatically based on the device type selected, so it's going to be easier to create specific nodes for specific devices.

Please let me know how you get on with the C&M node, especially if you have success with setting values.

Achronite commented 3 years ago

@DrOwl , @red-kooga Any word from testing? I have some time now to release v0.4 to the wild.

red-kooga commented 3 years ago

Hi, I did try to use the dev branch but couldn't get it to work, I have been so busy that I haven't had as much time as i would've liked to test further, I am hoping to try again in a couple of weeks when I'm not so busy.

On Wed, 3 Feb 2021, 17:05 Achronite, notifications@github.com wrote:

@DrOwl https://github.com/DrOwl , @red-kooga https://github.com/red-kooga Any word from testing? I have some time now to release v0.4 to the wild.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Achronite/node-red-contrib-energenie-ener314rt/issues/36#issuecomment-772667452, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZG6SZ35DKL363GPE7YCK3S5F67JANCNFSM4SSGZISA .

imgrant commented 3 years ago

Hello, sorry to reopen, but wondering if anyone has any further experience with the MIHO069 thermostat and this software? I just got a thermostat and am using it without the gateway. I do not see any messages from the thermostat other than JOIN (when using discover/scan & pairing mode on the device), and periodic WAKEUP_MSG messages (0x59), I have never seen it report the temperature or anything like that.

I was able to detect it and send messages (0xf4 and 0x2a as above, to change the set temperature or operating mode), but they did not have any effect. Until, that is, I put the thermostat in pairing mode (hold down M button); for the short period it is in pairing mode (the display stays on and wireless icon blinks slowly), commands to set the target temperature or change the mode do work. When pairing mode finishes, the commands return to having no effect, whether the wireless LED is completely absent, or blinking rapidly (which I think indicates paired & comms activity).

I am wondering if:

  1. The thermostat operates like the eTRVs and does not listen all the time, and therefore does need cached commands (note, the thermostat is not mains-powered, but uses 2 AA batteries);
  2. It needs the gateway or there are some other undocumented commands;
  3. My thermostat is defective in some way...
Achronite commented 3 years ago

Hmmm. it sounds like it may operate the same as an eTRV then(?) Can you try adding the thermostat using the TRV node, and let me know how you get on?

I'm also wondering if the WAKE_UP messages are when it starts listening instead of the TEMPERATURE messages? I could try a patch to listen for WAKE_UP as well as TEMPERATURE if this is the case

imgrant commented 3 years ago

The WAKEUP_MSG seems to come about every 60 seconds. I don't know if it's possible to change this, like the eTRVs, or if temperature & humidity reporting happens on a different schedule (I have yet to see those messages ever).

Unfortunately, the cached command segfaults for me. E.g. using Node-RED:

[Logs]    [9/21/2021, 21:13:47] [node-red] *21 Sep 20:13:47 - [info] Started flows
[Logs]    [9/21/2021, 21:14:36] [node-red] ******************@*******************@**************************************************************@rlen=0
[Logs]    [9/21/2021, 21:14:36] [node-red] openThings_receive(): rec:0 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000}
[Logs]    [9/21/2021, 21:14:36] [node-red] openThings_devicePut() device added: 0:10502528
[Logs]    [9/21/2021, 21:14:36] [node-red] openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632255695 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000}
[Logs]    [9/21/2021, 21:14:36] [node-red] }
[Logs]    [9/21/2021, 21:14:36] [node-red] node-red: ../C/achronite/napi_energenie.c:745: tr_openThings_receive_thread: Assertion `napi_call_function(env, undefined, js_cb, 1, &js_buf, NULL) == napi_ok' failed.
[Logs]    [9/21/2021, 21:14:37] [node-red] /usr/src/app/start.sh: line 8:    18 Aborted                 (core dumped) DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket node-red -v --settings /usr/src/app/settings.js

Or, using the Node module directly (I rebuilt the module with tracing enabled) via the command line:

Welcome to Node.js v16.6.2.
Type ".help" for more information.
> var ener314rt = require('/usr/local/lib/node_modules/node-red-contrib-energenie-ener314rt/node_modules/energenie-ener314rt');
undefined
> ener314rt.initEner314rt(false);
init_ener314(): initialising
init_ener314(): mutex created & locked
radio_init()
radio_ver=36
radio_standby
writereg 1 4
_wait_ready
*writereg 2 8
writereg 5 0
writereg 6 0
writereg 7 108
writereg 8 122
writereg 9 225
writereg 25 65
writereg 3 26
writereg 4 11
writereg 45 0
writereg 46 0
writereg 55 128
writereg 56 0
radio_standby
writereg 1 4
_wait_ready
0
> ener314rt.openThingsDeviceList(true);
openthings_deviceList(): called
openThings_scan(): called
@rlen=0
openThings_devicePut() device added: 0:10502528
openthings_deviceList(): Returning: {"numDevices":1, "devices":[
{"mfrId":4,"productId":18,"deviceId":10502528,"control":1,"product":"Thermostat","joined":1}]}
'{"numDevices":1, "devices":[\n' +
  '{"mfrId":4,"productId":18,"deviceId":10502528,"control":1,"product":"Thermostat","joined":1}]}'
> ener314rt.openThingsCmd(18, 10502528, 244, 28, 20);
calling openThings_cmd(18,10502528,244,28,20)
openThings_cmd(): deviceId=10502528, cmd=244, data=28
openThings_build_msg: productId=18, deviceId=10502528, cmd=244, data=28 cmd=OTCP_TEMP_SET msglen=15
Built payload (unencrypted): 14,4,18,103,198,160,65,128,244,146,28,0,0,156,225,
Built payload (encrypted): 14,4,18,103,198,31,127,203,186,7,93,8,108,33,70,
openThings_cmd(): sending...
radio_mod_transmit()
writereg 1 12
_wait_ready
_wait_txready
radio_send_payload(): writereg 60 14
20 tx payloads
*|**|***|***|**|***|**|***|***|**|***|**|***|***|**|***|**|***|**|***|**irqflags1,2=176,8
writereg 1 16
_wait_ready
*openThings_cmd(): sent
openThings_cmd() returned 0
0
> ener314rt.openThingsCacheCmd(10502528, 244, 28);
openThings_cache_cmd(): deviceId=10502528, cmd=244, data=28
openThings_build_msg: productId=18, deviceId=10502528, cmd=244, data=28 cmd=OTCP_TEMP_SET msglen=15
Built payload (unencrypted): 14,4,18,105,115,160,65,128,244,146,28,0,0,156,225,
Built payload (encrypted): 14,4,18,105,115,132,33,136,88,25,4,1,50,10,128,
Segmentation fault (core dumped)
Achronite commented 3 years ago

I'm not sure what you are doing in the native node.js code example above, but SEGV is BAD, it means there is something wrong with the data types and allocation in the C / NAPI code that needs fixing.

Can you compile the underlying node module that is used by node-red in FULLTRACE mode and try again, so that I can see the node debug in the node-red log file? You can do this by un-commenting the 2 lines in trace.h

// uncomment next line to enable trace debug
#define TRACE_POSIX
#define FULLTRACE

Assuming you are using a standard install on pi, the trace.h should be in ~/.node-red/node_modules/node-red-contrib-energenie-ener314rt/node_modules/energenie-ener314rt/C/energenie, and then you can recompile using node-gyp, something like this:

$ cd ~/.node-red/node_modules/node-red-contrib-energenie-ener314rt/node_modules/energenie-ener314rt
$ node-gyp rebuild

Restart node-red and try again to see what debug is thrown up.

Achronite commented 3 years ago

Sorry for double post, but I've been thinking about the underlying issue more. @DrOwl and @red-kooga have received other types of messages from the MIHO069 thermostat (see earlier in thread). There may be a handshake that has not been received yet by the thermostat, so it is could still be in setup mode. I'm guessing, but this could be because they have previously set the thermostat up with a MiHome Gateway, or a JOIN worked correctly for them (but not for @imgrant), or WAKEUP_MSG somehow needs to be acknowledged; It would be good if @DrOwl or @red-kooga could confirm?

Also, regarding the cached commands causing a crash, the device type will need switching to type 2 for the MIHO069 to using caching in the C code for this to work properly (line 86 openThings.c). I believe it is crashing with the memory error because the extra caching structures are only added for type 2 devices, it crashes when it tries to use these unallocated structures. There may be some other code changes required too.

DrOwl commented 3 years ago

My Device was indeed set up using the MiHome Gateway first. I have not set up my Node Red Pi-mote server since moving home so have not done any further testing.

imgrant commented 3 years ago

@Achronite The above output was with node.js library already rebuilt with TRACE_POSIX and FULLTRACE enabled. In the node command line transcript above, I was doing:

// Load the library
> var ener314rt = require('/usr/local/lib/node_modules/node-red-contrib-energenie-ener314rt/node_modules/energenie-ener314rt');

// Initialise the radio
> ener314rt.initEner314rt(false);

// Scan for devices (whilst simultaneously putting the thermostat in pairing mode)
> ener314rt.openThingsDeviceList(true);

// Send a command to set the target temperature to 28°C, using the device ID reported by the scan & join
> ener314rt.openThingsCmd(18, 10502528, 244, 28, 20);
// (the radio transmits the command, but the thermostat does nothing)

// Send a _cached_ command to set the target temperature to 28°C
> ener314rt.openThingsCacheCmd(10502528, 244, 28);
// (it segfaults due to the thermostat device not being type 2 as you later described)

It would be good if @DrOwl or anyone can confirm the LED state(s) for the wireless link on their thermostats—holding down the 'M' button to initiate pairing mode makes the wireless link LED blink slowly; when the JOIN is ACKed, it goes solid on. For me, this solid on state lasted only briefly, before it begins to blink more rapidly (and I see the periodic WAKEUP_MSG messages if I start an openThingsReceiveThread listener).

Following on from the above, I have now had some success with cached commands. I changed the device type for the thermostat to 2 (line 86 in openThings.c as you pointed to), and repeated the above steps in node (also starting a receive thread to print messages to the console). After queuing the cached command, the next time I saw the WAKEUP_MSG, it transmitted the cached command, and the thermostat responded with a bunch of messages including the temperature, humidity, etc. 🥳 The transcript for this session is here (fold-out):

node transcript with successful cached command

```node root@mihome:/usr/local/lib/node_modules/node-red-contrib-energenie-ener314rt/node_modules/energenie-ener314rt# node Welcome to Node.js v16.6.2. Type ".help" for more information. > var ener314rt = require('/usr/local/lib/node_modules/node-red-contrib-energenie-ener314rt/node_modules/energenie-ener314rt'); napi_energenie.Init() called undefined > ener314rt.initEner314rt(false) init_ener314(): initialising init_ener314(): mutex created & locked radio_init() radio_ver=36 radio_standby writereg 1 4 _wait_ready *writereg 2 8 writereg 5 0 writereg 6 0 writereg 7 108 writereg 8 122 writereg 9 225 writereg 25 65 writereg 3 26 writereg 4 11 writereg 45 0 writereg 46 0 writereg 55 128 writereg 56 0 radio_standby writereg 1 4 _wait_ready 0 > ener314rt.openThingsDeviceList(true) openthings_deviceList(): called openThings_scan(): called writereg 2 0 writereg 5 1 writereg 6 236 writereg 7 108 writereg 8 147 writereg 9 51 writereg 11 0 writereg 24 8 writereg 25 67 writereg 3 26 writereg 4 11 writereg 46 136 writereg 47 45 writereg 48 212 writereg 55 160 writereg 56 66 writereg 57 6 writereg 1 16 _wait_ready *@@@@@rlen=0 openThings_scan(): New device found, sending ACK: deviceId:10502528 ACK tx payload (unencrypted): 12,4,18,1,0,160,65,128,106,0,0,219,131, radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 12 20 tx payloads *|**|**|***|**|**|**|***|**|**|**|***|**|**|***|**|**|**|***|**|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_devicePut() adding cache cmd struct. openThings_devicePut() device added: 0:10502528 rlen=0 openThings_scan(): New device found, sending ACK: deviceId:10502528 ACK tx payload (unencrypted): 12,4,18,1,0,160,65,128,106,0,0,219,131, radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 12 20 tx payloads *|**|**|***|**|**|**|***|**|**|**|***|**|**|***|**|**|**|***|**|**irqflags1,2=176,8 writereg 1 16 _wait_ready *rlen=0 openThings_scan(): New device found, sending ACK: deviceId:10502528 ACK tx payload (unencrypted): 12,4,18,1,0,160,65,128,106,0,0,219,131, radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 12 20 tx payloads *|**|**|***|**|**|**|***|**|**|**|***|**|**|***|**|**|**|***|**|**irqflags1,2=176,8 writereg 1 16 _wait_ready *rlen=0 openThings_scan(): New device found, sending ACK: deviceId:10502528 ACK tx payload (unencrypted): 12,4,18,1,0,160,65,128,106,0,0,219,131, radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 12 20 tx payloads *|**|**|***|**|**|**|***|**|**|**|***|**|**|***|**|**|**|***|**|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openthings_deviceList(): Returning: {"numDevices":1, "devices":[ {"mfrId":4,"productId":18,"deviceId":10502528,"control":2,"product":"Thermostat","joined":0}]} '{"numDevices":1, "devices":[\n' + '{"mfrId":4,"productId":18,"deviceId":10502528,"control":2,"product":"Thermostat","joined":0}]}' > ener314rt.openThingsReceiveThread(10000, (msg) => { console.log(`Msg received: ${msg}`); }); tf_ napi_create_threadsafe_function done tf_ monitor thread started, timeout=10000 tx_openThings_receive_thread starting undefined > openThings_receive(): rec:0 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399337 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} } Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399337 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} } > ener314rt.openThingsCacheCmd(10502528, 244, 28); openThings_cache_cmd(): deviceId=10502528, cmd=244, data=28 openThings_build_msg: productId=18, deviceId=10502528, cmd=244, data=28 cmd=OTCP_TEMP_SET msglen=15 Built payload (unencrypted): 14,4,18,103,198,160,65,128,244,146,28,0,0,156,225, Built payload (encrypted): 14,4,18,103,198,31,127,203,186,7,93,8,108,33,70, 1 payload(s) cached 0 > openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=9 rlen=0 openThings_receive(): rec:0 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399404 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} } Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399404 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} } openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=8 openThings_receive(): rec:0 {"name":"TEMPERATURE","id":116,"type":2,"str":"","int":369,"float":23.062500} openThings_receive(): rec:1 {"name":"REL_HUMIDITY","id":104,"type":1,"str":"","int":72,"float":72.000000} openThings_receive(): rec:2 {"name":"BATTERY_LEVEL","id":98,"type":2,"str":"","int":12648,"float":3.087891} openThings_receive(): rec:3 {"name":"MOTION_DETECTOR","id":109,"type":1,"str":"","int":168,"float":168.000000} openThings_receive(): rec:4 {"name":"THERMOSTAT_MODE","id":42,"type":1,"str":"","int":1,"float":1.000000} openThings_receive(): rec:5 {"name":"TARGET_TEMP","id":75,"type":2,"str":"","int":448,"float":28.000000} openThings_receive(): rec:6 {"name":"SWITCH_STATE","id":115,"type":1,"str":"","int":1,"float":1.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399404,"TEMPERATURE":23.062500,"REL_HUMIDITY":72,"BATTERY_LEVEL":3.087891,"MOTION_DETECTOR":168,"THERMOSTAT_MODE":1,"TARGET_TEMP":28.000000,"SWITCH_STATE":1} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399404,"TEMPERATURE":23.062500,"REL_HUMIDITY":72,"BATTERY_LEVEL":3.087891,"MOTION_DETECTOR":168,"THERMOSTAT_MODE":1,"TARGET_TEMP":28.000000,"SWITCH_STATE":1} openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=7 openThings_receive(): rec:0 {"name":"TEMPERATURE","id":116,"type":2,"str":"","int":369,"float":23.062500} openThings_receive(): rec:1 {"name":"REL_HUMIDITY","id":104,"type":1,"str":"","int":72,"float":72.000000} openThings_receive(): rec:2 {"name":"BATTERY_LEVEL","id":98,"type":2,"str":"","int":12648,"float":3.087891} openThings_receive(): rec:3 {"name":"MOTION_DETECTOR","id":109,"type":1,"str":"","int":168,"float":168.000000} openThings_receive(): rec:4 {"name":"THERMOSTAT_MODE","id":42,"type":1,"str":"","int":1,"float":1.000000} openThings_receive(): rec:5 {"name":"TARGET_TEMP","id":75,"type":2,"str":"","int":448,"float":28.000000} openThings_receive(): rec:6 {"name":"SWITCH_STATE","id":115,"type":1,"str":"","int":1,"float":1.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399405,"TEMPERATURE":23.062500,"REL_HUMIDITY":72,"BATTERY_LEVEL":3.087891,"MOTION_DETECTOR":168,"THERMOSTAT_MODE":1,"TARGET_TEMP":28.000000,"SWITCH_STATE":1} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399405,"TEMPERATURE":23.062500,"REL_HUMIDITY":72,"BATTERY_LEVEL":3.087891,"MOTION_DETECTOR":168,"THERMOSTAT_MODE":1,"TARGET_TEMP":28.000000,"SWITCH_STATE":1} openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=6 openThings_receive(): rec:0 {"name":"TEMPERATURE","id":116,"type":2,"str":"","int":369,"float":23.062500} openThings_receive(): rec:1 {"name":"REL_HUMIDITY","id":104,"type":1,"str":"","int":72,"float":72.000000} openThings_receive(): rec:2 {"name":"BATTERY_LEVEL","id":98,"type":2,"str":"","int":12648,"float":3.087891} openThings_receive(): rec:3 {"name":"MOTION_DETECTOR","id":109,"type":1,"str":"","int":168,"float":168.000000} openThings_receive(): rec:4 {"name":"THERMOSTAT_MODE","id":42,"type":1,"str":"","int":1,"float":1.000000} openThings_receive(): rec:5 {"name":"TARGET_TEMP","id":75,"type":2,"str":"","int":448,"float":28.000000} openThings_receive(): rec:6 {"name":"SWITCH_STATE","id":115,"type":1,"str":"","int":1,"float":1.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399406,"TEMPERATURE":23.062500,"REL_HUMIDITY":72,"BATTERY_LEVEL":3.087891,"MOTION_DETECTOR":168,"THERMOSTAT_MODE":1,"TARGET_TEMP":28.000000,"SWITCH_STATE":1} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399406,"TEMPERATURE":23.062500,"REL_HUMIDITY":72,"BATTERY_LEVEL":3.087891,"MOTION_DETECTOR":168,"THERMOSTAT_MODE":1,"TARGET_TEMP":28.000000,"SWITCH_STATE":1} openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=5 openThings_receive(): rec:0 {"name":"TEMPERATURE","id":116,"type":2,"str":"","int":369,"float":23.062500} openThings_receive(): rec:1 {"name":"REL_HUMIDITY","id":104,"type":1,"str":"","int":72,"float":72.000000} openThings_receive(): rec:2 {"name":"BATTERY_LEVEL","id":98,"type":2,"str":"","int":12648,"float":3.087891} openThings_receive(): rec:3 {"name":"MOTION_DETECTOR","id":109,"type":1,"str":"","int":168,"float":168.000000} openThings_receive(): rec:4 {"name":"THERMOSTAT_MODE","id":42,"type":1,"str":"","int":1,"float":1.000000} openThings_receive(): rec:5 {"name":"TARGET_TEMP","id":75,"type":2,"str":"","int":448,"float":28.000000} openThings_receive(): rec:6 {"name":"SWITCH_STATE","id":115,"type":1,"str":"","int":1,"float":1.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399407,"TEMPERATURE":23.062500,"REL_HUMIDITY":72,"BATTERY_LEVEL":3.087891,"MOTION_DETECTOR":168,"THERMOSTAT_MODE":1,"TARGET_TEMP":28.000000,"SWITCH_STATE":1} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399407,"TEMPERATURE":23.062500,"REL_HUMIDITY":72,"BATTERY_LEVEL":3.087891,"MOTION_DETECTOR":168,"THERMOSTAT_MODE":1,"TARGET_TEMP":28.000000,"SWITCH_STATE":1} openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=4 rlen=0 openThings_receive(): rec:0 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399468 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} } Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399468 {"name":"WAKEUP_MSG","id":89,"type":0,"str":"","int":0,"float":0.000000} } openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=3 openThings_receive(): rec:0 {"name":"TEMPERATURE","id":116,"type":2,"str":"","int":366,"float":22.875000} openThings_receive(): rec:1 {"name":"REL_HUMIDITY","id":104,"type":1,"str":"","int":71,"float":71.000000} openThings_receive(): rec:2 {"name":"BATTERY_LEVEL","id":98,"type":2,"str":"","int":12623,"float":3.081787} openThings_receive(): rec:3 {"name":"MOTION_DETECTOR","id":109,"type":1,"str":"","int":1,"float":1.000000} openThings_receive(): rec:4 {"name":"THERMOSTAT_MODE","id":42,"type":1,"str":"","int":1,"float":1.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399468,"TEMPERATURE":22.875000,"REL_HUMIDITY":71,"BATTERY_LEVEL":3.081787,"MOTION_DETECTOR":1,"THERMOSTAT_MODE":1} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399468,"TEMPERATURE":22.875000,"REL_HUMIDITY":71,"BATTERY_LEVEL":3.081787,"MOTION_DETECTOR":1,"THERMOSTAT_MODE":1} openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=2 openThings_receive(): rec:0 {"name":"TEMPERATURE","id":116,"type":2,"str":"","int":366,"float":22.875000} openThings_receive(): rec:1 {"name":"REL_HUMIDITY","id":104,"type":1,"str":"","int":71,"float":71.000000} openThings_receive(): rec:2 {"name":"BATTERY_LEVEL","id":98,"type":2,"str":"","int":12623,"float":3.081787} openThings_receive(): rec:3 {"name":"MOTION_DETECTOR","id":109,"type":1,"str":"","int":1,"float":1.000000} openThings_receive(): rec:4 {"name":"THERMOSTAT_MODE","id":42,"type":1,"str":"","int":1,"float":1.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399469,"TEMPERATURE":22.875000,"REL_HUMIDITY":71,"BATTERY_LEVEL":3.081787,"MOTION_DETECTOR":1,"THERMOSTAT_MODE":1} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399469,"TEMPERATURE":22.875000,"REL_HUMIDITY":71,"BATTERY_LEVEL":3.081787,"MOTION_DETECTOR":1,"THERMOSTAT_MODE":1} openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=1 openThings_receive(): rec:0 {"name":"TEMPERATURE","id":116,"type":2,"str":"","int":366,"float":22.875000} openThings_receive(): rec:1 {"name":"REL_HUMIDITY","id":104,"type":1,"str":"","int":71,"float":71.000000} openThings_receive(): rec:2 {"name":"BATTERY_LEVEL","id":98,"type":2,"str":"","int":12623,"float":3.081787} openThings_receive(): rec:3 {"name":"MOTION_DETECTOR","id":109,"type":1,"str":"","int":1,"float":1.000000} openThings_receive(): rec:4 {"name":"THERMOSTAT_MODE","id":42,"type":1,"str":"","int":1,"float":1.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399470,"TEMPERATURE":22.875000,"REL_HUMIDITY":71,"BATTERY_LEVEL":3.081787,"MOTION_DETECTOR":1,"THERMOSTAT_MODE":1} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399470,"TEMPERATURE":22.875000,"REL_HUMIDITY":71,"BATTERY_LEVEL":3.081787,"MOTION_DETECTOR":1,"THERMOSTAT_MODE":1} openThings_cache_send(): sending cached msg radio_mod_transmit() writereg 1 12 _wait_ready _wait_txready radio_send_payload(): writereg 60 14 1 tx payloads *|**irqflags1,2=176,8 writereg 1 16 _wait_ready *openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=0 openThings_receive(): rec:0 {"name":"TEMPERATURE","id":116,"type":2,"str":"","int":366,"float":22.875000} openThings_receive(): rec:1 {"name":"REL_HUMIDITY","id":104,"type":1,"str":"","int":71,"float":71.000000} openThings_receive(): rec:2 {"name":"BATTERY_LEVEL","id":98,"type":2,"str":"","int":12623,"float":3.081787} openThings_receive(): rec:3 {"name":"MOTION_DETECTOR","id":109,"type":1,"str":"","int":1,"float":1.000000} openThings_receive(): rec:4 {"name":"THERMOSTAT_MODE","id":42,"type":1,"str":"","int":1,"float":1.000000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399471,"TEMPERATURE":22.875000,"REL_HUMIDITY":71,"BATTERY_LEVEL":3.081787,"MOTION_DETECTOR":1,"THERMOSTAT_MODE":1} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399471,"TEMPERATURE":22.875000,"REL_HUMIDITY":71,"BATTERY_LEVEL":3.081787,"MOTION_DETECTOR":1,"THERMOSTAT_MODE":1} openThings_receive(): rec:0 {"name":"WAKEUP_MSG","id":89,"type":2,"str":"","int":0,"float":22.875000} openThings_receive: Returning: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399483,"WAKEUP_MSG":22.875000} Msg received: {"deviceId":10502528,"mfrId":4,"productId":18,"timestamp":1632399483,"WAKEUP_MSG":22.875000} > ener314rt.stopMonitoring() nf_stop_openThings_receive_thread called undefined > *tx_ monitor thread completed tc_ monitor thread closing... tc_ done ```

What is notable is that it keeps retrying sending the cached command (you can see the repeated attempts with retries=_n_ decrementing as it goes), even though it is successful. I guess the code needs to note the incoming reply for that? There are a couple of other interesting things here:

  1. During this period where it was sending the cached command, the wireless link LED was solid on, and later switched back to blinking rapidly. Maybe the thermostat expects a reply to the WAKEUP_MSG messages in order for it to think its connected (ordinarily to the gateway) and show the LED solid on?
  2. The WAKEUP_MSG messages following the cached command now seem to show the current ambient temperature in the payload (before it was 0.000000)

I'm also wondering if there is a command that can be sent to the thermostat that will cause it to report the temperature, humidity, battery, etc (without having to change anything like set a target temperature), as I would like to track this metric.

Anyway, hope this info helps! I plan to take a closer look at your eTRV code, and see if the thermostat might need more of those routines.

DrOwl commented 3 years ago

The radio Icon tends to stay on (Mine is paired to the MiHome gateway) and flashes when pressing a button. Changing the temp on the MIHO069, updates the value in the Mi|Home app quite quickly. But changing the on/off state or Temperature in the app is quite slow to update the MIHO069 (if it does at all).

Achronite commented 3 years ago

@imgrant seems like we are making progress. :-) Good to see that you have confirmed it is indeed a cached device. I do have a mechanism to stop the retrying on successful Rx, I'll take a look at it; it maybe needs tweaking for the thermostat response messages.

Transient Parameters For the eTRV I have an extra structure to store the transient / infrequent parameters; these are then be returned when a report is sent back to node-red:

struct TRV_DEVICE {
    float         targetC;
    float         currentC;
    float         voltage;
    unsigned int  diagnostics;
    bool          errors;
    bool          lowPowerMode;
    bool          exerciseValve;
    enum valveState valve;
    time_t        diagnosticDate;
    time_t        voltageDate;
    time_t        valveDate;
    char errString[MAX_ERRSTR];
};

Can you have a think to see if this type of functionality is needed for the thermostat? I could reuse 'as-is' for the thermostat, or it may need tweaking. What parameters need to be stored for the thermostat?

@DrOwl definitely sounds like a 'not listening'/timing issue to me. That's why i built the retry mechanism for the eTRV to increase the hit rate on commands..

Achronite commented 3 years ago

@imgrant I have made changes to the development branch of dependent node 'energenie-ener314rt'. I have made the assumption that a WAKEUP (note I dropped _MSG for consistency) is the trigger for when a cached command to be sent to the thermostat. I have also tried to match the requested values against what is returned from the thermostat before stopping the retries.

Can you please check that these changes work for you with your manual commands? I will then work on the node-red code to match.

I may also need some help obtaining the response messages to some of the other request commands; I have no idea if OTCP_REQUEST_DIAGNOSTICS (0xA6) works, but it could help to regularly get the extra data you are looking for.

imgrant commented 3 years ago

@Achronite Had a chance to test out the develop branch, but unfortunately I am getting segfaults when using the cached command. See transcript below, it sends the command when it receives the WAKEUP message successfully (and I could verify that the thermostat received it, because it changed the temperature), but then crashes immediately, so I never see the data returned from the thermostat any more. Maybe this is to do with the data struct on receive? Haven't had a chance to investigate further. My goal is to run this without having to resort to a gateway, but wondering if it might be worth picking up a gateway if I can find one cheap on eBay in order to sniff the messages between the thermostat and gateway.

> e.openThingsCacheCmd(10502528, 244, 16);***********************************
*openThings_cache_cmd(): deviceId=10502528, cmd=244, data=16
openThings_build_msg: productId=18, deviceId=10502528, cmd=244, data=16 cmd=OTCP_TEMP_SET msglen=15
Built payload (unencrypted): 14,4,18,105,115,160,65,128,244,146,16,0,0,233,128,
Built payload (encrypted): 14,4,18,105,115,132,33,136,88,25,8,1,50,127,225,
1 payload(s) cached
0
> *******************@openThings_cache_send(): sending cached msg
radio_mod_transmit()
writereg 1 12
_wait_ready
_wait_txready
radio_send_payload(): writereg 60 14
1 tx payloads
*|**irqflags1,2=176,8
writereg 1 16
_wait_ready
*openThings_cache_send(): g_CachedCmds=1, g_PreCachedCmds=0, deviceId=10502528, retries=9
rlen=0
openThings_receive(): rec:0 {"name":"WAKEUP","id":89,"type":0,"str":"","int":0,"float":0.000000}
Segmentation fault (core dumped)
Achronite commented 3 years ago

@imgrant I think I've fixed the segfault, i was using the deviceId rather than device index (I really should read my own code comments!).

Please try again with the develop branch.

Achronite commented 3 years ago

@imgrant Have you had time to test this yet?

FYI - I also have a node-red update that introduces a new Thermostat node that uses this code (see develop branch of this repo).

Achronite commented 2 years ago

Releasing updated code, as others may benefit.

sgulati-hub commented 1 year ago

I could not manage to send any commands to Thermostat however I have successfully received some messages from the Thermostat. I have tried commands like the following: Setting temperature : { "command": 244, "data": 17 } Identify : { "command": 191 }

Also, noticed that Thermostat sends the TARGET_TEMP only when target temperature changes (either due to schedule on the MiHome Web/App or Manual change via Web/App). It seems MiHome hub might have some command with the ability to wake up the Thermostat as changing the target temperature on the web app immediately updates it on the thermostat (and I receive a message with TARGET_TEMP), even though I am only getting WAKEUP messages every 3-5 minutes.

I have tried sending the command with and without caching by using line 151 instead of line 150 in openThings-thermostat.js, however I have had no successful commands with either:

var res = ener314rt.openThingsCacheCmd(deviceId, cmd, data);
// ener314rt.openThingsCmd(productId, deviceId, cmd, data, xmits);
// Also added var res = 0; so that the rest of the code works

I have raised the question with Energenie in the hope to get some information/contact from them.

Achronite commented 1 year ago

The caching behaviour is controlled by the device type, so you cannot override it directly in node-red. The Thermostat (0x12) is currently set-up as a cached device (2) in the code (openThings.c line 86).

The key thing is, it does not seem to be responding to any of the commands that the eTRVs use. Caching just delays the command being sent until a WAKEUP message is received.

To progress this any further we need a list of the commands (with data as applicable) that the Thermostat responds to, ideally from energenie. Let's hope that they can provide this - they didn't when I asked back in Feb 21.

DrOwl commented 1 year ago

To progress this any further we need a list of the commands (with data as applicable) that the Thermostat responds to, ideally from energenie. Let's hope that they can provide this - they didn't when I asked back in Feb 21.

Did you raise a ticket with them? https://sandal.zendesk.com/

Funny company I like their products and someone there (at least at one point) seemed like they wanted to offer them to the maker community but then gave up, Shame as having Node Red / Home Assistant community on your side could be quite useful.

nathanael-pearson commented 1 year ago

Hi There is an api that you can use to control the energenie devices. I use this for automating sockets in HA but the command structure is the same... https://mihome4u.co.uk/docs/api-documentation/thermostats-api

Kind regards

Achronite commented 1 year ago

Did you raise a ticket with them? https://sandal.zendesk.com/

Yes I did raise it via the ticket system, but it went cold. I have just sent a follow-up.

There is an api that you can use to control the energenie devices. I use this for automating sockets in HA but the command structure is the same... https://mihome4u.co.uk/docs/api-documentation/thermostats-api

Yeah... but that only works if you have a MiHome Hub as well. I don't have one, but maybe @sgulati-hub does?

sgulati-hub commented 1 year ago

I have a MiHome hub and have used their APIs as well to control the light switches and Thermostat but wanted to control MiHome devices using a Two-way Pi-mote - ENER314-RT i.e. independent of Mihome Hub and their server.
I have also raised the ticket with Energenie asking for help regarding the commands for Thermostat but have not got any relevant help till now.

Achronite commented 1 year ago

I've been thinking... in order to test that the thermostat is responding to ANY commands, can you please test the commands that I've listed in the README and let me know the results?

Achronite commented 11 months ago

Work is progressing through https://github.com/Achronite/mqtt-energenie-ener314rt/issues/56 and will be retrofitted here.