github upload

This commit is contained in:
2020-05-29 15:05:46 +02:00
commit f06e658bf0
11 changed files with 1359 additions and 0 deletions

BIN
WiFi.mpy Normal file

Binary file not shown.

105
WiFi.py Normal file
View File

@@ -0,0 +1,105 @@
import network
import utime
import machine
_DEBUG = False
class NetSet(object):
def __init__(self, wifi_type):
self.sta = network.WLAN(network.STA_IF)
self.ap = network.WLAN(network.AP_IF)
if wifi_type == 'infra':
if _DEBUG:
print("Disabling AP")
self.ap.active(False)
if _DEBUG:
print("Activating INFRA")
self.sta.active(True)
self.sta.isconnected() # False, it should be # Comments by Yoda
self._SSID = None
self._PASS = None
self._TIMEOUT = None
elif wifi_type == 'ap':
if _DEBUG:
print("Disabling INFRA")
self.ap.active(True)
if _DEBUG:
print("Activating AP")
self.sta.active(False)
self.sta.isconnected() # False, it should be # Comments by Yoda
self._SSID = None
self._PASS = None
self._TIMEOUT = None
def connectInfraGo(self, _timeout):
if _DEBUG:
print("Connecting to infra")
self.sta.connect(self._SSID, self._PASS)
if _DEBUG:
print("Let's wait for the network to come up")
while not (self.sta.isconnected()):
if _timeout > 0:
print("Trying... {} more times".format(_timeout))
utime.sleep_ms(1001)
_timeout -= 1
else:
print("Out of retrys")
return False
network_config = self.sta.ifconfig()
return network_config
def connectInfra(self, _SSID, _PASS, _TIMEOUT):
self._SSID = _SSID
self._PASS = _PASS
try:
net_conf_result = self.connectInfraGo(_TIMEOUT)
utime.sleep_ms(100)
if net_conf_result:
return {
'ip': net_conf_result[0],
'mask': net_conf_result[1],
'gw': net_conf_result[2],
'dns': net_conf_result[3] }
else:
return False
except Exception as e:
print("ERROR: Network configuration failed with: {}".format(e))
return False
def connectAp(self):
# TBI
pass
def readNetworkConfig(self):
self.config_dict = {}
try:
with open('inet.conf', 'r') as conf_handler:
for item in conf_handler.readlines():
option = item.split("=")[0].strip()
if len(item.split("=")) == 2 and '#' not in option:
value = item.split("=")[1].strip()
self.config_dict.update({option: value})
else:
if _DEBUG:
if '#' in option:
print(b"COMMENT in config")
else:
print(b"WARNING: Fucked up option, make it better")
except Exception as e:
if _DEBUG:
print("WARNING: Errors in INFRA config, still going for AP")
return False
if _DEBUG:
print("CONFIG DICT: {}".format(self.config_dict))
self._SSID = self.config_dict['_SSID']
self._PASS = self.config_dict['_PASS']
self._TIMEOUT = int(self.config_dict['_TIMEOUT'])
self._INFLUX_HOST = self.config_dict['_INFLUX_HOST']
self._INFLUX_PORT = self.config_dict['_INFLUX_PORT']
self._INFLUX_USER = self.config_dict['_INFLUX_USER']
self._INFLUX_PASS = self.config_dict['_INFLUX_PASS']
self._INF_DB_WEATHER = self.config_dict['_INF_DB_WEATHER']
self._INF_DB_STATUS = self.config_dict['_INF_DB_STATUS']
self._INF_DB_RAW = self.config_dict['_INF_DB_RAW']

3
boot.py Normal file
View File

@@ -0,0 +1,3 @@
# This file is executed on every boot (including wake-boot from deepsleep)
import gc
gc.collect()

BIN
cc1101_davis.mpy Normal file

Binary file not shown.

390
cc1101_davis.py Normal file
View File

@@ -0,0 +1,390 @@
import utime
import gc
import machine
ss = machine.Pin(15,machine.Pin.OUT) # Chip select / HCS
so = machine.Pin(12) # HMISO
si = machine.Pin(13) # HMOSI
sck = machine.Pin(14) # HSCLK
interrupt = machine.Pin(2) # Interrupt for packet available
gc.collect()
class CC1101(object):
def __init__(self):
self.debug = 1
self.hspi = machine.SPI(1, baudrate=600000, polarity=0, phase=0)
self.PA_TABLE = [0xC0, 0xC0, 0xC0, 0xC0,
0xC0, 0xC0, 0xC0, 0xC0]
self.FREQ_2 = [0x21, 0x21, 0x21, 0x21, 0x21]
self.FREQ_1 = [0x62, 0x65, 0x67, 0x64, 0x66]
self.FREQ_0 = [0xE2, 0x40, 0x9D, 0x11, 0x6F]
self.CRC_TABLE = [
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0]
self.BUFFER_SIZE = 16
self.DAVIS_PACKET_LENGTH = 10
self.rxBuffer = []
self.rxBufferIndex = 0
self.rxBufferLength = 0
self.hopIndex = 0
self.freqComp = [0, 0, 0, 0, 0]
# CC1101 Transfer Types.
self.WRITE_BURST = 0x40
self.READ_SINGLE = 0x80
self.READ_BURST = 0xC0
# Davis Register Configuration Settings.
self.DAVIS_IOCFG2 = 0x2E # GDO2 Output Pin Configuration
self.DAVIS_IOCFG1 = 0x2E # GDO1 Output Pin Configuration
self.DAVIS_IOCFG0 = 0x01 # GDO0 Output Pin Configuration
self.DAVIS_FIFOTHR = 0x42 # RX FIFO and TX FIFO Thresholds
self.DAVIS_SYNC1 = 0xCB # Synchronization word, high byte
self.DAVIS_SYNC0 = 0x89 # Synchronization word, low byte
self.DAVIS_PKTLEN = 0x0A # Packet Length
self.DAVIS_PKTCTRL1 = 0xC4 # Packet Automation Control
self.DAVIS_PKTCTRL0 = 0x00 # Packet Automation Control
self.DAVIS_ADDR = 0x00 # Device Address
self.DAVIS_CHANNR = 0x00 # Channel Number
self.DAVIS_FSCTRL1 = 0x06 # Frequency Synthesizer Control
self.DAVIS_FSCTRL0 = 0xF0 # Frequency Synthesizer Control
self.DAVIS_FREQ2 = 0x23 # Frequency Control Word, High Byte
self.DAVIS_FREQ1 = 0x0D # Frequency Control Word, Middle Byte
self.DAVIS_FREQ0 = 0x97 # Frequency Control Word, Low Byte
self.DAVIS_MDMCFG4 = 0xC9 # Modem Configuration
self.DAVIS_MDMCFG3 = 0x83 # Modem Configuration
self.DAVIS_MDMCFG2 = 0x12 # Modem Configuration
self.DAVIS_MDMCFG1 = 0x21 # Modem Configuration
self.DAVIS_MDMCFG0 = 0xF9 # Modem Configuration
self.DAVIS_DEVIATN = 0x24 # Modem Deviation Setting
self.DAVIS_MCSM2 = 0x07 # Main Radio Control State Machine Configuration
self.DAVIS_MCSM1 = 0x00 # Main Radio Control State Machine Configuration
self.DAVIS_MCSM0 = 0x18 # Main Radio Control State Machine Configuration
self.DAVIS_FOCCFG = 0x16 # Frequency Offset Compensation Configuration
self.DAVIS_BSCFG = 0x6C # Bit Synchronization Configuration
self.DAVIS_AGCCTRL2 = 0x43 # AGC Control
self.DAVIS_AGCCTRL1 = 0x40 # AGC Control
self.DAVIS_AGCCTRL0 = 0x91 # AGC Control
self.DAVIS_WOREVT1 = 0x87 # High Byte Event0 Timeout
self.DAVIS_WOREVT0 = 0x6B # Low Byte Event0 Timeout
self.DAVIS_WORCTRL = 0xF8 # Wake On Radio Control
self.DAVIS_FREND1 = 0x56 # Front End RX Configuration
self.DAVIS_FREND0 = 0x10 # Front End TX Configuration
self.DAVIS_FSCAL3 = 0xEF # Frequency Synthesizer Calibration
self.DAVIS_FSCAL2 = 0x2B # Frequency Synthesizer Calibration
self.DAVIS_FSCAL1 = 0x2F # Frequency Synthesizer Calibration
self.DAVIS_FSCAL0 = 0x1F # Frequency Synthesizer Calibration
self.DAVIS_RCCTRL1 = 0x00 # RC Oscillator Configuration
self.DAVIS_RCCTRL0 = 0x00 # RC Oscillator Configuration
self.DAVIS_FSTEST = 0x59 # Frequency Synthesizer Calibration Control
self.DAVIS_PTEST = 0x7F # Production Test
self.DAVIS_AGCTEST = 0x3F # AGC Test
self.DAVIS_TEST2 = 0x81 # Various Test Settings
self.DAVIS_TEST1 = 0x35 # Various Test Settings
self.DAVIS_TEST0 = 0x09 # Various Test Settings
self.CC1101_IOCFG2 = 0x00 # GDO2 Output Pin Configuration
self.CC1101_IOCFG1 = 0x01 # GDO1 Output Pin Configuration
self.CC1101_IOCFG0 = 0x02 # GDO0 Output Pin Configuration
self.CC1101_FIFOTHR = 0x03 # RX FIFO and TX FIFO Thresholds
self.CC1101_SYNC1 = 0x04 # Sync Word, High Byte
self.CC1101_SYNC0 = 0x05 # Sync Word, Low Byte
self.CC1101_PKTLEN = 0x06 # Packet Length
self.CC1101_PKTCTRL1 = 0x07 # Packet Automation Control
self.CC1101_PKTCTRL0 = 0x08 # Packet Automation Control
self.CC1101_ADDR = 0x09 # Device Address
self.CC1101_CHANNR = 0x0A # Channel Number
self.CC1101_FSCTRL1 = 0x0B # Frequency Synthesizer Control
self.CC1101_FSCTRL0 = 0x0C # Frequency Synthesizer Control
self.CC1101_FREQ2 = 0x0D # Frequency Control Word, High Byte
self.CC1101_FREQ1 = 0x0E # Frequency Control Word, Middle Byte
self.CC1101_FREQ0 = 0x0F # Frequency Control Word, Low Byte
self.CC1101_MDMCFG4 = 0x10 # Modem Configuration
self.CC1101_MDMCFG3 = 0x11 # Modem Configuration
self.CC1101_MDMCFG2 = 0x12 # Modem Configuration
self.CC1101_MDMCFG1 = 0x13 # Modem Configuration
self.CC1101_MDMCFG0 = 0x14 # Modem Configuration
self.CC1101_DEVIATN = 0x15 # Modem Deviation Setting
self.CC1101_MCSM2 = 0x16 # Main Radio Control State Machine Configuration
self.CC1101_MCSM1 = 0x17 # Main Radio Control State Machine Configuration
self.CC1101_MCSM0 = 0x18 # Main Radio Control State Machine Configuration
self.CC1101_FOCCFG = 0x19 # Frequency Offset Compensation Configuration
self.CC1101_BSCFG = 0x1A # Bit Synchronization Configuration
self.CC1101_AGCCTRL2 = 0x1B # AGC Control
self.CC1101_AGCCTRL1 = 0x1C # AGC Control
self.CC1101_AGCCTRL0 = 0x1D # AGC Control
self.CC1101_WOREVT1 = 0x1E # High Byte Event0 Timeout
self.CC1101_WOREVT0 = 0x1F # Low Byte Event0 Timeout
self.CC1101_WORCTRL = 0x20 # Wake On Radio Control
self.CC1101_FREND1 = 0x21 # Front End RX Configuration
self.CC1101_FREND0 = 0x22 # Front End TX Configuration
self.CC1101_FSCAL3 = 0x23 # Frequency Synthesizer Calibration
self.CC1101_FSCAL2 = 0x24 # Frequency Synthesizer Calibration
self.CC1101_FSCAL1 = 0x25 # Frequency Synthesizer Calibration
self.CC1101_FSCAL0 = 0x26 # Frequency Synthesizer Calibration
self.CC1101_RCCTRL1 = 0x27 # RC Oscillator Configuration
self.CC1101_RCCTRL0 = 0x28 # RC Oscillator Configuration
self.CC1101_FSTEST = 0x29 # Frequency Synthesizer Calibration Control
self.CC1101_PTEST = 0x2A # Production Test
self.CC1101_AGCTEST = 0x2B # AGC Test
self.CC1101_TEST2 = 0x2C # Various Test Settings
self.CC1101_TEST1 = 0x2D # Various Test Settings
self.CC1101_TEST0 = 0x2E # Various Test Settings
# CC1101 Status Registers.
self.CC1101_PARTNUM = 0x30 # Chip ID
self.CC1101_VERSION = 0x31 # Chip ID
self.CC1101_FREQEST = 0x32 # Frequency Offset Estimate from Demodulator
self.CC1101_LQI = 0x33 # Demodulator Estimate for Link Quality
self.CC1101_RSSI = 0x34 # Received Signal Strength Indication
self.CC1101_MARCSTATE = 0x35 # Main Radio Control State Machine State
self.CC1101_WORTIME1 = 0x36 # High Byte of WOR Time
self.CC1101_WORTIME0 = 0x37 # Low Byte of WOR Time
self.CC1101_PKTSTATUS = 0x38 # Current GDOx Status and Packet Status
self.CC1101_VCO_VC_DAC = 0x39 # Current Setting from PLL Calibration Module
self.CC1101_TXBYTES = 0x3A # Underflow and Number of Bytes
self.CC1101_RXBYTES = 0x3B # Overflow and Number of Bytes
self.CC1101_RCCTRL1_STATUS = 0x3C # Last RC Oscillator Calibration Result
self.CC1101_RCCTRL0_STATUS = 0x3D # Last RC Oscillator Calibration Result
# CC1101 PA Table, TX FIFO and RX FIFO.
self.CC1101_PATABLE = 0x3E # PA TABLE address
self.CC1101_TXFIFO = 0x3F # TX FIFO address
self.CC1101_RXFIFO = 0x3F # RX FIFO address
# CC1101 Command Strobes.
self.CC1101_SRES = 0x30 # Reset CC1101 chip
self.CC1101_SFSTXON = 0x31 # Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL = 1). If in RX (with CCA):
# Go to a wait state where only the synthesizer is running (for quick RX / TX turnaround).
self.CC1101_SXOFF = 0x32 # Turn off crystal oscillator
self.CC1101_SCAL = 0x33 # Calibrate frequency synthesizer and turn it off. SCAL can be strobed from IDLE mode without
# setting manual calibration mode (MCSM0.FS_AUTOCAL = 0)
self.CC1101_SRX = 0x34 # Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL = 1
self.CC1101_STX = 0x35 # In IDLE state: Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL = 1.
# If in RX state and CCA is enabled: Only go to TX if channel is clear
self.CC1101_SIDLE = 0x36 # Exit RX / TX, turn off frequency synthesizer and exit Wake-On-Radio mode if applicable
self.CC1101_SWOR = 0x38 # Start automatic RX polling sequence (Wake-on-Radio) if WORCTRL.RC_PD = 0
self.CC1101_SPWD = 0x39 # Enter power down mode when CSn goes high
self.CC1101_SFRX = 0x3A # Flush the RX FIFO buffer. Only issue SFRX in IDLE or RXFIFO_OVERFLOW states
self.CC1101_SFTX = 0x3B # Flush the TX FIFO buffer. Only issue SFTX in IDLE or TXFIFO_UNDERFLOW states
self.CC1101_SWORRST = 0x3C # Reset real time clock to Event1 value
self.CC1101_SNOP = 0x3D # No operation. May be used to get access to the chip status byte
# CC1101 Transfer Types.
self.WRITE_BURST = 0x40
self.READ_SINGLE = 0x80
self.READ_BURST = 0xC0
# CC1101 Returned Status Bytes.
self.CC1101_STATE_IDLE = 0x01
self.CC1101_STATE_ENDCAL = 0x0C
self.CC1101_STATE_RX = 0x0D
self.CC1101_STATE_RXFIFO_ERROR = 0x11
self.CC1101_STATE_TX = 0x13
self.CC1101_STATE_TX_END = 0x14
self.CC1101_STATE_TXFIFO_ERROR = 0x16
self.reset()
self.setRegisters()
for i in range(0, 5):
self.freqComp[i] = self.DAVIS_FSCTRL0
def readRegister(self, regAddr):
addr = regAddr | self.READ_SINGLE
ss.off()
read_addr = bytes([addr])
self.hspi.write(read_addr)
val = self.hspi.read(1, 0x00)
ss.on()
return int(val[0])
def writeRegister(self, regAddr, value):
ss.off()
self.hspi.write(bytes([regAddr]))
self.hspi.write(bytes([value]))
ss.on()
def writeBurst(self, regAddr, wr_buffer):
addr = regAddr | self.WRITE_BURST
ss.off()
self.hspi.write(bytes([addr]))
for contents in wr_buffer:
self.hspi.write(bytes([contents]))
ss.on()
def readBurst(self, regAddr, size):
addr = regAddr | self.READ_BURST
ss.off()
self.hspi.write(bytes([addr]))
rd_buffer = []
for i in range(0, size):
rd_result = self.hspi.read(1, 0x00)
rd_buffer.append(hex(rd_result[0]))
ss.on()
return rd_buffer
def cmdStrobe(self, command):
ss.off()
self.hspi.write(bytes([command]))
ss.on()
def readStatus(self, regAddr):
addr = regAddr | self.READ_BURST
ss.off()
self.hspi.write(bytes([addr]))
value = self.hspi.read(1, 0x00)
ss.on()
return int(value[0])
def reset(self):
ss.off()
utime.sleep_ms(1)
ss.on()
utime.sleep_ms(1)
ss.off()
while so.value():
pass
self.hspi.write(bytes([self.CC1101_SRES]))
while so.value():
pass
ss.on()
def sidle(self):
self.cmdStrobe(self.CC1101_SIDLE)
while self.readStatus(self.CC1101_MARCSTATE) != 0x01:
utime.sleep_us(100)
self.cmdStrobe(self.CC1101_SFTX)
self.cmdStrobe(self.CC1101_SFRX)
utime.sleep_us(100)
def setRegisters(self):
self.writeRegister(self.CC1101_IOCFG2, self.DAVIS_IOCFG2)
self.writeRegister(self.CC1101_IOCFG1, self.DAVIS_IOCFG1)
self.writeRegister(self.CC1101_IOCFG0, self.DAVIS_IOCFG0)
self.writeRegister(self.CC1101_FIFOTHR, self.DAVIS_FIFOTHR)
self.writeRegister(self.CC1101_SYNC1, self.DAVIS_SYNC1)
self.writeRegister(self.CC1101_SYNC0, self.DAVIS_SYNC0)
self.writeRegister(self.CC1101_PKTLEN, self.DAVIS_PKTLEN)
self.writeRegister(self.CC1101_PKTCTRL1, self.DAVIS_PKTCTRL1)
self.writeRegister(self.CC1101_PKTCTRL0, self.DAVIS_PKTCTRL0)
self.writeRegister(self.CC1101_ADDR, self.DAVIS_ADDR)
self.writeRegister(self.CC1101_CHANNR, self.DAVIS_CHANNR)
self.writeRegister(self.CC1101_FSCTRL1, self.DAVIS_FSCTRL1)
self.writeRegister(self.CC1101_FSCTRL0, self.DAVIS_FSCTRL0)
self.writeRegister(self.CC1101_FREQ2, self.DAVIS_FREQ2)
self.writeRegister(self.CC1101_FREQ1, self.DAVIS_FREQ1)
self.writeRegister(self.CC1101_FREQ0, self.DAVIS_FREQ0)
self.writeRegister(self.CC1101_MDMCFG4, self.DAVIS_MDMCFG4)
self.writeRegister(self.CC1101_MDMCFG3, self.DAVIS_MDMCFG3)
self.writeRegister(self.CC1101_MDMCFG2, self.DAVIS_MDMCFG2)
self.writeRegister(self.CC1101_MDMCFG1, self.DAVIS_MDMCFG1)
self.writeRegister(self.CC1101_MDMCFG0, self.DAVIS_MDMCFG0)
self.writeRegister(self.CC1101_DEVIATN, self.DAVIS_DEVIATN)
self.writeRegister(self.CC1101_MCSM2, self.DAVIS_MCSM2)
self.writeRegister(self.CC1101_MCSM1, self.DAVIS_MCSM1)
self.writeRegister(self.CC1101_MCSM0, self.DAVIS_MCSM0)
self.writeRegister(self.CC1101_FOCCFG, self.DAVIS_FOCCFG)
self.writeRegister(self.CC1101_BSCFG, self.DAVIS_BSCFG)
self.writeRegister(self.CC1101_AGCCTRL2, self.DAVIS_AGCCTRL2)
self.writeRegister(self.CC1101_AGCCTRL1, self.DAVIS_AGCCTRL1)
self.writeRegister(self.CC1101_AGCCTRL0, self.DAVIS_AGCCTRL0)
self.writeRegister(self.CC1101_WOREVT1, self.DAVIS_WOREVT1)
self.writeRegister(self.CC1101_WOREVT0, self.DAVIS_WOREVT0)
self.writeRegister(self.CC1101_WORCTRL, self.DAVIS_WORCTRL)
self.writeRegister(self.CC1101_FREND1, self.DAVIS_FREND1)
self.writeRegister(self.CC1101_FREND0, self.DAVIS_FREND0)
self.writeRegister(self.CC1101_FSCAL3, self.DAVIS_FSCAL3)
self.writeRegister(self.CC1101_FSCAL2, self.DAVIS_FSCAL2)
self.writeRegister(self.CC1101_FSCAL1, self.DAVIS_FSCAL1)
self.writeRegister(self.CC1101_FSCAL0, self.DAVIS_FSCAL0)
self.writeRegister(self.CC1101_RCCTRL1, self.DAVIS_RCCTRL1)
self.writeRegister(self.CC1101_RCCTRL0, self.DAVIS_RCCTRL0)
self.writeRegister(self.CC1101_FSTEST, self.DAVIS_FSTEST)
self.writeRegister(self.CC1101_PTEST, self.DAVIS_PTEST)
self.writeRegister(self.CC1101_AGCTEST, self.DAVIS_AGCTEST)
self.writeRegister(self.CC1101_TEST2, self.DAVIS_TEST2)
self.writeRegister(self.CC1101_TEST1, self.DAVIS_TEST1)
self.writeRegister(self.CC1101_TEST0, self.DAVIS_TEST0)
self.writeBurst(self.CC1101_PATABLE, self.PA_TABLE)
self.setFrequency(self.hopIndex)
def flush(self):
self.sidle()
self.cmdStrobe(self.CC1101_SFRX) # Flush Rx FIFO
self.cmdStrobe(self.CC1101_SFTX) # Flush Tx FIFO
self.rxBuffer = [0x00] * self.BUFFER_SIZE
self.rxBufferLength = self.rxBufferIndex = 0
def rx(self):
self.cmdStrobe(self.CC1101_SRX)
while (self.readStatus(self.CC1101_MARCSTATE) & 0x1F) != self.CC1101_STATE_RX:
utime.sleep_us(900)
self.rxing = 1
self.writeRegister(self.CC1101_IOCFG0, self.DAVIS_IOCFG0)
def hop(self):
self.hopIndex += 1 # Increment the index
if (self.hopIndex > 4): # 5 EU frequencies
self.hopIndex = 0
self.writeRegister(self.CC1101_FSCTRL0, self.freqComp[self.hopIndex])
self.setFrequency(self.hopIndex) # Set the frequency.
def setFrequency(self, index):
self.sidle()
self.writeRegister(self.CC1101_FREQ2, self.FREQ_2[index])
self.writeRegister(self.CC1101_FREQ1, self.FREQ_1[index])
self.writeRegister(self.CC1101_FREQ0, self.FREQ_0[index])
self.flush()
def calcCrc(self, _buffer, length):
crc = 0x0000
buffer_index = 0
for i in range(length, 0, -1):
crc = (crc << 8) ^ self.CRC_TABLE[(crc >> 8) ^ (_buffer[buffer_index])]
buffer_index += 1
return crc
def readRssi(self):
rssi = self.readRegister(self.CC1101_RXFIFO)
if rssi >= 128:
return (rssi - 256)/2 - 74
elif rssi < 128:
return rssi/2 -74
else:
return False
def readLQI(self):
return self.readRegister(self.CC1101_RXFIFO) & 0x7F

BIN
davis_decode.mpy Normal file

Binary file not shown.

223
davis_decode.py Normal file
View File

@@ -0,0 +1,223 @@
import urequests
_DEBUG = False
def send_to_influx(host, port, db, user, password, davis_unit_id, wind, measurement, name, value, tags):
post = "http://{}:{}/write?db={}".format(host, port, db)
if _DEBUG:
print("SENDING TO: {}".format(post))
if measurement is False:
return (False, "ERROR measurement set False")
if measurement is None:
data = "wind,type=speed,davis_id={_davis_id} value={_speed}\n wind,type=direction,davis_id={_davis_id} value={_direction}".format(
_davis_id = davis_unit_id,
_speed=wind['speed'],
_direction=wind['direction'])
if _DEBUG:
print("SEND WIND only: {}")
else:
for tag in tags.keys():
measurement = "{},{}={}".format(measurement, tag, tags[tag])
data = "{_measure},davis_id={_davis_id} {_name}={_value}\n wind,type=speed,davis_id={_davis_id} value={_speed}\n wind,type=direction,davis_id={_davis_id} value={_direction}".format(
_measure=measurement,
_name=name,
_value=value,
_davis_id = davis_unit_id,
_speed=wind['speed'],
_direction=wind['direction'])
if _DEBUG:
print("POST_DATA: {}".format(data))
try:
return (True, urequests.post(post, data=data))
except Exception as e:
return (False, "ERROR sending data to influx: {}".format(e))
def reverseBits(data):
data = "{:08b}".format(data)
z = ""
for i in range(len(data),0,-1):
z = z + (data[i-1])
return int(z, 2)
class davisDecoder(object):
def __init__(self, weather_db, stat_db, raw_db):
__name__ = u'Davis value decoder class'
self.weather_influx_db = weather_db
self.stat_influx_db = stat_db
self.raw_influx_db = raw_db
def byte_split(self, data):
msb = data >> 4
lsb = data & 0b00001111
result = {"MSB": msb, "LSB": lsb}
return result
def davis_id(self, header):
self.davis_packet_id = 0
self.battery_low = 0
self.unit_id = 0
bin_header = self.byte_split(header)
self.unit_id = bin_header['LSB'] & 0b0111
self.battery_low = bin_header['LSB'] >> 3
self.davis_packet_id = bin_header['MSB']
result = {"davis_id": self.unit_id,
"packet_id": self.davis_packet_id,
"bat_low": self.battery_low}
return result
def decode_wind(self, databytes):
# wind speed in mph, i suppose. Let's convert it
wind_speed = round(float(databytes['windspeed'] * 1.60934), 1)
wind_direction_factor = round(float(360)/float(255), 1)
wind_direction = databytes['winddir']
wind_direction = float(wind_direction) * wind_direction_factor
result = {"speed": wind_speed, "direction": wind_direction}
return result
def decode_temp(self, temp):
temp_f = (float(temp)) / float(160) # in Fahrenheit
temp_c = round((temp_f - 32) * float(5)/float(9), 1)
result = {"celsius": temp_c, "fahrenheit": temp_f}
return result
def decode_humidity(self, hum):
pass
def supercap_decode(self, byte2, byte3):
cap = (byte2 << 2) + (byte3 >> 6)
result = float(cap / 100.00)
return result
def solarvolt_decode(self, byte2, byte3):
solar = (byte2 << 1) + (byte3 >> 7)
result = float(solar)
return result
def rain_decode(self, rain):
result = float(rain & 0x7F)
return result
def rainrate_decode(self, byte2, byte3):
# if byte3(b2 here) is 0xFF, or 255, there is no rain
#print("b2:{} b3:{} = result:{}".format(byte2, byte3, byte2 + (byte3 >> 4 << 8)))
if byte2 == 255:
rainstate = 0
rainrate = 0
elif byte2 == 254:
rainstate = 1
rainrate = 0.2
else:
rainstate = 2
if byte3 > 4:
rainrate = 720 / ((byte3 >> 4 << 8) + byte2)
else:
rainrate = 0
result = {"state": float(rainstate), "rate": float(rainrate)}
#print(result)
return result
def DecodePacket(self, packet):
# By default and most of the time, write to weather
self.write_influx_db = self.weather_influx_db
# Set all to None
self.wind = False
self.measurement = False
self.name = False
self.value = False
self.tags = False
self.wind = self.decode_wind(
{"windspeed": packet[1], "winddir": packet[2]})
if self.davis_packet_id == 2:
# SuperCap charge 0x2
if _DEBUG:
print('SCAP:')
supercap = self.supercap_decode(
packet[3], packet[4]
)
if _DEBUG:
print("{}".format(supercap))
self.write_influx_db = self.stat_influx_db
self.measurement = 'iss'
self.name = 'voltage'
self.tags = {'type': 'capacitor'}
self.value = supercap
elif self.davis_packet_id == 3:
# No fucking idea 0x3
# {'hop':1,'h':48,'b0':6,'b1':237,'b2':255,'b3':195,'b4':135,'b5':50,'b6':110,'b7':255,'b8':255,'b9':179,'rssi':45,'lqi':0,'nxt':64,'cnt':163}
self.measurement = None
self.name = None
self.tags = None
self.value = None
elif self.davis_packet_id == 5:
# Rainrate 0x5
rainrate_dict = self.rainrate_decode(
packet[3],
packet[4])
if _DEBUG:
print("RAINRATE: {}".format(rainrate_dict))
self.measurement = 'rain'
self.name = 'value'
self.tags = {'type': 'rainrate'}
self.value = rainrate_dict['rate']
elif self.davis_packet_id == 6:
# Sun Irradiation 0x6 (NOT ON vantage Vue)
pass
elif self.davis_packet_id == 7:
# Super Cap voltage 0x7
solarvolt = self.solarvolt_decode(
packet[3], packet[4]
)
if _DEBUG:
print("SOLV {}".format(solarvolt))
self.write_influx_db = self.stat_influx_db
self.measurement = 'iss'
self.name = 'voltage'
self.tags = {'type': 'solar'}
self.value = solarvolt
elif self.davis_packet_id == 8:
# Temperature 0x8
raw_temp = (packet[3] << 8) + packet[4]
temp_dict = self.decode_temp(raw_temp)
temp = float(temp_dict['celsius'])
if _DEBUG:
print("TEMP: {}".format(temp))
self.measurement = 'temphumi'
self.name = 'temperature'
self.tags = {'type': 'external'}
self.value = temp
elif self.davis_packet_id == 9:
# Wind gusts 0x9
windgust = packet[3] * 1.60934
if _DEBUG:
print("WINDGUST: {}".format(windgust))
self.measurement = 'wind'
self.name = 'value'
self.tags = {'type': 'windgust'}
self.value = windgust
elif self.davis_packet_id == 10:
# Humidity 0xa
raw_humidity = (((packet[4] >> 4) & 0b0011) << 8) \
+ packet[3]
humidity = round(int(raw_humidity) / float(10), 1)
if _DEBUG:
print("HUMI: {}".format(humidity))
self.measurement = 'temphumi'
self.name = 'humidity'
self.tags = {'type': 'external'}
self.value = humidity
elif self.davis_packet_id == 14:
# Rain bucket tips 0xe
raw_rain = (packet[3]) + (packet[4] >> 7 << 8)
rain = self.rain_decode(raw_rain)
if _DEBUG:
print("RAINCOUNT: {}".format(rain))
self.measurement = 'rain'
self.name = 'value'
self.tags = {'type': 'rain_bucket_tips'}
self.value = rain

20
inet.conf Normal file
View File

@@ -0,0 +1,20 @@
# No spaces around '='
# Try to avoid spaced at end or beginning of passwords. Stripping it
# One config option per line, all options need to be set.
_SSID=YourSSID
_PASS=YourWifiPass
# Time to keep waiting for the network to come up. Delay is 1001ms
_TIMEOUT=15
_INFLUX_HOST=IPofTheInfluxDB
_INFLUX_PORT=PortOfTheInfluxDB
# currently not implemented
_INFLUX_USER=InfluxUser
_INFLUX_PASS=HisPasswd
# Names of the databases
_INF_DB_WEATHER=weather
_INF_DB_STATUS=status
_INF_DB_RAW=raw

158
influx_structure.md Normal file
View File

@@ -0,0 +1,158 @@
#Structure of InfluxDB
InfluxDB was chosen for it's simplicity and ease of management, live with it.
##influxDB SCHEMA:
Firs off, 2 databases:
weather
status
###DB weather
measure wind
----------------
value | speed or direction or windgust | davis_id
---------------------------------------------------
field tag tag
measure temphumi
----------------
temperature | humidity | external, internal | davis_id
---------------------------------------------------------
field field tag tag
measure rain
----------------
rain | rate / total / intensity | davis_id
---------------------------------------------
field tag tag
###DB status
iss measure
----------------
voltage | solar or capacitor
----------------------------------------------------------------
field tag
RasPI system (only on the raspi system)
----------------
usage | disk, mem, cpu, eth, wifi %
------------------------------------
field | tag
## Retention policies
-------
weather
-------
create retention policy realtime on weather duration 168h replication 1 shard duration 1h
create retention policy monthly on weather duration 720h replication 1 shard duration 24h
create retention policy yearly on weather duration 8760h replication 1 shard duration 168h
create retention policy infinite on weather duration 0s replication 1 shard duration 720h
alter retention policy realtime on weather default
------
status
------
create retention policy realtime on status duration 168h replication 1 shard duration 1h
create retention policy monthly on status duration 720h replication 1 shard duration 24h
create retention policy yearly on status duration 8760h replication 1 shard duration 168h
create retention policy infinite on status duration 0s replication 1 shard duration 720h
alter retention policy realtime on status default
## Continuous queries
-------------------------------------------------------------------------------
WIND
-------------------------------------------------------------------------------
CREATE CONTINUOUS QUERY "cq_wind_10m" ON "weather_v2" BEGIN
SELECT max(value) AS wind_max, mean(value) AS wind, min(value) AS wind_min
INTO "monthly"."wind_aggregated"
FROM realtime.wind
GROUP BY time(10m), type
END
CREATE CONTINUOUS QUERY "cq_wind_1h" ON "weather_v2" BEGIN
SELECT max(value) AS wind_max, mean(value) AS wind, min(value) AS wind_min
INTO "yearly"."wind_aggregated"
FROM realtime.wind
GROUP BY time(1h), type
END
CREATE CONTINUOUS QUERY "cq_wind_6h" ON "weather_v2" BEGIN
SELECT max(value) AS wind_max, mean(value) AS wind, min(value) AS wind_min
INTO "infinite"."wind_aggregated"
FROM realtime.wind
GROUP BY time(6h), type
END
-------------------------------------------------------------------------------
RAIN
-------------------------------------------------------------------------------
CREATE CONTINUOUS QUERY "cq_rain_10m" ON "weather_v2" BEGIN
SELECT max("value") AS val_max, mean(value) AS value
INTO "monthly"."rainrate_aggregated"
FROM realtime.rain
GROUP BY type,time(10m)
END
CREATE CONTINUOUS QUERY "cq_rain_1h" ON "weather_v2" BEGIN
SELECT max("value") AS val_max, mean(value) AS value
INTO "yearly"."rainrate_aggregated"
FROM realtime.rain
GROUP BY type,time(1h)
END
CREATE CONTINUOUS QUERY "cq_rain_6h" ON "weather_v2" BEGIN
SELECT max("value") AS val_max, mean(value) AS value
INTO "infinite"."rainrate_aggregated"
FROM realtime.rain
GROUP BY type,time(6h)
END
-------------------------------------------------------------------------------
TEMPHUMI
-------------------------------------------------------------------------------
CREATE CONTINUOUS QUERY "cq_temphumi_10m" ON "weather_v2" BEGIN
SELECT
max("humidity") AS humidity_max,
min("humidity") AS humidity_min,
mean("humidity") AS humidity,
max("temperature") AS temperature_max,
min("temperature") AS temperature_min,
mean("temperature") AS temperature
INTO "monthly"."temphumi_aggregated"
FROM realtime.temphumi
GROUP BY type, time(10m)
END
CREATE CONTINUOUS QUERY "cq_temphumi_1h" ON "weather_v2" BEGIN
SELECT
max("humidity") AS humidity_max,
min("humidity") AS humidity_min,
mean("humidity") AS humidity,
max("temperature") AS temperature_max,
min("temperature") AS temperature_min,
mean("temperature") AS temperature
INTO "yearly"."temphumi_aggregated"
FROM realtime.temphumi
GROUP BY type, time(1h)
END
CREATE CONTINUOUS QUERY "cq_temphumi_6h" ON "weather_v2" BEGIN
SELECT
max("humidity") AS humidity_max,
min("humidity") AS humidity_min,
mean("humidity") AS humidity,
max("temperature") AS temperature_max,
min("temperature") AS temperature_min,
mean("temperature") AS temperature
INTO "infinite"."temphumi_aggregated"
FROM realtime.temphumi
GROUP BY type, time(6h)
END
-------------------------------------------------------------------------------
TRAFFIC
-------------------------------------------------------------------------------
CREATE CONTINUOUS QUERY "cq_net_1m" ON "status" BEGIN
SELECT NON_NEGATIVE_DERIVATIVE(max(*)) as traffic
INTO "monthly"."net_aggregated"
FROM realtime.net
WHERE time > now()-1m
GROUP BY time(30s)
END

89
main.py Normal file
View File

@@ -0,0 +1,89 @@
import cc1101_davis
import davis_decode
import utime
import WiFi
gc.collect()
_DEBUG = False
wifi_con = WiFi.NetSet('infra')
wifi_con.readNetworkConfig()
ips = wifi_con.connectInfra(
wifi_con._SSID,
wifi_con._PASS,
wifi_con._TIMEOUT)
if _DEBUG:
print("IPCONF: {}".format(ips))
davis = cc1101_davis.CC1101()
davis.setRegisters()
davis.setFrequency(davis.hopIndex)
decoder = davis_decode.davisDecoder(
wifi_con._INF_DB_WEATHER,
wifi_con._INF_DB_STATUS,
wifi_con._INF_DB_RAW)
# Main receive loop
while True:
data_length = davis.readRegister(davis.CC1101_RXBYTES)
data = ""
if data_length & 0x7f == 15:
data = davis.readBurst(davis.CC1101_RXFIFO, 10)
rssi = davis.readRssi()
lqi = davis.readLQI()
hop = davis.hopIndex
davis.flush()
davis.hop()
davis.rx()
data_int = [davis_decode.reverseBits(int(item)) for item in data]
header = decoder.davis_id(data_int[0])
decoder.DecodePacket(data_int)
data_prn = "{:5} {:5} {:5} {:5} {:5} {:5} {:5} {:5} {:5} {:5}".format(
data_int[0],
data_int[1],
data_int[2],
data_int[3],
data_int[4],
data_int[5],
data_int[6],
data_int[7],
data_int[8],
data_int[8],)
print("{_data:60} HOP: {_hop:<5} RSSI: {_rssi:<5} LQI: {_lqi:<5}".format(
_rssi=rssi,
_hop=hop,
_data=data_prn,
_lqi=lqi))
if _DEBUG:
print("Header: {} Wind: {}".format(header, decoder.wind))
print("{}: {}/{} ({})".format(
decoder.measurement,
decoder.name,
decoder.value,
decoder.tags))
sent_ok = False
data_sent = None
try:
(sent_ok, data_sent) = davis_decode.send_to_influx(
wifi_con._INFLUX_HOST,
wifi_con._INFLUX_PORT,
decoder.write_influx_db,
wifi_con._INFLUX_USER,
wifi_con._INFLUX_PASS,
decoder.unit_id,
decoder.wind,
decoder.measurement,
decoder.name,
decoder.value,
decoder.tags)
except Exception as e:
print("ERROR: Data send 'urequest': {}".format(e))
if _DEBUG:
if sent_ok:
print("DATA SEND: {}".format(data_sent.status_code))
else:
print("DATA SEND FAIL: {}".format(data_sent))
else:
utime.sleep_ms(100)
gc.collect()

371
readme.md Normal file
View File

@@ -0,0 +1,371 @@
#ESP8266 + CC1101 Davis weather station wifi logger
The intention is to gather data from a Weather station made by Davis.
In this case a Vantage Vue (integrated all sensors in one package) and
push them directly to an InfluxDB instance via WiFi.
##Prerequisites:
- WiFi available, plus access to it. (WPA2 PSK preferred)
- Running INfluxDB instance on the same network
- ESP8266 microcontroller (NodeMCU 8266 preferred)
- git, since you're here, I assume this is already settled
- Micropython tools: ampy, esptool
- serial console emulator, I use picocom
- CC1101 from Texas Instruments radio chip, the 868 MHz version! There are 433Mhz sold out there, read descriptions
- a couple wires, need to solder those tiny CC1101 pins and wires.
- 5V / 3.3V source, depending on what version of ESP you get. A stable 3.3V is preferred
##Quick setup of HW:
###1. Interconnect these pins:
The pins are marked on the NodeMcu ESP8266, on the CC1101 module, pins are counted from left, if you face the chip towards you.
ESP8266 | ESP8266 description | CC1101 | CC1101 description |
|-------|---------------------|-----------|--------------------|
|GND | GND | 1- GND | GND |
|3V3 | Voltage In | 2- VCC | Vcc, Input voltage |
|D7 | GPIO13 | 3- Pin3 | MOSI |
|D5 | GPIO14 | 4- Pin4 | SCLK |
|D6 | GPIO12 | 5- Pin5 | MISO |
|- | - | 6- Pin6 | GDO2 |
|- | - | 7- Pin7 | GDO0 |
|D8 | GPIO15 | 8- Pin8 | CSN |
IO pin GDO0, currently configured as interrupt, when new packet is received (i.e. goes HIGH).
This currently just to lights up a led, interrupt based receive is not implemented, though sounds cool.
###2. Clone this repo, get Micropython
```
git clone https://bastart.spoton.cz/git/Ventil/esp8266_CC1101_davis_vantage_vue.git
cd esp8266_CC1101_davis_vantage_vue
wget https://micropython.org/resources/firmware/esp8266-20191220-v1.12.bin -P /tmp
```
###3. Upload Micropython, check
Need to delete the flash first, then write the custom firmware.
You need to determine which device is the one
to write to. If you have only one ESP8266, you are probably safe to use the ttyUSB0,
I will use ttyUSB1 as I have multiple UARTS on my machine
```
esptool.py --port /dev/ttyUSB1 --baud 115200 erase_flash
esptool.py v2.8
Serial port /dev/ttyUSB1
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: cc:50:e3:56:b2:5b
Uploading stub...
Running stub...
Stub running...
Erasing flash (this may take a while)...
Chip erase completed successfully in 7.8s
Hard resetting via RTS pin...
```
Now it is time to upload uPython:
```
esptool.py --port /dev/ttyUSB1 --baud 115200 write_flash 0 /tmp/esp8266-20191220-v1.12.bin
esptool.py v2.8
Serial port /dev/ttyUSB1
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: cc:50:e3:56:b2:5b
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash params set to 0x0040
Compressed 619828 bytes to 404070...
Wrote 619828 bytes (404070 compressed) at 0x00000000 in 35.8 seconds (effective 138.6 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
```
And of course, when you try to get to the serial console, you should get somethinglike this
```
picocom -b 115200 /dev/ttyUSB1
picocom v3.1
port is : /dev/ttyUSB1
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
stopbits are : 1
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
hangup is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv -E
imap is :
omap is :
emap is : crcrlf,delbs,
logfile is : none
initstring : none
exit_after is : not set
exit is : no
Type [C-a] [C-h] to see available commands
Terminal ready
>>>
```
Exit from the console with Ctrl + A + X or ampy will not be able to list files
on the esp8266
###4. Freeze modules, or just upload the .mpy files
You can simply upload all the modules in question. If you modify anything in the .py
files, you need to freeze them again with mpy-cross <filename>
```
/usr/bin/ampy -p /dev/ttyUSB1 put WiFi.mpy
/usr/bin/ampy -p /dev/ttyUSB1 put cc1101_davis.mpy
/usr/bin/ampy -p /dev/ttyUSB1 put davis_decode.mpy
```
to freeze a module:
```
mpy-cross WiFi.py
ls -l WiFi.*
WiFi.mpy <-- the newly compiled (frozen) module
WiFi.py
```
###5. Modify inet.conf
Before uploading the inte.conf, please change it to your desired values.
###6, Upload files
```
/usr/bin/ampy -p /dev/ttyUSB1 put boot.py
/usr/bin/ampy -p /dev/ttyUSB1 put main.py
/usr/bin/ampy -p /dev/ttyUSB1 put inet.conf
/usr/bin/ampy -p /dev/ttyUSB1 ls
/WiFi.mpy
/boot.py
/cc1101_davis.mpy
/davis_decode.mpy
/inet.conf
/main.py
```
###7. If you haven't already, create 2 DBs in inclux
I am tempted to push the raw, undecoded data to a DB as well, but influx is not siutd for this. You can ignore the last DB creation
```
ssh 192.168.1.2
influx
create database weather
create database status
create database raw
```
###8. Restart esp8266, check data on serial
```
picocom -b 115200 /dev/ttyUSB1
picocom v3.1
port is : /dev/ttyUSB1
flowcontrol : none
baudrate is : 115200
parity is : none
databits are : 8
stopbits are : 1
escape is : C-a
local echo is : no
noinit is : no
noreset is : no
hangup is : no
nolock is : no
send_cmd is : sz -vv
receive_cmd is : rz -vv -E
imap is :
omap is :
emap is : crcrlf,delbs,
logfile is : none
initstring : none
exit_after is : not set
exit is : no
Type [C-a] [C-h] to see available commands
Terminal ready
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> {ll<6C><6C>|<7C>#<23>o
<20>
$<24>
c|<7C><><EFBFBD><EFBFBD>|#<23>
#<23><>nN<6E>$oN<6F><4E><EFBFBD>
bp<62><70>$sl{lp<6C>o<EFBFBD>
<20>l
"
N<>|<7C>l
#<23><>nN<6E>$<24><>l`<60>Nl or<6F><72><EFBFBD>N
<20>
<20>$p<>n<EFBFBD>
r<>ܜ<EFBFBD>
bn<62>|$
<20><>
#<23><>on<6F>
l <20>n$<24>$`n{<7B>ےo
l <20>o
<20><>#<23>ol<6F>
<20><>no<6E><6F>{lp<6C>o<EFBFBD>
r<><72><EFBFBD><EFBFBD><EFBFBD>
<20>p<EFBFBD>
#
N<>|<7C><>p<EFBFBD><70>on<6F>l<EFBFBD>l <20>n$<24>$`nr<6E><72><EFBFBD><EFBFBD>
$l`{<7B><>n
l$ <20><><EFBFBD>o<EFBFBD>r<EFBFBD><72>n|<7C>ll$d`#<23><><EFBFBD>r<EFBFBD>l<EFBFBD>o<EFBFBD><6F>o<EFBFBD>l <20><>r<EFBFBD>$<24>$<24>
l`<60><>r<EFBFBD>p<EFBFBD><70>l<EFBFBD>
$`<60><><EFBFBD>o<EFBFBD>l<EFBFBD><6C><EFBFBD>
l$`sl<73><6C>b<EFBFBD><62><EFBFBD>#
<20><>B|
$b<><62><EFBFBD>#|<7C><><EFBFBD><EFBFBD>l$b<><62>n<EFBFBD><6E>Trying... 15 more times
Trying... 14 more times
Trying... 13 more times
Trying... 12 more times
Trying... 11 more times
Trying... 10 more times
IPCONF: {'ip': '192.168.1.174', 'mask': '255.255.255.0', 'gw': '192.168.1.254', 'dns': '192.168.1.4'}
0 10 4 35 8 4 78 196 255 255 HOP: 0 RSSI: -71.5 LQI: 127
Header: {'bat_low': 0, 'packet_id': 0, 'davis_id': 0} Wind: {'speed': 16.1, 'direction': 5.6}
False: False/False (False)
DATA SEND FAIL: ERROR measurement set False
224 10 234 17 1 4 38 49 255 255 HOP: 1 RSSI: -70 LQI: 127
Header: {'bat_low': 0, 'packet_id': 14, 'davis_id': 0} Wind: {'speed': 16.1, 'direction': 327.6}
rain: value/17.0 ({'type': 'rain_bucket_tips'})
DATA SEND: 204
80 9 224 255 113 15 89 230 255 255 HOP: 2 RSSI: -70 LQI: 127
Header: {'bat_low': 0, 'packet_id': 5, 'davis_id': 0} Wind: {'speed': 14.5, 'direction': 313.6}
rain: value/0.0 ({'type': 'rainrate'})
DATA SEND: 204
128 8 252 34 233 10 229 180 255 255 HOP: 3 RSSI: -70 LQI: 127
Header: {'bat_low': 0, 'packet_id': 8, 'davis_id': 0} Wind: {'speed': 12.9, 'direction': 352.8}
temphumi: temperature/13.3 ({'type': 'external'})
DATA SEND: 204
160 8 249 109 41 2 202 57 255 255 HOP: 4 RSSI: -69 LQI: 127
Header: {'bat_low': 0, 'packet_id': 10, 'davis_id': 0} Wind: {'speed': 12.9, 'direction': 348.6}
temphumi: humidity/62.1 ({'type': 'external'})
DATA SEND: 204
224 9 225 17 1 2 182 58 255 255 HOP: 0 RSSI: -68 LQI: 127
Header: {'bat_low': 0, 'packet_id': 14, 'davis_id': 0} Wind: {'speed': 14.5, 'direction': 315.0}
rain: value/17.0 ({'type': 'rain_bucket_tips'})
DATA SEND: 204
80 10 241 255 115 10 236 224 255 255 HOP: 1 RSSI: -68.5 LQI: 127
Header: {'bat_low': 0, 'packet_id': 5, 'davis_id': 0} Wind: {'speed': 16.1, 'direction': 337.4}
rain: value/0.0 ({'type': 'rainrate'})
DATA SEND: 204
128 16 233 34 219 10 39 214 255 255 HOP: 2 RSSI: -68.5 LQI: 127
Header: {'bat_low': 0, 'packet_id': 8, 'davis_id': 0} Wind: {'speed': 25.7, 'direction': 326.2}
temphumi: temperature/13.2 ({'type': 'external'})
```
And with '_DEBUG' set to False on line 7, in main.py:
You can see the raw data that are comming in from the Davis weather station.
```
>>>
MPY: soft reboot
Trying... 15 more times
0 17 244 212 193 138 98 76 255 255 HOP: 0 RSSI: -68 LQI: 127
224 13 3 17 3 3 32 253 255 255 HOP: 1 RSSI: -68.5 LQI: 127
80 13 5 255 112 2 10 211 255 255 HOP: 2 RSSI: -68 LQI: 127
128 9 236 34 203 2 181 206 255 255 HOP: 3 RSSI: -68.5 LQI: 127
160 11 252 106 43 2 123 92 255 255 HOP: 4 RSSI: -69 LQI: 127
224 13 247 17 3 6 37 228 255 255 HOP: 0 RSSI: -68.5 LQI: 127
80 12 6 255 113 2 8 111 255 255 HOP: 1 RSSI: -69 LQI: 127
128 9 239 34 203 3 62 51 255 255 HOP: 2 RSSI: -70 LQI: 127
32 8 232 212 195 128 93 215 255 255 HOP: 3 RSSI: -70.5 LQI: 127
224 6 239 17 3 3 7 218 255 255 HOP: 4 RSSI: -69.5 LQI: 127
80 7 237 255 115 7 72 162 255 255 HOP: 0 RSSI: -69 LQI: 127
128 9 14 34 203 0 252 14 255 255 HOP: 1 RSSI: -68.5 LQI: 127
```
If you are interested in the packet format, please:
```
Header byte0 byte1 byte2 byte3 byte4 byte5 byte6 byte7 byte8 Freq Sig_strength Link_quality
224 13 3 17 3 3 32 253 255 255 HOP: 1 RSSI: -68.5 LQI: 127
```
###9, explore data in Influx
You're all set, let's look at the data
```
ssh 192.168.1.2
influx
> use weather
Using database weather
> select * from wind where time > now() - 1m group by type
name: wind
tags: type=direction
time davis_id value
---- -------- -----
1590755264047546640 0 23.8
1590755266495686261 0 12.6
1590755269170611760 0 315
1590755271670765583 0 4.2
1590755274297615725 0 340.2
1590755276695612090 0 351.4
1590755279347820779 0 14
1590755282048791933 0 14
1590755284420807397 0 5.6
1590755287147874950 0 5.6
1590755289521471177 0 25.2
1590755292271754999 0 323.4
1590755294748104920 0 351.4
1590755297195883784 0 350
1590755302322174318 0 330.4
1590755317723159515 0 333.2
1590755320496027169 0 341.6
name: wind
tags: type=speed
time davis_id value
---- -------- -----
1590755264047546640 0 20.9
1590755266495686261 0 20.9
1590755269170611760 0 16.1
1590755271670765583 0 25.7
1590755274297615725 0 24.1
1590755276695612090 0 22.5
1590755279347820779 0 24.1
1590755282048791933 0 22.5
1590755284420807397 0 20.9
1590755287147874950 0 17.7
1590755289521471177 0 20.9
1590755292271754999 0 22.5
1590755294748104920 0 19.3
1590755297195883784 0 22.5
1590755302322174318 0 20.9
1590755317723159515 0 11.3
1590755320496027169 0 12.9
name: wind
tags: type=windgust
time davis_id value
---- -------- -----
1590755279347820779 0 25.7494
```
### Optionally, get grafana to plot the graphs for you