Commit cc4bab10 authored by Eduard Jozef Pitoňák's avatar Eduard Jozef Pitoňák
Browse files

Initial commit

parents
-----BEGIN CERTIFICATE-----
MIIEJTCCAw2gAwIBAgIUfY7SmN3lVLI8a0ooexaJR8FFgXswDQYJKoZIhvcNAQEL
BQAwgaExCzAJBgNVBAYTAlNLMRIwEAYDVQQIDAlQcmVzb3Zza3kxDzANBgNVBAcM
BlBvcHJhZDEVMBMGA1UECgwMbWV0ZW9rcm1pdGtvMRQwEgYDVQQLDAtpb3Rfa3Jt
aXRrbzEYMBYGA1UEAwwPREVTS1RPUC0zQjZKR0U5MSYwJAYJKoZIhvcNAQkBFhdi
b3pvbi5sdWthczIyQGdtYWlsLmNvbTAeFw0yMTA0MjkxMzAzNTJaFw0yNjA0Mjkx
MzAzNTJaMIGhMQswCQYDVQQGEwJTSzESMBAGA1UECAwJUHJlc292c2t5MQ8wDQYD
VQQHDAZQb3ByYWQxFTATBgNVBAoMDG1ldGVva3JtaXRrbzEUMBIGA1UECwwLaW90
X2tybWl0a28xGDAWBgNVBAMMD0RFU0tUT1AtM0I2SkdFOTEmMCQGCSqGSIb3DQEJ
ARYXYm96b24ubHVrYXMyMkBnbWFpbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQC98QkZvjBhLjYfL/GPtSffryPe0WYpp9WECXzTumQRN7pq18u9
QPZk3vNc3TFC2WOLxK78693aSm7t8xNw845rUVYlb2BRJTih4awkZBGrxknLX8BO
ihBpwJq3wjDXE5GD4XRxD+dzWuwKYQkuc6ethOPLa/hWxuEFoUO+T3TkODfq/EUJ
oyai9Szx/W0Xna9y5eeIwnHP6ZJ/E7VZEWg3aw4KTaWNOElM1C3OjmWoWhY5uiej
XOp/tPdKt/RNyC5xnY+JIL/KigNeMIxaJ+/AIHRt1KINqbNn0rrS7fOimV4fWj4G
4AhjHhAQoOzUe84aEauEmUm9JSRpjeqamBnrAgMBAAGjUzBRMB0GA1UdDgQWBBS+
jMUt9VgWEIL+QdnOpQy8LHEyYTAfBgNVHSMEGDAWgBS+jMUt9VgWEIL+QdnOpQy8
LHEyYTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCF77Oxjn/E
+tu89hNOXGwtbwxlaOSIK2eEdLE+WhXnoU5RRB4pKZttnC1bv+PC7XBvZ656JS36
L55p5D5UwxzgKSGLwIn3t7SY+oqwbEutN+2ZHOsYO9WidKRpo0icwROW8dS5IhZJ
pqZv3uynejKS3zDhAv5AHT9KSvVQnYNaPx7KIvrAuhWg0zR8OCv4M/JT0BejJzQd
cJdAl70JRhabBWuHpIg7oPy4w7l4OzX/uoS6qaW4m7JC87gXtQmQCqgMfe00oeIo
tLwwSbmR6g2y9Ob9tLUlqjJusjeTJpjeoOP591rETJa8Izw+lwWA4beSBrpE8paz
lbe2Vjne2S5k
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE REQUEST-----
MIIDCzCCAfMCAQAwgagxCzAJBgNVBAYTAlNLMRIwEAYDVQQIDAlQcmVzb3Zza3kx
DzANBgNVBAcMBlBvcHJhZDEVMBMGA1UECgwMbWV0ZW9rcm1pdGtvMRswGQYDVQQL
DBJpb3Rfc2VydmVyX2tybWl0a28xGDAWBgNVBAMMD0RFU0tUT1AtM0I2SkdFOTEm
MCQGCSqGSIb3DQEJARYXYm96b24ubHVrYXMyMkBnbWFpbC5jb20wggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDCOiU9ED7M/lQCyyiGjZ5KWSxGcw9aHN75
Lbm95aXYaULo0uYXVI+ZmgUSP2na5DSEvsXX7C9MleeRuURWLLZjA1jLk5SPFWLg
XnzyTXRmqBVwYQ30sSGrg2fw5L/3OUiMXN2DLwwWJT/XXQtxatG++IlcNUotgvbB
9o1pBonWBhAipirxWNc2Anp3gqY4Od1B8E9YCSUMJ7ObbJlJIOlg5R6cgDjZiTkO
FZIZ4V7NPoiVDaXCdRyYZvrxE7CmKC2VV/aYmcTAF8yJWZBzDjC4Z+Wj5yWgRnGc
Fd27XEk0ZL0w8ViSIXTCKhLXgxxyWMitZC4vAohkaOmq9ddVzXv3AgMBAAGgHTAb
BgkqhkiG9w0BCQcxDgwMbWV0ZW9rcm1pdGtvMA0GCSqGSIb3DQEBCwUAA4IBAQAY
JlgsRWCMyu5iqYgfxDARs1rs4XcIuKYvumHaaR+4v9VDDFzq7Q/Gyf1PS55cVLZH
HmeDIE0FzF1AUubhHkWpNii9slc7d3mcbfwq3ZScYCjdWUdL1YwQp9WF5gW5JCTe
aDiuqRSgeG6UPZns3w+pJUKFAj1vIsO05l+mACBZwVlutvd2u8neMUFSBts3Ysfq
Rm4ZXYJKHiV4vRNvDu1DFRgJM3uUOsv6Q4KyI5YMtatkdK8LMPLSneW5eibOFXS4
z1UInLXxP41+sxJ//XebCTMH8fAJgm7E46CegwsZRjopkLh1IEugvb6ZtwAUMk2Z
FMcvCQTcLr86kpdaGGqw
-----END CERTIFICATE REQUEST-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwjolPRA+zP5UAssoho2eSlksRnMPWhze+S25veWl2GlC6NLm
F1SPmZoFEj9p2uQ0hL7F1+wvTJXnkblEViy2YwNYy5OUjxVi4F588k10ZqgVcGEN
9LEhq4Nn8OS/9zlIjFzdgy8MFiU/110LcWrRvviJXDVKLYL2wfaNaQaJ1gYQIqYq
8VjXNgJ6d4KmODndQfBPWAklDCezm2yZSSDpYOUenIA42Yk5DhWSGeFezT6IlQ2l
wnUcmGb68ROwpigtlVf2mJnEwBfMiVmQcw4wuGflo+cloEZxnBXdu1xJNGS9MPFY
kiF0wioS14MccljIrWQuLwKIZGjpqvXXVc179wIDAQABAoIBAHxZy9OvnfWS82ii
d3zGGM0TEJS+P9r61wsD6oKZEDhhFDSKKkRPoGzAPnTzYquBJdrDZVmb3qCS7SLQ
Ud82W0NDNkuIXjnJgHeUJzzeuCKthKRhjxTVf3AW/qotWnZHF5q+Lhg6O+vFx3z0
Fkp0EHvLFe6SM761tZRzbRAL3p3GQG8wOOwf1ZhUbnn/V/VZrwEY9m/0E6nu80Ff
ywdgEm5fiO/+CLtp3Af2oS1seOmT6VjmxugKfoLPAxiBqQBw8zq+OiTy3dpzVJAo
J4OXhw2YSESqbuteAlgPIWeQsumH4/lUwW8UXqSRyyLM776OcrIUMYDSoLE/S/eh
jVLz7gkCgYEA4IstLHSHEx6gomC04J+AYrjzVJ5r90wjECXxjNgrwwlfqJ5B6Kku
0t7CEKkpZCuEkYB8hziDGe/U4HCvote/sVnDG4tWvEUNbsQ59hWqq/fm9EowcYCv
C9xnRqCYwt7tdT1PzGYuV4u5CIKQah0xnJF5exrklqqyPoWTzw5wKaMCgYEA3W+5
twKNjmyagD9gubm78o2TlYf6ReeWMxwK/2oGquAaVZF0BINWhB5P4XLIc0CF9YNy
/7Xrmcuf/xwvskzJ3+Kqfb7DiaWmbbveoiU2/PT6XpxmzH4nfCoETZfWbe8L4PAR
0So8hn7H39VY42bKV1ISWP6N9xIjYmh0z+UBcZ0CgYEAtvvUKVkgxkz8PLcwT6jL
uCfebAPaGiJapIs3SD7VktAtuzyUm2Rbuw46+dbQ20e3dddOI+fCtr1CLlDGYJ8P
IRj0LZskaLKhGrYgQdEwT4nrFQLsbWKfw7uuEdlIA+4ldpgrUnempkM/25aC12bJ
Cj1m0RJ+W+Xo8Zhrdp3ee58CgYB6YHOXk76dtqGQPPZ8zgvz2ZB1tEd5eKqGpnnh
fDwhFWcYYSFoGRmoPIRTCTeEkmU2MSZN8cE6JtHOkEo/1LZAmCk3A0VXfgfDX2+D
1uNT2yO/Q9qAKzwxH5tvMnncGZ9L+gEuwpPelJRrvKG6UyWCKqZfLpdQs2KA0U+1
UU+B9QKBgDa12UrQNqxHWf4bl87Od+QYn5jeGUbjfDOwtqW0jOx9h70sSLj9xnC/
qTgeUF89S4ibhYecwzWyznf+B/RFeeS8/19eaNDOA/ZrB474WlW9AIx9O8G1lBjM
PJVqKhNM2rvgChKhOSC1kAH//5l4dvxro96R5ZxGcuZ8dsWtOuz4
-----END RSA PRIVATE KEY-----
persistence true
persistence_location /mosquito/data/
log_dest file /mosquitto/log/mosquitto.log
password_file /mosquitto/config/pwfile
allow_anonymous false
listener 1883
#tls_version tlsv1.2
#cafile /certs/ca.crt
#certfile /certs/server.crt
#keyfile /certs/server.key
#port 1883
#listener 8883
#require_certificate true
#use_identity_as_username true
meteokrmitko:$7$101$GaIZDZexjG7iZWEC$nYIDreF50LbC1HKZJ4xRnGV1hKazY6wv9y73fBjVPl4/CXeznOwTEFmmf6wGxfDdSO9+IO9LkDU4BgpcBLgkNQ==
version: "3.6"
services:
nodered:
image: nodered/node-red
container_name: node-red
ports:
- "1880:1880"
volumes:
- node_red_data:/data
networks:
- feeder_net
influxdb:
image: influxdb:1.8
container_name: influxdb
environment:
- INFLUXDB_DB=db
- INFLUXDB_ADMIN_USER=krmitkar
- INFLUXDB_ADMIN_PASSWORD=AAZXcp#/hCq7jf>^
- INFLUXDB_USER=krmic
- INFLUXDB_USER_PASSWORD=JJD4j)ycMh^j\GND
ports:
- "8086:8086"
volumes:
- influxdb:/var/lib/influxdb
networks:
- feeder_net
mosquitto:
container_name: mosquitto
image: eclipse-mosquitto
volumes:
- mosquitto-data:/mosquitto/data
- mosquitto-logs:/mosquitto/logs
- mosquitto-conf:/mosquitto/config
ports:
- "1883:1883"
- "8883:8883"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
volumes:
- grafana:/var/lib/grafana
networks:
- feeder_net
volumes:
node_red_data:
influxdb:
grafana:
mosquitto-data:
mosquitto-logs:
mosquitto-conf:
networks:
feeder_net:
\ No newline at end of file
from machine import I2C
import time
# BME280 default address.
BME280_I2CADDR = 0x76
# Operating Modes
BME280_OSAMPLE_1 = 1
BME280_OSAMPLE_2 = 2
BME280_OSAMPLE_4 = 3
BME280_OSAMPLE_8 = 4
BME280_OSAMPLE_16 = 5
# BME280 Registers
BME280_REGISTER_DIG_T1 = 0x88 # Trimming parameter registers
BME280_REGISTER_DIG_T2 = 0x8A
BME280_REGISTER_DIG_T3 = 0x8C
BME280_REGISTER_DIG_P1 = 0x8E
BME280_REGISTER_DIG_P2 = 0x90
BME280_REGISTER_DIG_P3 = 0x92
BME280_REGISTER_DIG_P4 = 0x94
BME280_REGISTER_DIG_P5 = 0x96
BME280_REGISTER_DIG_P6 = 0x98
BME280_REGISTER_DIG_P7 = 0x9A
BME280_REGISTER_DIG_P8 = 0x9C
BME280_REGISTER_DIG_P9 = 0x9E
BME280_REGISTER_DIG_H1 = 0xA1
BME280_REGISTER_DIG_H2 = 0xE1
BME280_REGISTER_DIG_H3 = 0xE3
BME280_REGISTER_DIG_H4 = 0xE4
BME280_REGISTER_DIG_H5 = 0xE5
BME280_REGISTER_DIG_H6 = 0xE6
BME280_REGISTER_DIG_H7 = 0xE7
BME280_REGISTER_CHIPID = 0xD0
BME280_REGISTER_VERSION = 0xD1
BME280_REGISTER_SOFTRESET = 0xE0
BME280_REGISTER_CONTROL_HUM = 0xF2
BME280_REGISTER_CONTROL = 0xF4
BME280_REGISTER_CONFIG = 0xF5
BME280_REGISTER_PRESSURE_DATA = 0xF7
BME280_REGISTER_TEMP_DATA = 0xFA
BME280_REGISTER_HUMIDITY_DATA = 0xFD
class Device:
"""Class for communicating with an I2C device.
Allows reading and writing 8-bit, 16-bit, and byte array values to
registers on the device."""
def __init__(self, address, i2c):
"""Create an instance of the I2C device at the specified address using
the specified I2C interface object."""
self._address = address
self._i2c = i2c
def writeRaw8(self, value):
"""Write an 8-bit value on the bus (without register)."""
value = value & 0xFF
self._i2c.writeto(self._address, value)
def write8(self, register, value):
"""Write an 8-bit value to the specified register."""
b=bytearray(1)
b[0]=value & 0xFF
self._i2c.writeto_mem(self._address, register, b)
def write16(self, register, value):
"""Write a 16-bit value to the specified register."""
value = value & 0xFFFF
b=bytearray(2)
b[0]= value & 0xFF
b[1]= (value>>8) & 0xFF
self.i2c.writeto_mem(self._address, register, value)
def readRaw8(self):
"""Read an 8-bit value on the bus (without register)."""
return int.from_bytes(self._i2c.readfrom(self._address, 1),'little') & 0xFF
def readU8(self, register):
"""Read an unsigned byte from the specified register."""
return int.from_bytes(
self._i2c.readfrom_mem(self._address, register, 1),'little') & 0xFF
def readS8(self, register):
"""Read a signed byte from the specified register."""
result = self.readU8(register)
if result > 127:
result -= 256
return result
def readU16(self, register, little_endian=True):
"""Read an unsigned 16-bit value from the specified register, with the
specified endianness (default little endian, or least significant byte
first)."""
result = int.from_bytes(
self._i2c.readfrom_mem(self._address, register, 2),'little') & 0xFFFF
if not little_endian:
result = ((result << 8) & 0xFF00) + (result >> 8)
return result
def readS16(self, register, little_endian=True):
"""Read a signed 16-bit value from the specified register, with the
specified endianness (default little endian, or least significant byte
first)."""
result = self.readU16(register, little_endian)
if result > 32767:
result -= 65536
return result
def readU16LE(self, register):
"""Read an unsigned 16-bit value from the specified register, in little
endian byte order."""
return self.readU16(register, little_endian=True)
def readU16BE(self, register):
"""Read an unsigned 16-bit value from the specified register, in big
endian byte order."""
return self.readU16(register, little_endian=False)
def readS16LE(self, register):
"""Read a signed 16-bit value from the specified register, in little
endian byte order."""
return self.readS16(register, little_endian=True)
def readS16BE(self, register):
"""Read a signed 16-bit value from the specified register, in big
endian byte order."""
return self.readS16(register, little_endian=False)
class BME280:
def __init__(self, mode=BME280_OSAMPLE_1, address=BME280_I2CADDR, i2c=None,
**kwargs):
# Check that mode is valid.
if mode not in [BME280_OSAMPLE_1, BME280_OSAMPLE_2, BME280_OSAMPLE_4,
BME280_OSAMPLE_8, BME280_OSAMPLE_16]:
raise ValueError(
'Unexpected mode value {0}. Set mode to one of '
'BME280_ULTRALOWPOWER, BME280_STANDARD, BME280_HIGHRES, or '
'BME280_ULTRAHIGHRES'.format(mode))
self._mode = mode
# Create I2C device.
if i2c is None:
raise ValueError('An I2C object is required.')
self._device = Device(address, i2c)
# Load calibration values.
self._load_calibration()
self._device.write8(BME280_REGISTER_CONTROL, 0x3F)
self.t_fine = 0
def _load_calibration(self):
self.dig_T1 = self._device.readU16LE(BME280_REGISTER_DIG_T1)
self.dig_T2 = self._device.readS16LE(BME280_REGISTER_DIG_T2)
self.dig_T3 = self._device.readS16LE(BME280_REGISTER_DIG_T3)
self.dig_P1 = self._device.readU16LE(BME280_REGISTER_DIG_P1)
self.dig_P2 = self._device.readS16LE(BME280_REGISTER_DIG_P2)
self.dig_P3 = self._device.readS16LE(BME280_REGISTER_DIG_P3)
self.dig_P4 = self._device.readS16LE(BME280_REGISTER_DIG_P4)
self.dig_P5 = self._device.readS16LE(BME280_REGISTER_DIG_P5)
self.dig_P6 = self._device.readS16LE(BME280_REGISTER_DIG_P6)
self.dig_P7 = self._device.readS16LE(BME280_REGISTER_DIG_P7)
self.dig_P8 = self._device.readS16LE(BME280_REGISTER_DIG_P8)
self.dig_P9 = self._device.readS16LE(BME280_REGISTER_DIG_P9)
self.dig_H1 = self._device.readU8(BME280_REGISTER_DIG_H1)
self.dig_H2 = self._device.readS16LE(BME280_REGISTER_DIG_H2)
self.dig_H3 = self._device.readU8(BME280_REGISTER_DIG_H3)
self.dig_H6 = self._device.readS8(BME280_REGISTER_DIG_H7)
h4 = self._device.readS8(BME280_REGISTER_DIG_H4)
h4 = (h4 << 24) >> 20
self.dig_H4 = h4 | (self._device.readU8(BME280_REGISTER_DIG_H5) & 0x0F)
h5 = self._device.readS8(BME280_REGISTER_DIG_H6)
h5 = (h5 << 24) >> 20
self.dig_H5 = h5 | (
self._device.readU8(BME280_REGISTER_DIG_H5) >> 4 & 0x0F)
def read_raw_temp(self):
"""Reads the raw (uncompensated) temperature from the sensor."""
meas = self._mode
self._device.write8(BME280_REGISTER_CONTROL_HUM, meas)
meas = self._mode << 5 | self._mode << 2 | 1
self._device.write8(BME280_REGISTER_CONTROL, meas)
sleep_time = 1250 + 2300 * (1 << self._mode)
sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
time.sleep_us(sleep_time) # Wait the required time
msb = self._device.readU8(BME280_REGISTER_TEMP_DATA)
lsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 1)
xlsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 2)
raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
return raw
def read_raw_pressure(self):
"""Reads the raw (uncompensated) pressure level from the sensor."""
"""Assumes that the temperature has already been read """
"""i.e. that enough delay has been provided"""
msb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA)
lsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 1)
xlsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 2)
raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
return raw
def read_raw_humidity(self):
"""Assumes that the temperature has already been read """
"""i.e. that enough delay has been provided"""
msb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA)
lsb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA + 1)
raw = (msb << 8) | lsb
return raw
def read_temperature(self):
"""Get the compensated temperature in 0.01 of a degree celsius."""
adc = self.read_raw_temp()
var1 = ((adc >> 3) - (self.dig_T1 << 1)) * (self.dig_T2 >> 11)
var2 = ((
(((adc >> 4) - self.dig_T1) * ((adc >> 4) - self.dig_T1)) >> 12) *
self.dig_T3) >> 14
self.t_fine = var1 + var2
return (self.t_fine * 5 + 128) >> 8
def read_pressure(self):
"""Gets the compensated pressure in Pascals."""
adc = self.read_raw_pressure()
var1 = self.t_fine - 128000
var2 = var1 * var1 * self.dig_P6
var2 = var2 + ((var1 * self.dig_P5) << 17)
var2 = var2 + (self.dig_P4 << 35)
var1 = (((var1 * var1 * self.dig_P3) >> 8) +
((var1 * self.dig_P2) >> 12))
var1 = (((1 << 47) + var1) * self.dig_P1) >> 33
if var1 == 0:
return 0
p = 1048576 - adc
p = (((p << 31) - var2) * 3125) // var1
var1 = (self.dig_P9 * (p >> 13) * (p >> 13)) >> 25
var2 = (self.dig_P8 * p) >> 19
return ((p + var1 + var2) >> 8) + (self.dig_P7 << 4)
def read_humidity(self):
adc = self.read_raw_humidity()
# print 'Raw humidity = {0:d}'.format (adc)
h = self.t_fine - 76800
h = (((((adc << 14) - (self.dig_H4 << 20) - (self.dig_H5 * h)) +
16384) >> 15) * (((((((h * self.dig_H6) >> 10) * (((h *
self.dig_H3) >> 11) + 32768)) >> 10) + 2097152) *
self.dig_H2 + 8192) >> 14))
h = h - (((((h >> 15) * (h >> 15)) >> 7) * self.dig_H1) >> 4)
h = 0 if h < 0 else h
h = 419430400 if h > 419430400 else h
return h >> 12
@property
def temperature(self):
"Return the temperature in degrees."
t = self.read_temperature()
ti = t // 100
td = t - ti * 100
return float("{}.{:02d}".format(ti, td))
@property
def pressure(self):
"Return the temperature in hPa."
p = self.read_pressure() // 256
pi = p // 100
pd = p - pi * 100
return float("{}.{:02d}".format(pi, pd))
@property
def humidity(self):
"Return the humidity in percent."
h = self.read_humidity()
hi = h // 1024
hd = h * 100 // 1024 - hi * 100
return float("{}.{:02d}".format(hi, hd))
import machine, time
from machine import Pin
__version__ = '0.2.0'
__author__ = 'Roberto Sánchez'
__license__ = "Apache License 2.0. https://www.apache.org/licenses/LICENSE-2.0"
class HCSR04:
"""
Driver to use the untrasonic sensor HC-SR04.
The sensor range is between 2cm and 4m.
The timeouts received listening to echo pin are converted to OSError('Out of range')
"""
# echo_timeout_us is based in chip range limit (400cm)
def __init__(self, trigger_pin, echo_pin, echo_timeout_us=500*2*30):
"""
trigger_pin: Output pin to send pulses
echo_pin: Readonly pin to measure the distance. The pin should be protected with 1k resistor
echo_timeout_us: Timeout in microseconds to listen to echo pin.
By default is based in sensor limit range (4m)
"""
self.echo_timeout_us = echo_timeout_us
# Init trigger pin (out)
self.trigger = Pin(trigger_pin, mode=Pin.OUT, pull=None)
self.trigger.value(0)
# Init echo pin (in)
self.echo = Pin(echo_pin, mode=Pin.IN, pull=None)
def _send_pulse_and_wait(self):
"""
Send the pulse to trigger and listen on echo pin.
We use the method `machine.time_pulse_us()` to get the microseconds until the echo is received.
"""
self.trigger.value(0) # Stabilize the sensor
time.sleep_us(5)
self.trigger.value(1)
# Send a 10us pulse.
time.sleep_us(10)
self.trigger.value(0)
try:
pulse_time = machine.time_pulse_us(self.echo, 1, self.echo_timeout_us)
return pulse_time
except OSError as ex:
if ex.args[0] == 110: # 110 = ETIMEDOUT
raise OSError('Out of range')
raise ex
def distance_mm(self):
"""
Get the distance in milimeters without floating point operations.
"""
pulse_time = self._send_pulse_and_wait()
# To calculate the distance we get the pulse_time and divide it by 2
# (the pulse walk the distance twice) and by 29.1 becasue
# the sound speed on air (343.2 m/s), that It's equivalent to
# 0.34320 mm/us that is 1mm each 2.91us
# pulse_time // 2 // 2.91 -> pulse_time // 5.82 -> pulse_time * 100 // 582
mm = pulse_time * 100 // 582
return mm
def distance_cm(self):
"""
Get the distance in centimeters with floating point operations.
It returns a float
"""
pulse_time = self._send_pulse_and_wait()
# To calculate the distance we get the pulse_time and divide it by 2
# (the pulse walk the distance twice) and by 29.1 becasue
# the sound speed on air (343.2 m/s), that It's equivalent to
# 0.034320 cm/us that is 1cm each 29.1us
cms = (pulse_time / 2) / 29.1
return cms
import hcsr04
from machine import Pin, I2C
import time
import bme280
from umqtt.robust import MQTTClient
import ujson
import network
def do_connect():
sta_if = network.WLAN(network.STA_IF)
sta_if.active(False)
if not sta_if.isconnected():
print('connecting to network...')
sta_if.active(True)
sta_if.connect(b'SSID', 'PASS')
while not sta_if.isconnected():
pass
print('network config:', sta_if.ifconfig())
do_connect()
weatherPin = I2C(scl=Pin(23), sda=Pin(22), freq=10000)
ultrasonicPin = hcsr04.HCSR04(trigger_pin=5, echo_pin=18, echo_timeout_us=1000000)
rainPin = Pin(19, Pin.IN)
client = MQTTClient('meteokrmitko_1', '192.168.100.5', 1883, 'meteokrmitko', 'ToQ7F4He9y')
client.connect()
def formatFood(food):
oldMin = 0
oldMax = 14.5
if food > oldMax:
food = oldMax
elif food < oldMin:
food = oldMin
newMin = 0
newMax = 1
oldRange = oldMax - oldMin
newRange = newMax - newMin
return abs(((food - oldMin) * newRange / oldRange) - newMax)
while True:
bme = bme280.BME280(i2c=weatherPin)
res = {}
res["name"] = 'Poprad'
res["temperature"] = bme.temperature
res["humidity"] = bme.humidity
res["pressure"] = bme.pressure
res["rainsnow"] = not rainPin.value()
res["food"] = formatFood(ultrasonicPin.distance_cm())
client.publish('meteokrmitko/iot', ujson.dumps(res))
time.sleep_ms(5000)
This diff is collapsed.
[{"id":"587760f6.9754e","type":"tab","label":"ultrakrmitko","disabled":false,"info":""},{"id":"4a360a0b.7a1004","type":"http request","z":"587760f6.9754e","name":"Spišská Belá","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=49.188654&lon=20.434503&units=metric&appid=17c1a61a61eb92b17c981af1306981d2","tls":"","persist":false,"proxy":"","authType":"","x":470,"y":120,"wires":[["8448b570.601fb8"]]},{"id":"8448b570.601fb8","type":"json","z":"587760f6.9754e","name":"","property":"payload","action":"","pretty":false,"x":830,"y":260,"wires":[["1e687bf4.3ee1a4"]]},{"id":"c1a80cf5.6b782","type":"mqtt out","z":"587760f6.9754e","name":"meteokrmitko/iot","topic":"meteokrmitko/iot","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"1c4b921.705786e","x":1200,"y":260,"wires":[]},{"id":"b156e7d9.5f1218","type":"inject","z":"587760f6.9754e","name":"Ultraposielac","props":[{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":130,"y":260,"wires":[["4a360a0b.7a1004","5092240.a6ab5dc","ac22eec1.83ad8","c18a14d1.818f58","5c8ae730.b6dc68","1aa50310.30d7ed","c8a1a11d.542ac","34a5afce.0e242","e8bcb029.88c53"]]},{"id":"1e687bf4.3ee1a4","type":"function","z":"587760f6.9754e","name":"","func":"let isBird = Math.floor(Math.random() * 50) == 10;\nlet globalVariableName = msg.payload.name.replace(\" \", \"\");\nvar availableFood = global.get(globalVariableName);\n\nif (isBird && availableFood >= 0.05) {\n availableFood -= 0.05;\n global.set(globalVariableName, availableFood);\n}\n\nlet data = {};\ndata.topic = msg.topic;\ndata.payload = {\n \"name\": msg.payload.name,\n \"temperature\": msg.payload.main.temp,\n \"humidity\": msg.payload.main.humidity,\n \"pressure\": msg.payload.main.pressure,\n \"rainsnow\": (msg.payload.rain || msg.payload.snow) ? true : false,\n \"food\": availableFood\n};\n\nreturn data;","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is deployed.\n\nglobal.set(\n [\"Košice\",\n \"Prešov\",\n \"Poprad\",\n \"Lipany\",\n \"Svidník\",\n \"StaráĽubovňa\",\n \"SpišskáBelá\",\n \"Nitra\",\n \"Vrbica\",\n \"Bardejov\"],\n [1,\n 1,\n 1,\n 1,\n 1,\n 1,\n 1,\n 1,\n 1,\n 1]);","finalize":"","libs":[],"x":1000,"y":260,"wires":[["c1a80cf5.6b782"]]},{"id":"ac22eec1.83ad8","type":"http request","z":"587760f6.9754e","name":"Košice","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=48.710924&lon=21.257726&units=metric&appid=17c1a61a61eb92b17c981af1306981d2\t","tls":"","persist":false,"proxy":"","authType":"","x":450,"y":200,"wires":[["8448b570.601fb8"]]},{"id":"5092240.a6ab5dc","type":"http request","z":"587760f6.9754e","name":"Nitra","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=48.294898&lon=18.070108&units=metric&appid=17c1a61a61eb92b17c981af1306981d2","tls":"","persist":false,"proxy":"","authType":"","x":450,"y":160,"wires":[["8448b570.601fb8"]]},{"id":"c18a14d1.818f58","type":"http request","z":"587760f6.9754e","name":"Prešov","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=48.998081&lon=21.227857&units=metric&appid=17c1a61a61eb92b17c981af1306981d2","tls":"","persist":false,"proxy":"","authType":"","x":460,"y":240,"wires":[["8448b570.601fb8"]]},{"id":"5c8ae730.b6dc68","type":"http request","z":"587760f6.9754e","name":"Svidnik","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=49.300961&lon=21.566639&units=metric&appid=17c1a61a61eb92b17c981af1306981d2","tls":"","persist":false,"proxy":"","authType":"","x":460,"y":280,"wires":[["8448b570.601fb8"]]},{"id":"1aa50310.30d7ed","type":"http request","z":"587760f6.9754e","name":"Bardejov","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=49.312682&lon=21.266119&units=metric&appid=17c1a61a61eb92b17c981af1306981d2","tls":"","persist":false,"proxy":"","authType":"","x":460,"y":320,"wires":[["8448b570.601fb8"]]},{"id":"c8a1a11d.542ac","type":"http request","z":"587760f6.9754e","name":"Lipany","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=49.247493&lon=20.918895&units=metric&appid=17c1a61a61eb92b17c981af1306981d2\t","tls":"","persist":false,"proxy":"","authType":"","x":450,"y":360,"wires":[["8448b570.601fb8"]]},{"id":"34a5afce.0e242","type":"http request","z":"587760f6.9754e","name":"Stará Ľubovňa","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=49.311057&lon=20.691009&units=metric&appid=17c1a61a61eb92b17c981af1306981d2","tls":"","persist":false,"proxy":"","authType":"","x":480,"y":400,"wires":[["8448b570.601fb8"]]},{"id":"e8bcb029.88c53","type":"http request","z":"587760f6.9754e","name":"Vrbica","method":"GET","ret":"txt","paytoqs":"ignore","url":"http://api.openweathermap.org/data/2.5/weather?lat=49.078033&lon=19.611038&units=metric&appid=17c1a61a61eb92b17c981af1306981d2","tls":"","persist":false,"proxy":"","authType":"","x":450,"y":440,"wires":[["8448b570.601fb8"]]},{"id":"223880a.d8b578","type":"mqtt in","z":"587760f6.9754e","name":"meteokrmitko/iot","topic":"meteokrmitko/iot","qos":"2","datatype":"auto","broker":"1c4b921.705786e","nl":false,"rap":false,"x":180,"y":640,"wires":[["a7b30a01.054e88"]]},{"id":"a7b30a01.054e88","type":"json","z":"587760f6.9754e","name":"","property":"payload","action":"","pretty":false,"x":370,"y":640,"wires":[["39d76d7c.98b4b2","8f793aa3.185838"]]},{"id":"39d76d7c.98b4b2","type":"influxdb out","z":"587760f6.9754e","influxdb":"1fd91944.2ff3e7","name":"","measurement":"feederDb","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":610,"y":640,"wires":[]},{"id":"8f793aa3.185838","type":"debug","z":"587760f6.9754e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":550,"y":600,"wires":[]},{"id":"1c4b921.705786e","type":"mqtt-broker","name":"","broker":"192.168.100.5","port":"1883","clientid":"","usetls":false,"compatmode":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"sessionExpiry":""},{"id":"1fd91944.2ff3e7","type":"influxdb","hostname":"influxdb","port":"8086","protocol":"http","database":"db","name":"","usetls":false,"tls":"","influxdbVersion":"1.x","url":"http://localhost:8086","rejectUnauthorized":true}]
\ No newline at end of file