Gruppo Meteo/HowTo/LorawanGateway
LoRaWAN Gateway on rapberry, IMST iC880A Concentrator 868MHz, Centos 7
Main characteristics
- User lorawan packet forwarder ( TTN legacy mode )
- Remote access using ssh tunneling
- Hardware reset for IMST concentrator
- Autorestart services and network connections
- Use system users for services (none run as root or privileged users)
- All software (not configuration) is packaged and use standard public repo (not signed)
- Use firewalld
Assemble the gateway
Parts:
- Raspberry 3
- iC880A - LoRaWAN® Concentrator 868MHz https://wireless-solutions.de/products/long-range-radio/ic880a.html
- IP65 Box
- LM2596 DC-DC 3-35V adjustable step-down power Supply module http://hobbycomponents.com/power/215-lm2596-dc-dc-3-35v-adjustable-step-down-power-supply-module
- 2200uF capacitor
- internet key with SIM card
- power supply 12V 2A
Assemble the gateway as described at: https://github.com/ttn-zh/ic880a-gateway/wiki
Regulate the DC-DC power Supply to output 5.0V Connect the capacitor to the output of DC-DC power Supply Connect power supply to DC-DC input Connect DC-DC output to raspberry
Operative system
Follow https://wiki.centos.org/SpecialInterestGroup/AltArch/Arm32/RaspberryPi3
enable epel:
cat > /etc/yum.repos.d/epel.repo << EOF [epel] name=Epel rebuild for armhfp baseurl=https://armv7.dev.centos.org/repodir/epel-pass-1/ enabled=1 gpgcheck=0 EOF
enable ttn:
cd /etc/yum.repos.d wget http://rmap.cc/repo/ttn/rmapcentos.repo
change root password!
Install packages
TOBEDONE
chkconfig ttn-gateway on
chkconfig ttn-imstreset-setgpio on
Autossh
- attivare autossh, ossia un tunneling ssh su macchina pubblica per
permettere l'accesso remoto di amministrazione; infatti la connesione tramite wifi o ethernet o GSM non espongono un ip pubblico (almeno senza fare un reindirizzamento di porta):
yum install autossh da root:
ssh-keygen ssh-copy-id
/usr/lib/systemd/system/autossh.service
[Unit] Description=Autossh tunneling After=network.target [Service] #User=ttn #Group=ttn WorkingDirectory=/root #ExecStart=/usr/bin/autossh -M 5023 -N -R 5022:localhost:22 pat1@ttn.rmap.it ExecStart=/usr/bin/autossh -M 0 -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -N -R 5022:localhost:22 <user>@<remotehost> SyslogIdentifier=autossh Restart=always RestartSec=30 [Install] WantedBy=multi-user.target
systemctl daemon-reload service autossh start chkconfig autossh on
ora dalla macchina remota si può fare:
ssh root@localhost -p5022
Pulsante poweoff
dnf install dbusgpio
/etc/dbus-1/system.d/dbusgpio.conf
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> <busconfig> <policy user="root"> <allow send_destination="org.gpio.myboard.Pins"/> <allow own="org.gpio.myboard.Pins"/> </policy> <policy context="default"> <allow receive_interface="org.gpio.myboard.Pins"/> </policy> </busconfig>
/etc/dbusgpio/dbusgpio-site.cfg
[dbusgpiod] logfile = '/var/log/dbusgpio/dbusgpiod.log' errfile = '/var/log/dbusgpio/dbusgpiod.err' lockfile = '/var/run/dbusgpiod.lock' busaddress='systembus' pinlist= 18,
/usr/local/bin/poweroffd
#!/usr/bin/env python # GPL. (C) 2014 Paolo Patruno. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # from dbusgpio import daemon import dbus import dbus.mainloop.glib import gobject #busaddress='tcp:host=192.168.1.180,port=1234' busaddress=None poweroffd = daemon.Daemon( stdin="/dev/null", stdout="/var/log/dbusgpio/poweroffd.log", stderr="/var/log/dbusgpio/poweroffd.err", pidfile="/var/run/poweroffd.lock", # user=autoradio.settings.user, # group=autoradio.settings.group ) def poweroff(): bus = dbus.SystemBus() ck = bus.get_object('org.freedesktop.login1', '/org/freedesktop/login1') p = dbus.Interface(ck,dbus_interface='org.freedesktop.login1.Manager') p.PowerOff(True) def signal_handler(interface,properties,arg0): print "signal received" print "interface=",interface for prop in properties.keys(): print prop, properties[prop] if prop == "Status" and properties[prop] == 0 : poweroff() #print arg0 def main(self): dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) if busaddress is None: bus = dbus.SystemBus() else: bus = dbus.bus.BusConnection(busaddress) proxy = bus.get_object('org.gpio.myboard.Pins','/org/gpio/myboard') properties_manager = dbus.Interface(proxy, 'org.freedesktop.DBus.Properties') board_manager= dbus.Interface(proxy, 'org.gpio.myboard') if not properties_manager.Get('org.gpio.myboard', 'Running'): # start management of board pins board_manager.Raise('org.gpio.myboard') #pin 18 in properties_manager.Set('org.gpio.myboard.pins.channel18','Pull',"up") properties_manager.Set('org.gpio.myboard.pins.channel18','Mode',"in") print "18 status=", properties_manager.Get('org.gpio.myboard.pins.channel18','Status') bus.add_signal_receiver(signal_handler, dbus_interface = dbus.PROPERTIES_IFACE, signal_name = "PropertiesChanged") try: loop = gobject.MainLoop() loop.run() except KeyboardInterrupt : # exit the management daemon board_manager.Quit('org.gpio.myboard') if __name__ == '__main__': import sys, os poweroffd.cwd=os.getcwd() if poweroffd.service(): sys.stdout.write("Daemon started with pid %d\n" % os.getpid()) sys.stdout.write("Daemon stdout output\n") sys.stderr.write("Daemon stderr output\n") main(poweroffd) # (this code was run as script) for proc in poweroffd.procs: proc.wait() sys.exit(0)
Assemblaggio
Connettere un pulsante normalmente apertro tra:
- Physical pin 12; BCM pin 18; Wiring Pi pin 1
- Physical pin 14; Ground
GSM
/etc/NetworkManager/system-connections
this for Vodafone:
[connection] id=vodafone uuid=9799d176-4b87-480b-82a8-d744f6f9959a type=gsm permissions= [gsm] apn=mobile.vodafone.it number=*99# [ipv4] dns-search= method=auto [ipv6] addr-gen-mode=stable-privacy dns-search= method=auto
this for TIM:
[connection] id=TIM Maxxi Alice/Internet uuid=67a55a9d-c19b-479f-8dd9-ea0a4fb23282 type=gsm autoconnect=true autoconnect-retries=0 permissions= [gsm] apn=ibox.tim.it number=*99# [serial] baud=115200 [ipv4] dns-search= method=auto [ipv6] addr-gen-mode=stable-privacy dns-search= method=ignore
or use:
nmcli connection edit type gsm con-name "mio provider"
The only thing you are likely to need to edit is the APN of your network. This can be set with set gsm.apn <APN> where APN would be something like ibox.tim.it after:
save
WIFI
installare in /lib/firmware/brcm/
https://raw.githubusercontent.com/RPi-Distro/firmware-nonfree/master/brcm/brcmfmac43455-sdio.txt
Dis/abiltare il wifi
/etc/NetworkManager/NetworkManager.conf
[keyfile] unmanaged-devices=interface-name:wlan0
Attivare Access Point
cd cd git git clone https://github.com/oblique/create_ap.git cd create_ap make install
Disabilitare la gestione del wifi con networkmanager (vedi sopra) poi:
create_ap -n wlan0 ttn-gateway
Monit
GSM
/etc/monit.d/gsm-connection (change usb_modeswitch command and serial port to adapt to your gsm modem):
CHECK PROGRAM check_gsm PATH /usr/local/bin/check_gsm TIMEOUT 30 SECONDS if status != 0 then start start program = "/sbin/usb_modeswitch -v 12d1 -p 14fe -c /usr/share/usb_modeswitch/12d1:14fe ; sleep 10; /usr/bin/nmcli device connect ttyUSB2" stop program = "/usr/bin/nmcli device disconnect ttyUSB2"
/usr/local/bin/check_gsm
#!/bin/bash set -e # "Check Mobile Broadband Connection." # testing...to see if gsm is on the list of active devices LC_ALL=C nmcli -t -f TYPE,STATE dev | grep -q "^gsm:connected$"
Packet forwarder
/usr/local/bin/check_gateway (change your gateway id and coordinate):
#!/usr/bin/python import urllib2 import json import dateutil.parser import datetime import sys GATEWAYID="eui-0ceee6fffe9da82e" LAT="44.48842723017417" LON="11.26079806901295" body=urllib2.urlopen("https://www.thethingsnetwork.org/gateway-data/location?latitude="+LAT+"&longitude="+LON+"&distance=15000").read() gatewaydata=json.loads(body) print gatewaydata[GATEWAYID]["last_seen"] lastseen = dateutil.parser.parse(gatewaydata[GATEWAYID]["last_seen"]).replace(tzinfo=None) now=datetime.datetime.utcnow() print lastseen print now elapsed=now-lastseen print "elapsed: ", elapsed if ( elapsed > datetime.timedelta(seconds=300)): sys.exit(1) sys.exit(0)
/etc/monit.d/gateway-connection
CHECK PROGRAM gateway-connection PATH /usr/local/bin/check_gateway TIMEOUT 30 SECONDS if status != 0 then restart start program = "/usr/sbin/service ttn-gateway start" stop program = "/usr/sbin/service ttn-gateway stop" every 5 cycles
Power off
/etc/monit.d/poweroff
check process dbusgpiod with pidfile /var/run/dbusgpiod.lock start program = "/bin/dbusgpiod restart" stop program = "/bin/dbusgpiod stop" check process poweroffd with pidfile /var/run/poweroffd.lock start program = "/usr/local/bin/poweroffd restart" stop program = "/usr/local/bin/poweroffd stop" depends on dbusgpiod
Activate monit
chkconfig monit on service monit start
BlueTooth
diff /boot/cmdline.txt /boot/cmdline.txt.save 1c1 < dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p3 rootfstype=ext4 elevator=deadline rootwait selinux=1 security=selinux enforcing=0 --- > dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p3 rootfstype=ext4 elevator=deadline rootwait selinux=1 security=selinux enforcing=0
/usr/lib/systemd/system/pi-bluetooth.hciuart.service
[Unit] Description=Configure Bluetooth Modems connected by UART ConditionPathIsDirectory=/proc/device-tree/soc/gpio@7e200000/bt_pins Before=bluetooth.service Wants=dev-serial1.device After=dev-serial1.device [Service] Type=forking ExecStart=/usr/bin/btuart [Install] WantedBy=multi-user.target
/usr/bin/btuart
#!/bin/sh set -x HCIATTACH=/usr/bin/hciattach SERIAL=`grep Serial /proc/cpuinfo | cut -c19-` B1=`echo $SERIAL | cut -c3-4` B2=`echo $SERIAL | cut -c5-6` B3=`echo $SERIAL | cut -c7-8` BDADDR=`printf b8:27:eb:%02x:%02x:%02x $((0x$B1 ^ 0xaa)) $((0x$B2 ^ 0xaa)) $((0x$B3 ^ 0xaa))`
if [ "$(cat /proc/device-tree/aliases/uart0)" = "$(cat /proc/device-tree/aliases/serial1)" ] ; then if [ "$(wc -c /proc/device-tree/soc/gpio@7e200000/uart0_pins/brcm\,pins | cut -f 1 -d ' ')" = "16" ] ; then $HCIATTACH /dev/ttyAMA0 bcm43xx 3000000 flow - $BDADDR else $HCIATTACH /dev/ttyAMA0 bcm43xx 921600 noflow - $BDADDR fi else $HCIATTACH /dev/ttyAMA0 bcm43xx 460800 noflow - $BDADDR fi
chkconfig pi-bluetooth.hciuart on
reboot
bluetoothctl power on agent on scan on pair <address>
Firewall
dnf install firewalld chkconfig firewalld on service firewalld start firewall-cmd --set-default-zone=block firewall-cmd --permanent --zone=block --add-service=ssh firewall-cmd --permanent --zone=block --add-service=dns
Accesso remoto
Tramite consol su porta seriale
Assicurarsi che nel file /boot/cmdline.txt /boot/cmdline.txt sia apresente
console=ttyAMA0,115200
https://elinux.org/RPi_Serial_Connection
Tramite Bluetooth
/usr/lib/systemd/system/bluetooth.service
ExecStart=/usr/libexec/bluetooth/bluetoothd --compat
service bluetooth restart
In /etc/udev/rules.d/90-rfcomm.rules, please put the following line:
KERNEL=="rfcomm[0-9]*", ENV{ID_MM_DEVICE_IGNORE}="1"
sdptool browse local sdptool add --channel=3 SP
bluetoothctl pairable on discoverable on agent on default-agent
rfcomm watch 0 3 /sbin/agetty -L rfcomm0 115200 linux
see at: https://docs.ubuntu.com/core/en/stacks/bluetooth/bluez/docs/reference/pairing/inbound
Tramite wifi
Connettersi all'AP con ssid ttn-gateway con password <password>
ssh root@ttn-gateway
Tramite ethernet
Scovare in qualche modo l'IP fornito dal dhcpserver e:
ssh root@<ipscovato>
Tramite server esterno
accedere a ttn.rmap.cc
ssh root@localhost -p 5022