Differenze tra le versioni di "Gruppo Meteo/HowTo/LorawanGateway"
| Riga 95: | Riga 95: | ||
ora dalla macchina remota si può fare:  | ora dalla macchina remota si può fare:  | ||
  ssh root@localhost -p5022  |   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>  | ||
| + | |||
| + |   <!-- Only root can send this message -->  | ||
| + |   <policy user="root">  | ||
| + |     <!-- Allow to be sent -->  | ||
| + |     <allow send_destination="org.gpio.myboard.Pins"/>  | ||
| + |     <!-- Allow  to own  -->  | ||
| + |     <allow own="org.gpio.myboard.Pins"/>  | ||
| + |   </policy>  | ||
| + | |||
| + |   <!-- Allow any connection to receive the message -->  | ||
| + |   <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  | ||
== Monit ==  | == Monit ==  | ||
| Riga 156: | Riga 306: | ||
     every 5 cycles  |      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 ===  | === Activate monit ===  | ||
Versione delle 12:30, 20 apr 2018
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
 
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