Gruppo Meteo/HowTo/LorawanGateway

Da raspibo.
Jump to navigation Jump to search

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:

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 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

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