Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Using moisture sensors to control programs
#1
Hi,

I have some Zigbee moisture sensors that I connect to my MQTT server using Zigbee2MQTT.

I would like to try and write a plugin that
  • Assigns a sensor to a station (via an MQTT topic?)
  • Allows the setting of a threshold moisture value per station
  • Suppresses any program from running for a station if the reported moisture value is higher than the threshold value
  • Shows if a program has been suppressed
  • Shows a graph of the moisture sensor values

Can someone please give me any pointers as to how to best to go about writing such a plugin?

Thanks in advance.
Reply
#2
Welcome,

There are a couple of ways to go about this.

1) You could use the Proto plugin that is included with the SIP installation as a stating point.
The MQTT plugin provides basic MQTT functioality.
The gv_reference.pdf file in the SIP documentation wiki provides information on how to control SIP behavior.
You would need to implement the graph using a JavaScript library like Chart.js

2) You could use Node-red and the new node-red plugin included with the SIP installation. Node red provides MQTT capability and graphing via the Dashboard modules.
https://github.com/Dan-in-CA/node-red-si...nodes/wiki
<p><br></p>
Reply
#3
Hello Dan,

thank you for taking the time to reply.

I did not find the file gv_reference.pdf, but I did find gv_reference.txt. I'm guessing they have the same content.

While I do use Node Red extensively, I would like to avoid that dependency at the moment.

If I go down the plugin route then would the following be about correct:

Assigns a sensor and moisture threshold to each station
- Create an HTML plugin page
- Display a table with station / MQTT topic / threshold
- Store the table in the plugin data file

Suppress any program from running for a station if the reported moisture value is higher than the threshold value
- Add signal for "stations_scheduled"
- Load data from plugin data file
- Check all gv.srvals for station 1 = turn on
 -  if the station MQTT topic value > station threshold value set gv.srvals for station 0 = turn off

Show if a program has been suppressed
- Might be part of the standard functionality already?

Shows a graph of the moisture sensor values
- Create a graph with Chart.js which show the moisture values for each station per week
- Should this be on the plugin page or in the footer of the main page or somewhere else?

Also on a slightly different topic it does not seem that I can set a water level on a per station basis, is this correct?
Reply
#4
Your descriptions of the plugin functionality are good.

You are right about the water level setting affecting all stations but you can control individual station duration times. those settings are in the variables gv_rs and gv_ps.

Even though you don't plan to use node-red for your project you may find some useful Python code in the node-red.py file in the plugins folder.

There is also a flow in the node-red library named "SIP Irrigation diagnostics":
https://flows.nodered.org/flow/378b38c41...e2fc3249f5

It can read and write SIP control variables while SIP is running. I find it to be a very useful development tool for SIP.
You just need to enable the node-red plugin.

As far as where to put the graph, it would depend how often you want to view the data. In the footer will always be visible. On a plugin HTML page would give you more space but you would need to open the page to view the data.

The gv_reference.pdf is at:
https://raw.githubusercontent.com/wiki/D...erence.pdf
but it is the same as the .txt file in the SIP directory.
<p><br></p>
Reply
#5
I'm having trouble with gv.srvals in that is not behaving as expected.

I have the following code in my plugin moisture_sensor.py

Code:
def notify_stations_scheduled(station, **kw):
    print("Station {} run started".format(station))
    print(f"srvals {gv.srvals}")


complete = signal("stations_scheduled")
complete.connect(notify_stations_scheduled)

I have set up a program to run every 1 minute for a duration of 30 seconds on station 2

In the logfile I see the following output

Code:
http://:::80/
Some Stations have been scheduled: [[0, 0, 0, 0], [1705407497, 1705407527, 30, 1], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Station SIP run started
srvals [0, 0, 0, 0, 0, 0, 0, 0]

I would have expected the srvals list to have the value  [0, 1, 0, 0, 0, 0, 0, 0] and not  [0, 0, 0, 0, 0, 0, 0, 0] as the second station is scheduled.

Any ideas what II need to change?
Reply
#6
After playing around quite a bit it seems that
  • srvals is set on signal zone_change and not on stations_changed
  • rs is set on signal stations_scheduled
  • setting rs[x] to [0, 0, 0, 0] will stop the schedule from running on station x

in which case it would seem that the following documentation is wrong as gv.srvals should be gv.rs
   "stations_scheduled      a program is started (Scheduled or "run now"), or station is manually started (check gv.srvals for stations set to run))"


Is there a way to determine if a station was triggered by schedule/Run Now or Run Once? 
The reason I ask is that while it makes sense to suppress a Schedule it might not make sense to suppress a Run Now and it does not make sense to suppress a Run Once.
Reply
#7
(2024 Jan 17, 01:30 PM)cdesouza Wrote: After playing around quite a bit it seems that
  • srvals is set on signal zone_change and not on stations_changed
  • rs is set on signal stations_scheduled
  • setting rs[x] to [0, 0, 0, 0] will stop the schedule from running on station x

in which case it would seem that the following documentation is wrong as gv.srvals should be gv.rs
   "stations_scheduled      a program is started (Scheduled or "run now"), or station is manually started (check gv.srvals for stations set to run))"
Is there a way to determine if a station was triggered by schedule/Run Now or Run Once? 
The reason I ask is that while it makes sense to suppress a Schedule it might not make sense to suppress a Run Now and it does not make sense to suppress a Run Once.

The signals (blinker signals) are notifications broadcast by SIP that can be used by plugins to trigger functions but they do not trigger functions in the core sip code.

As far as determining what triggered a program the gv.pon variable should hold the program number but it does not work for Run Now or Run Once. I will look into adding those.

There are 3 special program numbers:
98 = Run-once Program
99 = Manual mode
100 = Node-red

I will try to add a way to determine if a program was started with Run Now rather than by the start time.
dan
<p><br></p>
Reply
#8
OK.
I fixed gv.pon to show the program number for run once and manual started programs.
It is available in SIP version 5.1.19.

You can determine if a program was started by run now if the start time in gv.rs is different from the program's scheduled start time in gv.pd.

Here is some example code for doing that (not tested):
Code:
from datetime import datetime
for stn in gv.rs:
    if stn[0] != 0:
    timestamp = stn[0] #First station with a start time
    break
dt_obj = datetime.fromtimestamp(timestamp)
start_min = (dt_obj.hour * 60) + dt_obj.minute
print("start minute", start_min)
# compare start_min to start time of program in gv.pd
manual_start = gv.pd[gv.pon - 1]["start_min"] != start_min
<p><br></p>
Reply
#9
Quote:The signals (blinker signals) are notifications broadcast by SIP that can be used by plugins to trigger functions but they do not trigger functions in the core sip code.

So long as overriding gv.rs is the correct way to suppress a program I'm good.

Quote:As far as determining what triggered a program the gv.pon variable should hold the program number but it does not work for Run Now or Run Once. I will look into adding those.

There are 3 special program numbers:
98 = Run-once Program
99 = Manual mode
100 = Node-red

I will try to add a way to determine if a program was started with Run Now rather than by the start time.

Thanks, that will be very helpful.

In the meantime I'm making progress and I have two basic plugins (Moisture Sensor Control / Moisture Sensor Data MQTT) that:
  • Gather moisture readings regularly from sensors via MQTT
  • Assign afore mentioned sensors to stations
  • Suppress programs based on the assigned sensor value
but there is still much to do:
  • UI data validation and backend error handling
  • Add missing functionality like Reading path / Enable / Retention period / Stale reading 
Can you recommend any plugins with good examples of UI data validation?

   
   
Reply
#10
I don't think most plugins use data validation.
<p><br></p>
Reply


Forum Jump:


Users browsing this thread: 8 Guest(s)