Managing Power Distribution Unit via SMS

From MikroTik Wiki
Revision as of 10:34, 12 February 2015 by Marc Dilasser (talk | contribs)
Jump to: navigation, search

Below a script to manage Aviosys 9258S, 9258DS, ... PDU via /tool sms

Original page (in French) [1]


# Script RouterOS SMSIpPower de gestion des prises d'Aviosys 9258S et 9258DS        #
# Envoi un SMS de l'etat releve, bascule l'etat d'une prise.                        #
# Marc Dilasser, Le Net du Kermeur, Fevrier 2015                                    #
#####################################################################################

:global DV
:global PR
:global OP
:local  ADRIP     ""
:local  NETWORK   "LNDK"
:local  DEVNAME   ""
:local  MODEL     ""
:local  PRISE     -1
:local  NBJOB
:local  NBSMS
:local  VER
:local  NBOPER
:local  URL
:local  ERR
:local  OUTFILE   "EtatIpPower"
:local  IDF
:local  CONTENT
:local  MSG
:local  HHMMSS
:local  IJ
:local  IK
:local  ISTAT
:local  IOSTATE
:local  ITEM
:local  PORT
:local  NUMTEL
:local  DEBUG  0
:local  ADMIN
:local  PASSWORD
:local  ONOFF [:toarray ("OFF,ON ")]
:local  HEXAS [:toarray ("0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f")]

#######################################################################################
# Valeurs a configurer suivant exploitation :                                         #
#    - user et mot de passe Aviosys                                                   #
#    - adresse ip                                                                     #
#    - nom de device                                                                  #
#    - modele (9258S, 9258HP, 9258DSv1, 9258v4)                                       #
#    - numero telephone destinataire du SMS, par defaut allowed-number de /tool sms   #
#    - le device par defaut                                                           #
# La variable DV du SMS, si presente, donne le device                                 #
# La variable PR du SMS, si presente, donne la prise a basculer                       #
# La variable OP du SMS, si presente, donne le type d'operation (non implementee)     #
#######################################################################################
:if ([:len $DV] = 0) do={:set DV "pwr001"; }

:set  ADMIN     "admin"
:set  PASSWORD  "password"

:if ($DV = "pwr001") do={
   :set ADRIP    "10.6.7.8"
   :set DEVNAME  "pwr001"
   :set MODEL    "9258S" 
}

:if ($DV = "pwr009") do={
   :set ADRIP    "10.6.2.9" 
   :set DEVNAME  "pwr009"
   :set MODEL    "9258DSv1" 
   :set PASSWORD "motdepasse"
}

:if ($DV = "pwr028") do={
   :set ADRIP    "192.168.1.100"
   :set DEVNAME  "pwr028"
   :set MODEL    "9258DSv4"
   :set PASSWORD "motdepasse"
   :set DEBUG    1
}

:if ($DV = "pwr029") do={
   :set ADRIP    "192.168.1.100" 
   :set DEVNAME  "pwr029"
   :set MODEL    "9258HP" 
   :set PASSWORD "motdepasse"
   :set DEBUG    1
}

#######################################################################################
# END OF CONFIG                                                                       #
#######################################################################################

#################################################################################################
# CGI commands examples on different Aviosys models and responses                               #
# 9258S    :                                                                                    #
#  > /tool fetch url="http://admin:password@192.168.1.100/Set.cmd\?CMD=GetPower"                #
#  < <html>p61=0,p62=1,p63=0,p64=0</html>                                                       #
# 9258DSv1 : (firmware version 1.x)                                                             #
#  > wget -qO- http://192.168.1.100/Set.cmd?user=admin+pass=password+CMD=SetSysIO+IO=fb+Delay=1 #
#  <  IOVALUE:fb                                                                                #
# 9258DSv4 : (firmware version 4.x)                                                             #
#  > wget -qO- http://192.168.8.100/set.cmd?user=admin+pass=password+cmd=setpower+p63=1         #
#  <  P61=0,P62=1,P63=1,P64=0,P65=1,P66=1,P67=1,P68=1                                           #
# 9258HP   :                                                                                    #
#  > wget -qO- http://admin:password@192.168.1.100/SetPower.cgi?p4=1                            #
#  < <TITLE>Set Power Control</TITLE><BODY>Power Control = P4:1,P3:0,P2:1,P1:1;<p><b>[0->OFF... #
#################################################################################################

:set NBJOB [/system script job print count-only where script=SMSIpPower]
if ($NBJOB > 1) do={
   :log error "Lancement en double"
   return 240
}

:if ([:len $PR] > 0) do={ 
   :set NBOPER 3
   :set PRISE ($PR - 1); 
} else={
   :set NBOPER 1
} 
:if ([:len $OP] = 0) do={ :set OP ""; }
:set VER [/system resource get version]
:log info "Device $DEVNAME, adresse $ADRIP"

#######################################################################################
# Bouclage tant qu'il reste des operations a effectuer                                #
#######################################################################################
while ($NBOPER > 0) do={
   :set URL ""       
   :if ($MODEL = "9258S") do={
      :set URL ("http://" . $ADMIN . ":" . $PASSWORD . "@" . $ADRIP . "/Set.cmd\?CMD=GetPower")
   }
   :if ($MODEL = "9258DSv1") do={
      :set URL ("http://" . $ADRIP . "/Set.cmd\?user=" . $ADMIN . "+pass=" . $PASSWORD . "+CMD=GetSysIO")
   }
   :if ($MODEL = "9258DSv4") do={
      :set URL ("http://" . $ADRIP . "/set.cmd\?user=" . $ADMIN . "+pass=" . $PASSWORD . "+cmd=GetPower")
   }
   :if ($MODEL = "9258HP") do={
      :set URL ("http://" . $ADRIP . "/GetPower.cgi")
   }
# Pas d'URL definie, on sort
   :if ([:len $URL] = 0) do={
      :return 250
   } else={  
      :if ($DEBUG > 0) do={ :put "Url : $URL";  }
  }

# Passer la commande HTTP d'interrogation de l'etat de l'IpPower
# et recuperation du resultat, si RouterOS >= 6.2 l'erreur Http peut etre testee
   :set ERR 0
   :if ($VER >= 6.20) do={
      :do {
         /tool fetch url=$URL dst-path=$OUTFILE;
      } on-error={ :set ERR 1};
   } else={
      /tool fetch url=$URL dst-path=$OUTFILE; 
   }
   :if ($ERR < 1) do={
      :set IDF [/file find where name=$OUTFILE]
      :set CONTENT [ /file get $IDF contents]
      :if ($DEBUG > 0) do={ :put $CONTENT; }

# Message SMS
      :set HHMMSS [/system clock get time]
      :set MSG ($NETWORK . " : etat de " . $DEVNAME . " a " . $HHMMSS . "\n")

# Pour 9258DS, recuperation de deux octets en hexa
      :if ($MODEL = "9258DSv1") do={
         :set ISTAT [:tonum ("0x" . [:pick $CONTENT 9 11])]
         :set IOSTATE $ISTAT
         :set IJ 0
         while ($IJ < 8) do={
            :set IK ($ISTAT % 2)
            :set MSG ($MSG . "Prise " . [:tostr ($IJ + 1)] . " : " . [:pick $ONOFF $IK] . " ")
            :if (($IJ % 2) = 1) do={ :set MSG ($MSG . "\n"); }
            :set ISTAT ($ISTAT / 2)
            :set IJ ($IJ + 1)
         }
      }
# 9258S et 9258DSv4, on recupere un ligne du genre <html>p61=0,p62=0,p63=0,p64=0</html>
# Si un numero de prise, noter son etat
      :if (($MODEL = "9258S") || ($MODEL = "9258DSv4")) do={
          :if ($MODEL = "9258S") do={ :set IJ 10; } else={ :set IJ 5; } 
         :if (([:pick $CONTENT 0 6] = "<html>") || ([:pick $CONTENT 0 5] = " P61=")) do={
            :set MSG ($MSG . "   Prise 1 : " . ([:pick $ONOFF [:pick $CONTENT $IJ ]]))
            :set MSG ($MSG . ", prise 2 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 6) ]]) . "\n")
            :set MSG ($MSG . "   Prise 3 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 12) ]]))
            :set MSG ($MSG . ", prise 4 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 18) ]]))
            :if ($MODEL = "9258DSv4") do={
               :set MSG ($MSG . "\n")
               :set MSG ($MSG . "   Prise 5 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 24) ]]))
               :set MSG ($MSG . ", prise 6 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 30) ]]) . "\n")
               :set MSG ($MSG . "   Prise 7 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 36) ]]))
               :set MSG ($MSG . ", prise 8 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 42) ]]))
            }
            :if ( $PRISE > -1 ) do={
               :set IOSTATE [:pick $CONTENT ($IJ + (6 * $PRISE))]
               :log info ("Prise " . ($PRISE + 1) . ", iostate : $IOSTATE")
            }
         }
      }
# 9258HP
      :if ($MODEL = "9258HP") do={
         :set IJ [:find $CONTENT "Control = P4"]
         :if ([:len $IJ] > 0) do={
            :set IJ ($IJ + 13)
            :set MSG ($MSG . "   Prise 1 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 15) ]]))
            :set MSG ($MSG . ", prise 2 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 10) ]]) . "\n")
            :set MSG ($MSG . "   Prise 3 : " . ([:pick $ONOFF [:pick $CONTENT ($IJ + 5) ]]))
            :set MSG ($MSG . ", prise 4 : " . ([:pick $ONOFF [:pick $CONTENT $IJ ]]))
            :if ( $PRISE > -1 ) do={
               :set IOSTATE [:pick $CONTENT ($IJ + (5 * $PRISE))]
               :log info ("Prise " . ($PRISE + 1) . ", iostate : $IOSTATE")
            }
         }
      }
######################################################   Envoi du SMS
      if ([:len $MSG] > 60) do={
         :if ($DEBUG = 0) do={
            :set PORT [/tool sms get port]
            :if ([:len $NUMTEL] = 0) do={
               :set NUMTEL [/tool sms get allowed-number]
            }
            /tool sms send $PORT $NUMTEL message=$MSG
         } else={
            :put ($MSG)
            :log info ($MSG)
         }
      }
      /file remove $IDF
   } else={ 
# Erreur HTTP, on sort
      return 220; 
   }
   :set NBOPER ($NBOPER - 1)
# Tester s'il reste une operation de bascule de prise
   :if (($NBOPER > 1) && ([:len $PR] = 1)) do={
      :set URL ""       
      :if ($MODEL = "9258S") do={
         :set URL ("http://" . $ADMIN . ":" . $PASSWORD . "@" . $ADRIP . "/Set.cmd\?CMD=SetPower")
         :set URL ($URL . "+P6" . [:tostr ($PRISE + 1)] . "=" . [:tostr (($IOSTATE + 1) % 2)])
      }
      :if ($MODEL = "9258DSv4") do={
         :set URL ("http://" . $ADMIN . ":" . $PASSWORD . "@" . $ADRIP . "/set.cmd\?cmd=setpower")
         :set URL ($URL . "+p6" . [:tostr ($PRISE + 1)] . "=" . [:tostr (($IOSTATE + 1) % 2)])
      }
      :if ($MODEL = "9258DSv1") do={
         :set URL ("http://" . $ADRIP . "/Set.cmd\?user=" . $ADMIN . "+pass=" . $PASSWORD . "+CMD=SetSysIO+IO=")
# Construire un MASK pour un XOR
         :set IJ 8
         :set IK 0
         while ($IJ > 0) do={
            :set IK ($IK * 2)
            :if ($IJ = ($PRISE + 1)) do={ :set IK ($IK + 1); }
            :set IJ ($IJ - 1)
         }
         :set IJ ( $IOSTATE ^ $IK)
         :set URL ($URL . [:pick $HEXAS ($IJ / 16)])
         :set URL ($URL . [:pick $HEXAS ($IJ % 16)])
         :set URL ($URL . "+Delay=1")
      }
      :if ($MODEL = "9258HP") do={
         :set URL ("http://" . $ADMIN . ":" . $PASSWORD . "@" . $ADRIP . "/SetPower.cgi\?p")
         :set URL ($URL . [:tostr ($PRISE + 1)] . "=" . [:tostr (($IOSTATE + 1) % 2)])
      }
# Pas d'URL definie, on sort
      :if ([:len $URL] = 0) do={
         :return 230
      } 
      :if ($DEBUG > 1) do={
         :put "Url : $URL"
         :log info "Url : $URL"
      } else={
         :log info "Url : $URL"
         :set ERR 0
         :if ($VER >= 6.20) do={
            :do {
               /tool fetch url=$URL dst-path=$OUTFILE;
            } on-error={ :set ERR 1};
         } else={
            /tool fetch url=$URL dst-path=$OUTFILE;
         }
         :if ($ERR < 1) do={
            :set IDF [/file find where name=$OUTFILE]
            /file remove $IDF
         }
      }
      :set NBOPER ($NBOPER - 1)
   } else={
     :set NBOPER 0
   }
}

# Nettoyage
:foreach ITEM in ("DV", "OP", "PR") do={
   /system script environment remove [find where name=$ITEM]
}

# Nettoyer l'Inbox des SMS
:set NBSMS [/tool sms inbox print count-only]
:if ($NBSMS >= 30) do={
   /tool sms inbox remove 0,1,2,3,4,5,6,7,8,9
}
###########   End of SMSIpPower   ###########   That's All, Folks   ###########