kevinkk525 / pysmartnode

Micropython Smarthome framework
MIT License
116 stars 22 forks source link

It seems that interval_publish / interval_reading in components.py has no effect #25

Closed Nabla128k closed 4 years ago

Nabla128k commented 4 years ago

Hi, I don't know what I am doing wrong, but it seems for me, that interval_publish / interval_reading has no efect in component configuration. I have DS18B20 sensor and ESP8622, pysmartnode downloaded from Github (latest build). In components.py there's just COMPONENTS = { "_order": ["ds18"], "ds18": { "package": ".sensors.ds18", "component": "DS18", "constructor_args": { "rom":"102624ED020800F5", "interval_publish": 30, "interval_reading": 30, "auto_detect": False, "precision_temp": 2, "discover": True, "friendly_name": "Krnsko vodomerna sachta", "expose_intervals": True, }, }, }

I tried also without rom: .... and with auto_detect: True.... and cannot make it to accept my interval of read and publish... it also uses values from config.py:

INTERVAL_SEND_SENSOR = const(300) # I don't know if this is from older verison? INTERVAL_SENSOR_PUBLISH = const(300) INTERVAL_SENSOR_READ = const(300)

If I comment out these settings it I think using 10 minutes interval....

What I am doing wrong?

kevinkk525 commented 4 years ago

Hi, thanks for using pysmartnode! How do you verify that interval_publish/interval_reading doesn't have any effect?

I just tried it and pysmartnode.config.COMPONENTS["ds18"]._intpb shows 30, as well as _intrd so it should honor your config. I verified it by the mqtt publications and I got a new publication every 30 seconds. The values INTERVAL_SEND_SENSOR in config.py are default values that are being used if you don't specify an interval for the sensor.

I did however discover a bug when using "expose_intervals=True" with the ds18 module so I'm surprised that your config actually works? I pushed a fix for that error on the dev branch (https://github.com/kevinkk525/pysmartnode/commit/cebad06020d3c9148ac8a4b674722008647a3674) but it might take a while until I upload a new release with a new build for the esp8266. Until then using expose_intervals=False will work, at least if you don't plan on changing the intervals through mqtt publications.

Besides, your config is missing the "pin" argument and doesn't work the way you posted it.

Nabla128k commented 4 years ago

Currently my (working) config seems like this: `COMPONENTS = { "_order": ["ds18"], "ds18": { "package": ".sensors.ds18", "component": "DS18", "interval_publish": 10, "interval_reading": 5, "constructor_args": {

"rom":"102624ED020800F5",

        "auto_detect": True,
        "precision_temp": 2,
        "discover": True,
        "friendly_name": "Krnsko vodomerna sachta",
         "expose_intervals": True,
    },
},

}

from pysmartnode import config import gc

gc.collect() from pysmartnode.components.sensors.ds18 import DS18

gc.collect()

ds18 = DS18(pin=10) config.addComponent("ds18", ds18) gc.collect()`

So I have pin=10 on DS18 instance creating (is is ok?)

I'm checking interval by mosquitto_sub listening at broker side and can't get it to publish in such short intervals that I have in components.py.

And yes, it works with expose_intervals=True, but - I haven't tried to change intervals at runtime, because I don't know how yet :-) (currently struggling with if there's a possibility to expose some part or whole Home Assistant dashboard to public access without login and is seems it's not possible... but it's offtopic here)

kevinkk525 commented 4 years ago

If all that is in your "components.py" then I'm not surprised anymore. Components.py gets imported and therefore the line "ds18 = DS18(pin=10)" gets executed and the object ds18 with the name "ds18" stored in the components. After that, the dictionary "COMPONENTS" will get loaded but since there's already an object with the name "ds18", it will be ignored. So all the time you were just trying to get the object "ds18=DS18(pin=10)" to change its intervals by changing the config in COMPONENTS which gets ignored. But there should be an error displayed that the component ds18 has already been added.

So either configure your ds18 object in COMPONENTS dictionary or in code, but not both because the configuration in the dictionary will be ignored.

(Then you will also encounter that expose_intervals=True will cause an error)

So the easiest way might be to just add the "pin=10" argument to the dictionary and remove everything except the dictionary. And please check the output of the microcontroller for errors.

(A public HASS dashboard without login sounds interesting, but why?)

Nabla128k commented 4 years ago

Ok, thanks for explanation! I've misunderstood example in https://github.com/kevinkk525/pysmartnode/blob/master/_templates/components.py (for GPIO component there's (from my understanding) the same approach... (?) - gpio = GPIO(discover_pins=["D0", "D1", "D2"]) ) update: I've probably did't understand this: '# Alternatively or additionally you can register components manually,' '# which saves a lot of RAM as no dict doesn't get loaded into RAM.' '# This example provides the same configuration as the COMPONENT dict above:' ....

However, I've deleted everything except COMPONENT={...} and added "pin":10, into constructor_args subdict.. Also deleted expose_intervals=True for now... Now I have:

[2020-10-18 20:28:22] [DS18] [critical] Exception in component loop: Traceback (most recent call last): File "pysmartnode/utils/component/sensor.py", line 347, in _loop File "pysmartnode/components/sensors/ds18.py", line 131, in _read TypeError: list indices must be integers, not str .... [2020-10-18 20:54:03] [config] [info] Added module DS18 version 3.4 as component ds18 [2020-10-18 20:54:04] [config] [info] Added module DS18 version 3.4 as component None .... (I don't know where's my fault...)

And btw yes - I've seen that error about "ds18" already imported (or something like that), but didn't catch it....

(about public dashboard - I want to measure some environmental parameters in my garden and share it with other gardeners around me - like freezing temperature etc. - on a public accessible www dashboard)

kevinkk525 commented 4 years ago

'# Alternatively or additionally you can register components manually,'

Yes this means you can either configure a component using the dictionary or using the code. But not both. The example shows the same configuration in both styles. The same is true for the GPIO.

[2020-10-18 20:28:22] [DS18] [critical] Exception in component loop: Traceback (most recent call last):
File "pysmartnode/utils/component/sensor.py", line 347, in _loop
File "pysmartnode/components/sensors/ds18.py", line 131, in _read
TypeError: list indices must be integers, not str

Oh this is another bug that occurs when a sensor is disconnected. But for this code to be reachable, you must have a configuration with auto_detect=True and rom=None and then disconnect the sensor. Fixed that bug here: https://github.com/kevinkk525/pysmartnode/commit/f9abbb25ebbaa687ac80abad9a85e671f21b135d Guess I should build a new firmware for the esp8266 tomorrow xD

[2020-10-18 20:54:03] [config] [info] Added module DS18 version 3.4 as component ds18
[2020-10-18 20:54:04] [config] [info] Added module DS18 version 3.4 as component None

This is strange, you should not have 2 DS18 objects if only one is configured in your COMPONENTS dictionary. Can you post your complete components.py please and the whole output during esp8266 boot?

(ah well that is an interesting use-case. Take a look at appdaemon dashboards, a bit more complicated and you have to build it yourself but afaik it can be accessed without a password. Has been a while since I used it. And I don't know about the security of making it public, you might have to ask on the forum about that: https://appdaemon.readthedocs.io/en/latest/DASHBOARD_INSTALL.html )

Nabla128k commented 4 years ago

pysmartnode.log

components.py.txt

... attaching files... rom: is commented out but not set to None explicitly

thanks for support, I like pysmartnode :-)

(I've already found AppDaemon, but it seemed for me quite complicated/don't understand how to even start :-) I got HomeAssistant at Raspberry Pi3 running Raspbian, so no official HA distro and it seems even more complicated.. but bare HomeAssistant run well. Maybe I just make some other dasboard like Smashing/Dashing and some kind of simple MQQT>HTTP bridge....)

kevinkk525 commented 4 years ago

Thanks, I now understand what's happening in the logs and found a few more bugs.. Will try to push a new version tomorrow that fixes all that. Fixes are already pushed to the dev branch. I'm using the ds18 component myself but only as a generic sensor with one connected ds18 unit (with no rom provided but with auto_detect=False) or with multiple ds18 units but providing a rom.. So for now auto_detect=True doesn't work correctly. But if you only have 1 sensor connected, then you don't need auto_detect=True.

I'm glad you like it :)

(yeah it can be tricky. Took me a while too.. Well maybe you get an answer on the homeassistant forum)

kevinkk525 commented 4 years ago

Ok I built an esp8266 with all the ds18 fixes, please try this one: firmware-combined.zip

Nabla128k commented 4 years ago

It seems ok, now it works with the same (correct) components.py. Just one thing (last two lines of log): PySmartNode version 613 started free ram 28944 free ram 27376 Starting uasyncio loop [2020-10-19 05:46:56] [config] [info] Added module STATS version 1.71 as component STATS [2020-10-19 05:46:57] [MQTT] [info] mqtt connected [2020-10-19 05:46:57] [MQTT] [info] WIFI state True Connected, local ip '192.168.100.17' Synchronize time from NTP server ... Set time to (2020, 10, 19, 6, 47, 8, 0, 293) [2020-10-19 06:47:08] [DS18] [info] Sensor DS18_102624ED020800F5 will publish readings for temperature to topic home/krnsko1/DS18_102624ED020800F5 [2020-10-19 06:47:08] [MQTT] [info] (sysname='esp8266', nodename='esp8266', release='2.2.0-dev(9422289)', version='v1.13-107-g18518e26a-dirty on 2020-10-19', machine='ESP module with ESP8266') [2020-10-19 06:47:09] [MQTT] [info] Client version: 613 [2020-10-19 06:47:09] [STATS0] [info] 17920 [2020-10-19 06:47:10] [config] [info] Added module DS18 version 3.6 as component ds18 [2020-10-19 06:47:11] [config] [info] Added module DS18 version 3.6 as component ds18_102624ED020800F5

Is this ok? It was (in 612 version): [2020-10-18 21:49:00] [config] [info] Added module DS18 version 3.4 as component ds18 [2020-10-18 21:49:00] [config] [info] Added module DS18 version 3.4 as component None

However, as far as I can say it seems fine. I have to learn how to control intervals from H.A. easily and so... Just one question - how "friendly_name" gets into Home Assistant? I don't see it here and also not in mqtt data and log...

Thanks for support!

kevinkk525 commented 4 years ago

The difference you saw is a feature I added. The ds18 module with auto_detect=True creates a new ds18 object for each sensor it can find. But adding it without a name looks ugly and impractical so now it creates it with the name "ds18_sensorid".

Glad it works now. You can also use it with expose_intervals=True now. Changing intervals from HA however is not that easy.. You need a helper for choosing a numeric value and an automation that publishes that value to the ../set topic. Then the device will confirm the change by publishing on the topic without /set at the end. I wanted to have that for my pump in the garden but actually just left it as it is and never change it :D

As for friendly name: https://www.home-assistant.io/docs/configuration/customizing-devices/#friendly_name "Name of the entity as displayed in the UI." That value is only published with the discovery message for a sensor, you won't see it in the logs but in the mqtt discovery message (subscribe to homeassistant/# if you didn't change that config).

Nabla128k commented 4 years ago

Ok, thanks, I think we can close this issue?

I don't see friendly_name in HA dashboard items, but maybe I have to delete device and let it discover again as new, because "frendly_name" was probably not set when creating device... never mind, I'll play with it later. Thanks again.

kevinkk525 commented 4 years ago

Changing the friendly_name in your config will change it in HA too. It is the name displayed in your dashboard. grafik

  htu:
  {
    package: .sensors.htu21d
    component: HTU21D
    constructor_args:
    {
      i2c: i2c
      precision_temp: 2         #precision of the temperature value published
      precision_humid: 1        #precision of the humid value published
      temp_offset: 0.0            #offset for temperature to compensate bad sensor reading offsets
      humid_offset: 5.0           #...   
      friendly_name_temp: "Temperature internal"  # optional, friendly name shown in homeassistant gui with mqtt discovery
      friendly_name_humid: "Humidity internal" # optional, friendly name shown in homeassistant gui with mqtt discovery          
    }
  }
Nabla128k commented 4 years ago

Not in my case :-) "Name override" is empty (and always was) and I changed friendly name without visible effect (discovery is on)

''{"~":"home/krnsko1/status","name":"Status krnsko1","stat_t":"~","uniq_id":"krnsko1_status","avty_t":"home/krnsko1/available","json_attributes_topic":"~","unit_of_meas":"dBm","val_tpl":"{{value_json.RSSI|int}}","ic":"mdi:information-outline","dev":{"ids":"krnsko1","sw":"pysmartnode 613","mf":"espressif","mdl":"esp8266","name": "krnsko1","connections": [["mac", "68:c6:3a:84:1e:9b"]]}} {"~":"home/krnsko1/HTU0","name":"Humidity","stat_t":"~","uniq_id":"krnsko1_HTU0H","avty_t":"home/krnsko1/available","dev_cla":"humidity","unit_of_meas":"%","val_tpl":"{{ value_json.humidity }}","expire_after":"1259","dev":{"ids":"krnsko1","sw":"pysmartnode 612","mf":"espressif","mdl":"esp8266","name": "krnsko1","connections": [["mac", "68:c6:3a:84:1e:9b"]]}} {"~":"home/krnsko1/HTU0","name":"Temperature","stat_t":"~","uniq_id":"krnsko1_HTU0T","avty_t":"home/krnsko1/available","dev_cla":"temperature","unit_of_meas":"°C","val_tpl":"{{ value_json.temperature }}","expire_after":"1259","dev":{"ids":"krnsko1","sw":"pysmartnode 612","mf":"espressif","mdl":"esp8266","name": "krnsko1","connections": [["mac", "68:c6:3a:84:1e:9b"]]}} {"~":"home/krnsko1/DS18","name":"Temperature","stat_t":"~","uniq_id":"krnsko1_DS18T","avty_t":"home/krnsko1/available","dev_cla":"temperature","unit_of_meas":"°C","val_tpl":"{{ value|float }}","expire_after":"251","dev":{"ids":"krnsko1","sw":"pysmartnode 612","mf":"espressif","mdl":"esp8266","name": "krnsko1","connections": [["mac", "68:c6:3a:84:1e:9b"]]}} {"~":"home/krnsko1/DS18_102624ED020800F5","name":"Temperature","stat_t":"~","uniq_id":"krnsko1_DS18_102624ED020800F5T","avty_t":"home/krnsko1/available","dev_cla":"temperature","unit_of_meas":"°C","val_tpl":"{{ value|float }}","expire_after":"62","dev":{"ids":"krnsko1","sw":"pysmartnode 613","mf":"espressif","mdl":"esp8266","name": "krnsko1","connections": [["mac", "68:c6:3a:84:1e:9b"]]}} {"~":"home/krnsko1/easyGPIO/D0","name":"easyGPIO_D0","stat_t":"~","uniq_id":"krnsko1_easyGPIO_D0","avty_t":"home/krnsko1/available","cmd_t":"~/set","dev":{"ids":"krnsko1","sw":"pysmartnode 612","mf":"espressif","mdl":"esp8266","name": "krnsko1","connections": [["mac", "68:c6:3a:84:1e:9b"]]}} {"~":"home/krnsko1/easyGPIO/D1","name":"easyGPIO_D1","stat_t":"~","uniq_id":"krnsko1_easyGPIO_D1","avty_t":"home/krnsko1/available","cmd_t":"~/set","dev":{"ids":"krnsko1","sw":"pysmartnode 612","mf":"espressif","mdl":"esp8266","name": "krnsko1","connections": [["mac", "68:c6:3a:84:1e:9b"]]}} {"~":"home/krnsko1/easyGPIO/D2","name":"easyGPIO_D2","stat_t":"~","uniq_id":"krnsko1_easyGPIO_D2","avty_t":"home/krnsko1/available","cmd_t":"~/set","dev":{"ids":"krnsko1","sw":"pysmartnode 612","mf":"espressif","mdl":"esp8266","name": "krnsko1","connections": [["mac", "68:c6:3a:84:1e:9b"]]}}''

Nabla128k commented 4 years ago

and with friendly_name_temp its worse: [2020-10-19 09:29:41] [config] [error] Error during creation of object 'DS18', 'ds18', version 3.6: Traceback (most recent call last): File "pysmartnode/utils/registerComponents.py", line 90, in registerComponent File "pysmartnode/components/sensors/ds18.py", line 87, in init File "pysmartnode/utils/component/sensor.py", line 58, in init TypeError: unexpected keyword argument 'friendly_name_temp'

kevinkk525 commented 4 years ago

oh yes sorry, in your case with auto_detect=True friendly_name does not work because it searches for all connected sensors and creates an object for each one. So every sensor would have the same friendly name. (friendly_name_temp does not exist for ds18 as it only has temperature)

Nabla128k commented 4 years ago

ok, clear now; thanks