Skip to content

Commit

Permalink
Merge pull request #96 from DanielDecker/22CW11_service
Browse files Browse the repository at this point in the history
service reload config
  • Loading branch information
rkoshak authored Mar 28, 2022
2 parents 87e3998 + c803322 commit 71e38db
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 24 deletions.
44 changes: 28 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ If you've used sensorReporter or mqttReporter before, this is a complete rewrite
See the release notes below for details.

A number of connections, sensors, and actuators are currently supported.
- Connection: responsible for publishing sensor readings and actuator results and subscribing for actuator commands.
- Actuators: classes that perform some action when a message is received.
- Polling Sensors: classes that query some device on a set polling period.
- Background Sensors: classes that sense for events in the background and do not require polling.
- Connection: responsible for publishing sensor readings and actuator results and subscribing for actuator commands.
- Actuators: classes that perform some action when a message is received.
- Polling Sensors: classes that query some device on a set polling period.
- Background Sensors: classes that sense for events in the background and do not require polling.

Go into the subfolders for details in each subfolder's README.

Expand Down Expand Up @@ -49,10 +49,11 @@ Each individual plug-in will define it's own set of required and optional parame
See the README files in the subfolders for details.

However, some parmeters will be common.
- All polling sensors require a Poll parameter indicating how often in seconds to poll the sensor devices
- All sections require a Class parameter defining the class to load.
- All sensors and actuators require a Connection class containing the name of the Connection to publish/subscribe through. More than one can be defined in a comma separated list.
- All sections have an optional Level parameter where the logging level for that plugin or sensor_reporter overall can be set. Supported levels are DEBUG, INFO, WARNING, and ERROR.
- All polling sensors require a Poll parameter indicating how often in seconds to poll the sensor devices
- All sections require a Class parameter defining the class to load.
- All sensors and actuators require a Connection class containing the name of the Connection to publish/subscribe through. More than one can be defined in a comma separated list.
- All actuators require a CommandSrc, which has to be unique for the configured connection. E. g. if the CommandSrc `switch2` is used by several actuators only the last one will work.
- All sections have an optional Level parameter where the logging level for that plugin or sensor_reporter overall can be set. Supported levels are DEBUG, INFO, WARNING, and ERROR.

Sensors are defined in a `[SensorX]` section where `X` is a unique number.
Connections and Actuators are defined in similarly named sections.
Expand All @@ -67,14 +68,21 @@ See the readmes in the subfolders for details.
`python3 sensor_reporter configuration.ini`

An example systemd service file is provided for your reference.
The following steps describe how to setup the service:

1. clone this repo into `/opt/sensor_reporter`
2. create a `sensorReporter` user
3. write your config ini file
4. `sudo -u sensorReporter ln -s <path to config.ini> /opt/sensor_reporter/sensor_reporter.ini`
5. `sudo cp sensor_reporter.service /etc/systemd/system`
6. `sudo systemctl enable sensor_reporter.service`
7. `sudo sytemctl start sensor_reporter`
2. create a `sensorReporter` system user: `sudo adduser --system --force-badname --home /opt/sensor_reporter sensorReporter`
3. write your config ini file and save it to `/opt/sensor_reporter/sensor_reporter.ini`
4. change owner of the ini file: `sudo chown sensorReporter:nogroup /opt/sensor_reporter/sensor_reporter.ini`
5. limit read write to owner: `sudo chmod 600 sensor_reporter.ini`
6. install service file: `sudo cp sensor_reporter.service /etc/systemd/system`
7. set service to autostart: `sudo systemctl enable sensor_reporter.service`
8. start sensor_reporter: `sudo sytemctl start sensor_reporter.service`

Some plugins will reqire additional steps, see readmes in the subfolders for details.

To reload a modifierd sensor_reporter.ini use the command: `sudo sytemctl reload sensor_reporter.service`


# Configuration
sensor_reporter uses an ini file for configuration.
Expand All @@ -85,7 +93,7 @@ In addition logging will be published to syslog or to a log file.

*Security advice:* make sure your sensor_reporter.ini is owned by the user `sensorReporter` and only that user has read and write permissions.

`sudo chown sensorReporter:sensorReporter sensor_reporter.ini`
`sudo chown sensorReporter:nogroup sensor_reporter.ini`
`sudo chmod 600 sensor_reporter.ini`

## Syslog Example
Expand All @@ -103,7 +111,7 @@ When true no other parameters are required.

```ini
[Logging]
File = /var/log/sensorReporter.log
File = /var/log/sensor_reporter/sensorReporter.log
MaxSize = 67108864
NumFiles = 10
Syslog = NO
Expand All @@ -116,6 +124,10 @@ Level = INFO
The above parameters are only required if `SysLog` is a false value.
`Level` is the same as for `Syslog = True` and indicates the default logging level.

Make sure the user `sensorReporter` has write access:
1. `sudo mkdir /var/log/sensor_reporter`
2. `sudo chown sensorReporter:nogroup /var/log/sensor_reporter`

## Sections for Components

Note that sensor_reporter requires the section names to start with the type of the plugin.
Expand Down
11 changes: 11 additions & 0 deletions core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,14 @@ def get_sequential_param_pairs(params, name1, name2):
raise ValueError("Unequal number of parameters for %s and %s ", name1,
name2)
return dict(zip(one, two))

def is_toggle_cmd(msg):
"""Returns true it the input (msg) is equal
to the string "TOGGLE" or is a ISO 8601 formatted date time
"""
is_toggle = msg == "TOGGLE"
# datetime from sensor_reporter RpiGpioSensor (e.g. 2021-10-24T16:23:41.500792)
is_dt = len(msg) == 26 and msg[10] == "T"
# datetime from openHAB (e.g. 2022-02-27T17:58:45.165491+0100)
is_dt_timezone = len(msg) == 31 and msg[10] == "T"
return is_toggle or is_dt or is_dt_timezone
4 changes: 3 additions & 1 deletion gpio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ Additionally the Sensor can detect toggle events and report the time of the even
### Dependencies

The user running sensor_reporter must have permission to access the GPIO pins.
To grant the `sensorReporter` user GPIO permissions add the user to the group `gpio`: `sudo adduser sensorReporter gpio`

Depends on RPi.GPIO.

Expand Down Expand Up @@ -150,6 +151,7 @@ A recieved command will be sent back on all configured connections to the config
### Dependencies

The user running sensor_reporter must have permission to access the GPIO pins.
To grant the `sensorReporter` user GPIO permissions add the user to the group `gpio`: `sudo adduser sensorReporter gpio`

Depends on RPi.GPIO.

Expand All @@ -166,7 +168,7 @@ Parameter | Required | Restrictions | Purpose
`Level` | | DEBUG, INFO, WARNING, ERROR | When provided, sets the logging level for the sensor.
`CommandSrc` | X | | Destination/openHAB switch item where commands are received, expects ON/OFF. If Toggle is set all messages trigger a toggle.
`ToggleCommandSrc` | | | Destination/openHAB string item where toggle commands are recieverd. This is intended to be used for direct connections to a sensor via the Short_Press-Dest/Long_Press-Dest parameter. Expects the string TOGGLE, when recieved the output of the actuator will get toggled e.g. from LOW to HIGH until further commands. If the parameter `SimulateButton` is configured to TRUE this parameter is ignored. If not configured no ToggleCommandSrc will be registerd.
`ToggleDebounce` | | decimal number | The interval in seconds during which repeated toggle commands are ignored (Default 0.05 seconds)
`ToggleDebounce` | | decimal number | The interval in seconds during which repeated toggle commands are ignored (Default 0.15 seconds)
`Pin` | X | IO Pin | Pin to use as actuator output, using the pin numbering defined in `PinNumbering` (see below).
`InitialState` | | ON or OFF | Optional, when set to ON the pin's state is initialized to HIGH.
`SimulateButton` | | Boolean | When `True` simulates a button press by setting the pin to HIGH for half a second and then back to LOW. In case of `InitalState` ON it will toggle the other way around.
Expand Down
8 changes: 4 additions & 4 deletions gpio/rpi_gpio.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from RPi import GPIO
from core.sensor import Sensor
from core.actuator import Actuator
from core.utils import parse_values
from core.utils import parse_values, is_toggle_cmd

def set_gpio_mode(params, log):
"""Set GPIO mode (BCM or BOARD) for all Sensors and Actuators
Expand Down Expand Up @@ -294,8 +294,8 @@ def __init__(self, connections, params):
try:
self.toggle_debounce = float(params("ToggleDebounce"))
except NoOptionError:
#default debaunce time 0.05 seconds
self.toggle_debounce = 0.05
#default debaunce time 0.15 seconds
self.toggle_debounce = 0.15
self.last_toggle = datetime.datetime.fromordinal(1)

#remember the current output state
Expand Down Expand Up @@ -327,7 +327,7 @@ def on_message(self, msg):
" which is equal to current output state. Ignoring command!",
self.cmd_src, msg)
return
elif msg == "TOGGLE" or len(msg) == 26 and msg[10] == "T":
elif is_toggle_cmd(msg):
# If the string has length 26 and the char at index 10
# is T then its porbably a ISO 8601 formated datetime value,
# which was send from RpiGpioSensor
Expand Down
1 change: 1 addition & 0 deletions heartbeat/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

The Heartbeat sensor is a utility to report the sensor_reporter uptime.
This reliable scheduled reporting could be used as a heartbeat and the messages can be used to see how long sensor_reporter has been online.
To detect if sensor_reporter is offline, the linked item on openHAB can use the [expire parameter](https://www.openhab.org/docs/configuration/items.html#parameter-expire), which can be set via 'add metadata > expiration timer' in the item settings.

## Dependencies

Expand Down
4 changes: 3 additions & 1 deletion local/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Any sensor that has the Local Connection listed will publish it's readings to th
Any sensor that needs to react to that sensor's reading would also list the Local Connection and will use the same destination.

Local Connection allows some simple less than, greater than,and equals logic.
Toggle events, e.g. from a RpiGpioSensor will get forwarded in any case.

## Parameters

Expand All @@ -25,8 +26,9 @@ Parameter | Required | Restrictions | Purpose

One of `OnEq`, `OnGt`, or `OnLt` need to be present and `True`.
If more than one is present and `True` the first one marked as `True` is selected in the order listed (e.g. if `OnGt` and `OnLt` are both `True`, `OnGt` will be used and `OnLt` will be ignored).
Toggle events a evaluated before `OnEq`, `OnGt` and `OnLt`.

If none of the three optional parameters are supplied, the Connection will not do anything.
If none of the three optional parameters are supplied, the recieved messages will get forwarded unchanged.

## Example Configs

Expand Down
8 changes: 6 additions & 2 deletions local/local_conn.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"""
from configparser import NoOptionError
from core.connection import Connection
from core.utils import is_toggle_cmd

class LocalConnection(Connection):
"""A special connection that can link Sensors and Actuators to other
Expand Down Expand Up @@ -93,7 +94,10 @@ def publish(self, message, destination, filter_echo=False):
if destination in self.registered:
try:
send = message
if self.eq and message == self.eq:
# forward TOGGLE and ISO formated time messages
if is_toggle_cmd(message):
send = "TOGGLE"
elif self.eq and message == self.eq:
send = "ON"
elif self.eq:
send = "OFF"
Expand All @@ -111,4 +115,4 @@ def publish(self, message, destination, filter_echo=False):
except ValueError:
self.log.error("'%s' cannot be parsed to float!", message)
else:
self.log.debug("There is no handler registered for %s", destination)
self.log.debug("There is no handler registered for %s", destination)
1 change: 1 addition & 0 deletions sensor_reporter.service
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ WorkingDirectory=/opt/sensor_reporter
User=sensorReporter
Type=simple
ExecStart=python3 sensor_reporter.py sensor_reporter.ini
ExecReload=/bin/kill -HUP $MAINPID

[Install]
WantedBy=multi-user.target

0 comments on commit 71e38db

Please sign in to comment.