Managing Power Distribution Unit via SMS
From MikroTik Wiki
Below a script to manage Aviosys 9258S, 9258HP, 9258DS, ... PDU via /tool sms
Warning : needs Routeros >= 6.2, see comments in the script.
Original page (in French): Gestion des alimentations électriques via SMS
Testing
Getting state of outlets of default device and device named pwr004 :
/system script run LndkSmsPower :global DV "pwr004"; /system script run LndkSmsPower
Switching outlet 2 of default device :
:global PR 2; /system script run LndkSmsPower
Cycling outlet 1 of default device :
:global PR 1; :global OP "RE"; /system script run LndkSmsPower
Sending SMS
SMS to send to request state of pwr099 device, and then to switch outlet 3 of default device pwr015 :
:cmd password script LndkSmsPower DV=pwr099 :cmd password script LndkSmsPower PR=3
Android phone screenshot :
Cycling outlet 3 of default device :
:cmd password script LndkSmsPower OP=re PR=3
The LndkSmsPower script
Downloadable file LndkSmsPower.rsc (/tool fetch url=http://blog.lekermeur.net/wp-content/uploads/2015/02/LndkSmsPower.rsc) :
####################################################################################### # Script RouterOS LndkSmsPower # # Managing outlets of Aviosys PDU 9258S, 9258HP and 9258DS via SMS # # Send state of outlets of the device, switch or reinit outlet # # Web page : http://blog.lekermeur.net/?p=2531 # # Marc Dilasser, Le Net du Kermeur, Fevrier 2015 # ####################################################################################### :global DV :global PR :global OP :local ADRIP "" :local HPORT :local NETWORK "MyNet" :local DEVNAME "" :local MODEL "" :local PRISE -1 :local NBJOB :local NBSMS :local VER :local NBOPER :local URL :local ERR :local OUTFILE "LndkPowerState" :local IDF :local CONTENT :local MSG :local HHMMSS :local IJ :local IK :local IL :local ISTAT :local IOSTATE :local ITEM :local PORT :local NUMTEL :local DEBUG 0 :local ADMIN :local PASSWORD :local OPER :local AROPERS :local ONOFF [:toarray ("OFF,ON ")] :local HEXA [:toarray ("0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f")] :local LANG :local ARLANGS [:toarray ("en,fr")] :local AAR { "address"={ en="address"; fr="adresse" }; "outlet"={ en="outlet"; fr="prise" }; "device"={ en="device"; fr="equipement"}; "model"={ en="model"; fr="modele" }; "state"={ en=" state of "; fr=" etat de " }; "at"={ en=" at "; fr=" a " }; "err200"={ en="sending sms error"; fr="erreur envoi SMS" }; "err220"={ en="http error"; fr="erreur acces http" }; "err230"={ en="Url non defined"; fr="Url non definie" }; "err240"={ en="script already running"; fr="script deja en cours" }; } :global ChangeToMajOrMinCase do={ :local S1 :local S2 "" :local CH "" :local I1 :local I2 :local I3 :local MINMAJ { "min"="abcdefghijklmnopqrstuvwxyz"; "maj"="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; } :local SOURCE "min" :local TARGET "maj" :set S1 $1 :set I2 [:len $S1] :if ($2 = 0) do={ :set SOURCE "maj"; set TARGET "min"; } :if ($I2 > 0) do={ for I1 from=0 to=($I2 - 1) do={ :set CH [:pick $S1 $I1 ($I1 + 1)] :set I3 [:find ($MINMAJ->$SOURCE) $CH] :if ($I3 >= 0) do={ :set CH [:pick ($MINMAJ->$TARGET) $I3 ($I3 + 1)] } :set S2 ($S2 . $CH) } } :return $S2 } :local ToUpper do={ :global ChangeToMajOrMinCase :return [$ChangeToMajOrMinCase $1] } :local ToLower do={ :global ChangeToMajOrMinCase :return [$ChangeToMajOrMinCase $1 0] } # if ($VER >= 6.2) :local DoHttp do={ :local LERR 0 :do { /tool fetch url="$1" dst-path="$2" } on-error={ :set LERR 1 } :return $LERR } :local DoSendSms do={ :local LERR 0 :local MESS :set MESS [:pick $3 0 158] :do { /tool sms send "$1" "$2" message="$MESS" } on-error={ :set LERR 1 } :return $LERR } #endif ####################################################################################### # Valeurs a configurer suivant exploitation : # # - user et mot de passe Aviosys # # - adresse ip # # - nom de device # # - modele # # - 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 # ####################################################################################### :if ([:len $DV] = 0) do={:set DV "pwr001"; } :set ADMIN "admin" :set PASSWORD "password" # Default lang is en # :set LANG "fr" :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 DEBUG 1 } :if ($DV = "pwr029") do={ :set ADRIP "192.168.1.100" :set HPORT "8084" :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=GetSysIO # # < IOVALUE:fb # # 9258DSv4 : (firmware version 4.x) # # > wget -qO- http://192.168.8.100/set.cmd?user=admin+pass=password+cmd=GetPower # # < 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>... # ####################################################################################### :set NBJOB [/system script job print count-only where script=LndkSmsPower] if ($NBJOB > 1) do={ :log error ($AAR->"err240"->$LANG) return 240 } ####################################################################################### # List of operations # # Default operation is ST, only send STATE # # If PR (outlet) is set, defaut OP is SW, to switch this outlet # # If OP is RE (reinit) and PR is set, operations are STATE,SWITCH,DELAY,SWITCH,STATE # # If OP is LI (list names of outlets), operation is LIST (not implemented yet) # ####################################################################################### :if (([:len [:find $ARLANGS $LANG]]) = 0) do={ :set LANG "en"; } :if ([:len $OP] = 0) do={ :set OP "ST"; :if ([:len $PR] = 1) do={ :set OP "SW"; } } else={ :set OP [$ToUpper $OP] } :set AROPERS [:toarray ("STATE")] :if ($OP = "SW") do={ :if ([:len $PR] = 1) do={ :set AROPERS [:toarray ("STATE,SWITCH,STATE")] } } :if ($OP = "RE") do={ :if ([:len $PR] = 1) do={ :set AROPERS [:toarray ("STATE,SWITCH,STATE,DELAY20,SWITCH,STATE")] } } :if ($OP = "LI") do={ :set AROPERS [:toarray ("LIST")] } :if ([:len $PR] > 0) do={ :set PRISE ([:tonum $PR] - 1); } :if ([:len $OP] = 0) do={ :set OP ""; } :set VER [/system resource get version] :set MSG (($AAR->"device"->$LANG) . " " . $DEVNAME . ", ") :set MSG ($MSG . ($AAR->"model"->$LANG) . " " . $MODEL . ", ") :set MSG ($MSG . ($AAR->"address"->$LANG) . " " . $ADRIP) :log info $MSG ####################################################################################### # Do while some operation to do # ####################################################################################### foreach OPER in ($AROPERS) do={ :if ($OPER = "STATE") do={ :set URL "" :if ($MODEL = "9258S") do={ :set URL ("http://" . $ADMIN . ":" . $PASSWORD . "@" . $ADRIP ) :if ([:len $HPORT] > 0) do={ :set URL ($URL . ":" . $HPORT); } :set URL ($URL . "/Set.cmd\?CMD=GetPower") } :if ($MODEL = "9258DSv1") do={ :set URL ("http://" . $ADRIP); :if ([:len $HPORT] > 0) do={ :set URL ($URL . ":" . $HPORT); } :set URL ($URL . "/Set.cmd\?user=" . $ADMIN ) :set URL ($URL . "+pass=" . $PASSWORD . "+CMD=GetSysIO") } :if ($MODEL = "9258DSv4") do={ :set URL ("http://" . $ADRIP) :if ([:len $HPORT] > 0) do={ :set URL ($URL . ":" . $HPORT); } :set URL ($URL . "/set.cmd\?user=" . $ADMIN ) :set URL ($URL . "+pass=" . $PASSWORD . "+cmd=GetPower") } :if ($MODEL = "9258HP") do={ :set URL ("http://" . $ADRIP) :if ([:len $HPORT] > 0) do={ :set URL ($URL . ":" . $HPORT); } :set URL ($URL . "/GetPower.cgi") } :if ([:len $URL] = 0) do={ :return 250 } else={ :if ($DEBUG > 0) do={ :put "Url : $URL"; } } :set ERR 0 # if ($VER >= 6.2) :set ERR [$DoHttp $URL $OUTFILE] # else # :set ERR 0 # /tool fetch url=$URL dst-path=$OUTFILE # endif :if ($ERR < 1) do={ :set IDF [/file find where name=$OUTFILE] :set CONTENT [ /file get $IDF contents] :if ($DEBUG > 0) do={ :put $CONTENT; } :set HHMMSS [/system clock get time] :set MSG ($NETWORK . " :" . ($AAR->"state"->$LANG)) :set MSG ($MSG . $DEVNAME . ($AAR->"at"->$LANG) . $HHMMSS . "\n") :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 . ($AAR->"outlet"->$LANG) . " " . [:tostr ($IJ + 1)] ) :set MSG ($MSG . ": " . [:pick $ONOFF $IK] . " ") :if (($IJ % 2) = 1) do={ :set MSG ($MSG . "\n"); } :set ISTAT ($ISTAT / 2) :set IJ ($IJ + 1) } } :if (($MODEL = "9258S") || ($MODEL = "9258DSv4")) do={ :if ($MODEL = "9258S") do={ :set IJ 10; :set IK 4; } else={ :set IJ 5; :set IK 8; } :if (([:pick $CONTENT 0 6] = "<html>") || ([:pick $CONTENT 0 5] = " P61=")) do={ :for IL from=1 to=$IK do={ :set MSG ($MSG . " " . ($AAR->"outlet"->$LANG) . " " . ([:tostr $IL]) . ": ") :set MSG ($MSG . ([:pick $ONOFF [:pick $CONTENT ($IJ + (($IL - 1) * 6)) ]])) :if ((($IL % 2) = 0) && ($IL < $IK)) do={ :set MSG ($MSG . "\n") } } :if ( $PRISE > -1 ) do={ :set IOSTATE [:pick $CONTENT ($IJ + (6 * $PRISE))] :log info (($AAR->"outlet"->$LANG) . " " . ($PRISE + 1) . ", iostate : $IOSTATE") } } } :if ($MODEL = "9258HP") do={ :set IJ [:find $CONTENT "Control = P4"] :if ([:len $IJ] > 0) do={ :set IJ ($IJ + 13) :set MSG ($MSG . " " . ($AAR->"outlet"->$LANG) . " 1: ") :set MSG ($MSG . ([:pick $ONOFF [:pick $CONTENT ($IJ + 15) ]])) :set MSG ($MSG . ", " . ($AAR->"outlet"->$LANG) . " 2: ") :set MSG ($MSG . ([:pick $ONOFF [:pick $CONTENT ($IJ + 10) ]]) . "\n") :set MSG ($MSG . " " . ($AAR->"outlet"->$LANG) . " 3: ") :set MSG ($MSG . ([:pick $ONOFF [:pick $CONTENT ($IJ + 5) ]])) :set MSG ($MSG . ", " . ($AAR->"outlet"->$LANG) . " 4: ") :set MSG ($MSG . ([:pick $ONOFF [:pick $CONTENT $IJ ]])) :if ( $PRISE > -1 ) do={ :set IOSTATE [:pick $CONTENT ($IJ + (5 * $PRISE))] :log info (($AAR->"outlet"->$LANG) . " " . ($PRISE + 1) . ", iostate : $IOSTATE") } } } :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] } # if ($VER >= 6.2) :set ERR [$DoSendSms $PORT $NUMTEL $MSG] :if ($ERR > 0) do={ :log error ($AAR->"err200"->$LANG) return 200 } # else # /tool sms send ... # endif } else={ :put ($MSG) :log info ($MSG) } } /file remove $IDF } else={ :log error ($AAR->"err220"->$LANG) return 220; } } :if ($OPER = "SWITCH") do={ :if (([:len $PRISE] = 1) && ([:len $IOSTATE] > 0)) do={ :set URL "" :if ($MODEL = "9258S") do={ :set URL ("http://" . $ADMIN . ":" . $PASSWORD . "@") :set URL ($URL . $ADRIP) :if ([:len $HPORT] > 0) do={ :set URL ($URL . ":" . $HPORT); } :set URL ($URL . "/Set.cmd\?CMD=SetPower") :set URL ($URL . "+P6" . [:tostr ($PRISE + 1)] . "=") :set URL ($URL . [:tostr (($IOSTATE + 1) % 2)]) } :if ($MODEL = "9258DSv4") do={ :set URL ("http://" . $ADMIN . ":" . $PASSWORD . "@") :set URL ($URL . $ADRIP) :if ([:len $HPORT] > 0) do={ :set URL ($URL . ":" . $HPORT); } :set URL ($URL . "/set.cmd\?cmd=setpower") :set URL ($URL . "+p6" . [:tostr ($PRISE + 1)] . "=") :set URL ($URL . [:tostr (($IOSTATE + 1) % 2)]) } :if ($MODEL = "9258DSv1") do={ :set URL ("http://" . $ADRIP) :if ([:len $HPORT] > 0) do={ :set URL ($URL . ":" . $HPORT); } :set URL ($URL . "/Set.cmd\?user=" . $ADMIN ) :set URL ($URL . "+pass=" . $PASSWORD . "+CMD=SetSysIO+IO=") :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 $HEXA ($IJ / 16)]) :set URL ($URL . [:pick $HEXA ($IJ % 16)]) :set URL ($URL . "+Delay=1") } :if ($MODEL = "9258HP") do={ :set URL ("http://" . $ADMIN . ":" . $PASSWORD . "@") :set URL ($URL . $ADRIP) :if ([:len $HPORT] > 0) do={ :set URL ($URL . ":" . $HPORT); } :set URL ($URL . "/SetPower.cgi\?p") :set URL ($URL . [:tostr ($PRISE + 1)] . "=") :set URL ($URL . [:tostr (($IOSTATE + 1) % 2)]) } :if ([:len $URL] = 0) do={ :log error ($AAR->"err230"->$LANG) :return 230 } :if ($DEBUG > 0) do={ :put "Url : $URL" :log info "Url : $URL" } else={ :log info "Url : $URL" # if ($VER >= 6.2) :set ERR [$DoHttp $URL $OUTFILE] # else # :set ERR 0 # /tool fetch url=$URL dst-path=$OUTFILE # endif :if ($ERR < 1) do={ :set IDF [/file find where name=$OUTFILE] /file remove $IDF } } } else={ :log error ($AAR->"err220"->$LANG) :return 220 } } :if ($OPER = "DELAY20") do={ :delay 20 } :if ($OPER = "LIST") do={ :delay 1 } } ####################################################################################### # Some cleanings # ####################################################################################### :foreach ITEM in ("DV", "OP", "PR") do={ /system script environment remove [find where name=$ITEM] } :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 LndkSmsPower ########### That's All, Folks ###########