Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding sensor interface and LM75 i2c sensor support #52

Merged
merged 9 commits into from
Mar 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,6 @@ ENV/

# Rope project settings
.ropeproject

#Kate
*.kate-swp
37 changes: 34 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
PI MQTT GPIO
============

Expose the Raspberry Pi GPIO pins and/or external IO modules to an MQTT server. This allows pins to be read and switched by reading or writing messages to MQTT topics.
Expose the Raspberry Pi GPIO pins, external IO modules and I2C sensors to an MQTT server. This allows pins to be read and switched by reading or writing messages to MQTT topics. The I2C sensors will be read periodically and publish their values.

Modules
-------
GPIO Modules
------------

- Raspberry Pi GPIO (`raspberrypi`)
- PCF8574 IO chip (`pcf8574`)
- PiFaceDigital 2 IO board (`piface2`)

I2C Sensors
-----------

- LM75 i2c temperature sensor (`lm75`)

Installation
------------

Expand Down Expand Up @@ -82,6 +87,32 @@ digital_inputs:
pulldown: no
```

### Sensors

Receive updates on the value of a sensor by subscribing to the `home/sensor/temperature` topic:

```yaml
mqtt:
host: test.mosquitto.org
port: 1883
user: ""
password: ""
topic_prefix: home

sensor_modules:
- name: lm75
module: lm75
i2c_bus_num: 1
chip_addr: 0x48
cleanup: no # This optional boolean value sets whether the module's `cleanup()` function will be called when the software exits.

sensor_inputs:
- name: temperature
module: lm75
interval: 15 #interval in seconds, that a value is read from the sensor and a update is published
digits: 4 # number of digits to be round
```

#### SSL/TLS

You may want to connect to a remote server, in which case it's a good idea to use an encrypted connection. If the server supports this, then you can supply the relevant config values for the [tls_set()](https://github.com/eclipse/paho.mqtt.python#tls_set) command.
Expand Down
15 changes: 14 additions & 1 deletion config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ gpio_modules:
module: stdio
cleanup: no

sensor_modules:
- name: lm75
module: lm75
i2c_bus_num: 1
chip_addr: 0x48

digital_inputs:
- name: button
module: raspberrypi
Expand All @@ -30,7 +36,7 @@ digital_inputs:
digital_outputs:
- name: bell
module: pcf8574
pin: 20
pin: 5
on_payload: "ON"
off_payload: "OFF"
initial: low
Expand All @@ -40,3 +46,10 @@ digital_outputs:
pin: 1
on_payload: "ON"
off_payload: "OFF"

sensor_inputs:
- name: temperature
module: lm75
interval: 15
digits: 4

54 changes: 53 additions & 1 deletion config.schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,29 @@ mqtt:

gpio_modules:
type: list
required: yes
required: no
default: []
schema:
type: dict
allow_unknown: yes
schema:
name:
type: string
required: yes
empty: no
module:
type: string
required: yes
empty: no
cleanup:
type: boolean
required: no
default: yes

sensor_modules:
type: list
required: no
default: []
schema:
type: dict
allow_unknown: yes
Expand Down Expand Up @@ -189,3 +211,33 @@ digital_outputs:
type: boolean
required: no
default: no

sensor_inputs:
type: list
required: no
default: []
schema:
type: dict
schema:
name:
type: string
required: yes
empty: no
module:
type: string
required: yes
empty: no
retain:
type: boolean
required: no
default: no
interval:
type: integer
required: no
default: 60
min: 1
digits:
type: integer
required: no
default: 2
min: 0
54 changes: 53 additions & 1 deletion pi_mqtt_gpio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,29 @@

gpio_modules:
type: list
required: yes
required: no
default: []
schema:
type: dict
allow_unknown: yes
schema:
name:
type: string
required: yes
empty: no
module:
type: string
required: yes
empty: no
cleanup:
type: boolean
required: no
default: yes

sensor_modules:
type: list
required: no
default: []
schema:
type: dict
allow_unknown: yes
Expand Down Expand Up @@ -193,4 +215,34 @@
required: no
default: no

sensor_inputs:
type: list
required: no
default: []
schema:
type: dict
schema:
name:
type: string
required: yes
empty: no
module:
type: string
required: yes
empty: no
retain:
type: boolean
required: no
default: no
interval:
type: integer
required: no
default: 60
min: 1
digits:
type: integer
required: no
default: 2
min: 0

""")
22 changes: 22 additions & 0 deletions pi_mqtt_gpio/modules/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,25 @@ def cleanup(self):
Called when closing the program to handle any cleanup operations.
"""
pass


class GenericSensor(object):
"""
Abstracts a generic sensor interface to be implemented
by the modules in this directory.
"""
__metaclass__ = abc.ABCMeta

@abc.abstractmethod
def setup_sensor(self, config):
pass

@abc.abstractmethod
def get_value(self, sensor):
pass

def cleanup(self):
"""
Called when closing the program to handle any cleanup operations.
"""
pass
41 changes: 41 additions & 0 deletions pi_mqtt_gpio/modules/lm75.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from pi_mqtt_gpio.modules import GenericSensor


"""REQUIREMENTS = ("smbus",)"""
CONFIG_SCHEMA = {
"i2c_bus_num": {
"type": "integer",
"required": True,
"empty": False
},
"chip_addr": {
"type": "integer",
"required": True,
"empty": False
}
}

LM75_TEMP_REGISTER = 0


class Sensor(GenericSensor):
"""
Implementation of Sensor class for the LM75 temperature sensor.
"""
def __init__(self, config):
import smbus
self.bus = smbus.SMBus(config["i2c_bus_num"])
self.address = config["chip_addr"]

def setup_sensor(self, config):
return True # nothing to do here

def get_value(self, sensor):
"""get the temperature value from the sensor"""
value = self.bus.read_word_data(self.address,
LM75_TEMP_REGISTER) & 0xFFFF
value = ((value << 8) & 0xFF00) + (value >> 8)
return self.convert_to_celsius(value)

def convert_to_celsius(self, value):
return (value / 32.0) / 8.0
Loading