Page 1 of 1

Reading JSON from ESPeasy

Posted: Friday 03 January 2020 21:33
by PieterS
Running Domoticz V4.10717 on a Synology:

Try to create a script for reading the state of a relay contected to an ESP8266 in ESPeasy.

I can read its state by a request in my browser: http://192.168.X.XX/json.
The result is:

Code: Select all

{"System":{
"Build":20104,
"Git Build":"mega-20191119",
"System Libraries":"ESP82xx Core 2_5_2, NONOS SDK 2.2.1(cfd48f3), LWIP: 2.1.2 PUYA support",
"Plugins":46,
"Plugin description":" [Normal]",
"Local Time":"2020-01-03 20:33:17",
"Unit Number":11,
"Unit Name":"ESP_Alarm",
"Uptime":2119,
"Last Boot Cause":"Manual reboot",
"Reset Reason":"Hardware Watchdog",
"Load":15.40,
"Load LC":3346,
"CPU Eco Mode":"false",
"Heap Max Free Block":16720,
"Heap Fragmentation":15,
"Free RAM":19736
},
"WiFi":{
"Hostname":"ESP-Alarm-11",
"IP Config":"Static",
"IP Address":"192.168.X.X",
"IP Subnet":"255.255.255.0",
"Gateway":"192.168.X.X",
"STA MAC":"68:C6:3A:EA:24:73",
"DNS 1":"192.168.1.1",
"DNS 2":"(IP unset)",
"SSID":"XXXXXXX",
"BSSID":"C0:FF:D4:8D:30:E0",
"Channel":13,
"Connected msec":127151594,
"Last Disconnect Reason":1,
"Last Disconnect Reason str":"(1) Unspecified",
"Number Reconnects":0,
"Force WiFi B/G":"false",
"Restart WiFi Lost Conn":"false",
"Force WiFi No Sleep":"false",
"Periodical send Gratuitous ARP":"false",
"Connection Failure Threshold":0,
"RSSI":-43
},
"Sensors":[
{
"TaskValues": [
{"ValueNumber":1,
"Name":"State",
"NrDecimals":0,
"Value":0
}],
"DataAcquisition": [
{"Controller":1,
"IDX":831,
"Enabled":"true"
},
{"Controller":2,
"IDX":0,
"Enabled":"false"
},
{"Controller":3,
"IDX":0,
"Enabled":"false"
}],
"TaskInterval":0,
"Type":"Switch input - Switch",
"TaskName":"Alarmcontact",
"TaskDeviceNumber":1,
"TaskEnabled":"true",
"TaskNumber":1
}
],
"TTL":60000
}
I am not very familiar with dzvents so I tried to modify earlier script what is doing a similar, good job: This is my rebuild:

Code: Select all

local Enabled = 'true'

return {
        active = true,
    	logging = 
	    {
            level = domoticz.LOG_DEBUG,
            marker = "Alarmscript"
        },
        
        on = {
                timer = { 'every minute' },
                httpResponses = { 'Alarmstatus' } -- matches callback string below
        },
    
        execute = function(domoticz, item)

                if (item.isTimer) then
                        domoticz.openURL({
                                url = 'http://192.168.X.XX/json',
                                method = 'GET',
                                callback = 'Alarmstatus'
                        })

                elseif (item.isHTTPResponse) then
                        if (item.ok and item.isJSON) then 
                                if tonumber(item.json.age) < 60 then

                                        domoticz.devices('Alarmcontact').updateCustomSensor(item.json.Controller[1].Enabled)
                                end
                        else
                                domoticz.log('Error fetching Alarmstatus onduidelijk', domoticz.LOG_ERROR)
                                domoticz.log(item.data, domoticz.LOG_ERROR)
                        end
                end
        end
}
And this is what I see in the log of Domoticz:

Code: Select all

2020-01-03 20:43:00.356 Status: dzVents: Info: Alarmscript: ------ Start internal script: Alarm2:, trigger: every minute
2020-01-03 20:43:00.356 Status: dzVents: Debug: Alarmscript: OpenURL: url = http://192.168.X.XX/json
2020-01-03 20:43:00.356 Status: dzVents: Debug: Alarmscript: OpenURL: method = GET
2020-01-03 20:43:00.356 Status: dzVents: Debug: Alarmscript: OpenURL: post data = nil
2020-01-03 20:43:00.356 Status: dzVents: Debug: Alarmscript: OpenURL: headers = nil
2020-01-03 20:43:00.356 Status: dzVents: Debug: Alarmscript: OpenURL: callback = Alarmstatus
2020-01-03 20:43:00.356 Status: dzVents: Info: Alarmscript: ------ Finished Alarm2

2020-01-03 20:43:02.415 Status: dzVents: Info: Handling httpResponse-events for: "Alarmstatus
2020-01-03 20:43:02.416 Status: dzVents: Info: Alarmscript: ------ Start internal script: Alarm2: HTTPResponse: "Alarmstatus"
2020-01-03 20:43:02.418 Status: dzVents: Error (2.4.19): Alarmscript: An error occured when calling event handler Alarm2
2020-01-03 20:43:02.419 Status: dzVents: Error (2.4.19): Alarmscript: ...omoticz/var/scripts/dzVents/generated_scripts/Alarm2.lua:27: attempt to compare nil with number
2020-01-03 20:43:02.419 Status: dzVents: Info: Alarmscript: ------ Finished Alarm2 
Why is the result not as expected?
How can I read the value of Controller 1
And why is the log in ESP different from JSON?

This is the logfile in ESP, made by a simple rule:

Code: Select all

129812201: WD   : Uptime 2164 ConnectFailures 0 FreeMem 20888 WiFiStatus 3
129834079: EVENT: Rules#Timer=1
129834098: ACT  : SendToHTTP 192.168.x.x,XXXX,/json.htm?type=command¶m=udevice&idx=831&nvalue=0                   
129834111: Command: sendtohttp
129834143: ACT  : SendToHTTP 192.168.x.x,XXXX,/json.htm?type=command¶m=udevice&idx=831&svalue=Off
129834155: Command: sendtohttp
129834183: ACT  : timerSet,1,120
129834195: Command: timerset
129839080: EVENT: Clock#Time=Fri,21:18
129842201: WD   : Uptime 2164 ConnectFailures 0 FreeMem 21176 WiFiStatus 3
Lots of questions for a beginner.. :oops:
After that this scripts runs oke, Domoticz has to change some switches and the ActiveTimerPlan... :roll:
Any help is welcome.. Thanks in advance!

Re: Reading JSON from ESPeasy

Posted: Saturday 04 January 2020 1:27
by waaren
PieterS wrote: Friday 03 January 2020 21:33 Try to create a script for reading the state of a relay contected to an ESP8266 in ESPeasy.
Why is the result not as expected?
How can I read the value of Controller 1
The JSON you get back from the ESP is translated into a multilevel table by Lua / dzVents.
When dumped this table looks like below

Code: Select all

WiFi:
    STA MAC: 68:C6:3A:EA:24:73
    Hostname: ESP-Alarm-11
    Last Disconnect Reason: 1
    Force WiFi B/G: false
    Connection Failure Threshold: 0
    DNS 2: (IP unset)
    Gateway: 192.168.X.X
    Last Disconnect Reason str: (1) Unspecified
    IP Config: Static
    BSSID: C0:FF:D4:8D:30:E0
    Connected msec: 127151594
    Force WiFi No Sleep: false
    RSSI: -43
    Periodical send Gratuitous ARP: false
    DNS 1: 192.168.1.1
    Restart WiFi Lost Conn: false
    SSID: XXXXXXX
    Number Reconnects: 0
    IP Subnet: 255.255.255.0
    IP Address: 192.168.X.X
    Channel: 13
TTL: 60000
System:
    Heap Fragmentation: 15
    Reset Reason: Hardware Watchdog
    Unit Name: ESP_Alarm
    Build: 20104
    Plugins: 46
    Heap Max Free Block: 16720
    Uptime: 2119
    System Libraries: ESP82xx Core 2_5_2, NONOS SDK 2.2.1(cfd48f3), LWIP: 2.1.2 PUYA support
    CPU Eco Mode: false
    Unit Number: 11
    Free RAM: 19736
    Load LC: 3346
    Local Time: 2020-01-03 20:33:17
    Plugin description:  [Normal]
    Last Boot Cause: Manual reboot
    Git Build: mega-20191119
    Load: 15.4
Sensors:
    1:
            TaskDeviceNumber: 1
            TaskInterval: 0
            TaskValues:
                    1:
                            NrDecimals: 0
                            Value: 0
                            Name: State
                            ValueNumber: 1
            TaskNumber: 1
            TaskName: Alarmcontact
            DataAcquisition:
                    1:
                            IDX: 831
                            Enabled: true
                            Controller: 1
                    2:
                            IDX: 0
                            Enabled: false
                            Controller: 2
                    3:
                            IDX: 0
                            Enabled: false
                            Controller: 3
            TaskEnabled: true
            Type: Switch input - Switch
So no age field to check for and if you want to read the status of Controller with IDX 831 you need something like

Code: Select all

domoticz.devices('Alarmcontact').updateCustomSensor(item.json.Sensors[1].DataAcquisition[1].Enabled)
This means your script should look like.

Code: Select all

local Enabled = 'true'

return {
        active = true,
        logging = 
        {
            level = domoticz.LOG_DEBUG,
            marker = "Alarmscript"
        },
        
        on = {
                timer = { 'every minute' },
                httpResponses = { 'Alarmstatus' } -- matches callback string below
        },
    
        execute = function(domoticz, item)

                if (item.isTimer) then
                        domoticz.openURL({
                                url = 'http://192.168.X.XX/json',
                                method = 'GET',
                                callback = 'Alarmstatus'
                        })

                elseif (item.isHTTPResponse) then
                        if (item.ok and item.isJSON) then 
                           --     if tonumber(item.json.age) < 60 then     --- age is not one of the elements in the JSON
                                        
                                        -- domoticz.devices('Alarmcontact').updateCustomSensor(item.json.Controller[1].Enabled)
                                        domoticz.devices('Alarmcontact').updateCustomSensor(item.json.Sensors[1].DataAcquisition[1].Enabled)
                                        
                           --     end
                        else
                                domoticz.log('Error fetching Alarmstatus onduidelijk', domoticz.LOG_ERROR)
                                domoticz.log(item.data, domoticz.LOG_ERROR)
                        end
                end
        end
}

Re: Reading JSON from ESPeasy

Posted: Saturday 04 January 2020 16:45
by PieterS
Thanks waaren for quick reply and hints!
I changed my script in Domoticz and some settings in ESPeasy. Disabled the rule and remembered that when I send the state of a switch in ESPeasy to a switch in Domoticz it became a lot easier.. :oops: Advantage is that I can set an On action like: http://192.168.x.xx:portnr/json.htm?type=command&param=setactivetimerplan&ActiveTimerPlan=3

On the other hand: I prefer to start a script which sends four commands when alarm is on:
Change the ActiveTimerPlan=3
Set "Keukenboiler" = Off
Set SetPoint Huiskamer setpoint To 14 Degrees
Send email with subject Alarm ingeschakeld to [email protected]

And of course the opposite when alarm is off

It seems not possible to handle that in the properties of a switch; I need a script. I will figure that out.
Another thing: A switch has lots of properties, but had a on/off-function in the mobile version. A dummy sensor does not have that disadvantage... I just need to be informed. How to arrange that?

Game over for today on my MEGA and Espeasy: Error: Daily flash write rate exceeded! (powercycle to reset this)
Time to write a script that changes the above settings.

Re: Reading JSON from ESPeasy

Posted: Saturday 04 January 2020 19:42
by waaren
PieterS wrote: Saturday 04 January 2020 16:45 Another thing: A switch has lots of properties, but had a on/off-function in the mobile version. A dummy sensor does not have that disadvantage... I just need to be informed. How to arrange that?
I do not understand what you mean with this. Can you please explain ?

Re: Reading JSON from ESPeasy

Posted: Saturday 04 January 2020 21:07
by PieterS
waaren wrote: Saturday 04 January 2020 19:42
PieterS wrote: Saturday 04 January 2020 16:45 Another thing: A switch has lots of properties, but had a on/off-function in the mobile version. A dummy sensor does not have that disadvantage... I just need to be informed. How to arrange that?
I do not understand what you mean with this. Can you please explain ?
Sorry for my English: I mean the device parameters which are related to a switch. Show up when the edit-button is pressed..