I added a few more metrics, Total daliy traffic, total daily upload and total daily download.
I'm sorry i put here the code but I can't open PR.
import Domoticz
import math
import os
import sys
module_paths = [x[0] for x in os.walk(os.path.join(os.path.dirname(file), '.', '.env/lib/')) if x[0].endswith('site-packages')]
for mp in module_paths:
sys.path.append(mp)
from miktapi.sentence import sentence_pack, SentenceUnpacker
from miktapi.helper import SentenceParser
from miktapi.exceptions import UnpackerException, ParseException, PackException
class BasePlugin:
bwOptions = {"Custom": "1;Mbit/s"}
iconName = 'mikrotik-routeros-winbox'
bwUpUnit = 1
bwDownUnit = 2
statusUnit = 3
totalTrafficUnit = 4
dailyDownloadUnit = 5
dailyUploadUnit = 6
statusOptions = {
"LevelActions": "||",
"LevelNames": "Disabled|Running|Enabled",
"SelectorStyle": "0"
}
def __init__(self):
self.miktLoggedIn = False
self.miktAuthError = False
self.miktConn = None
self.miktUnpacker = SentenceUnpacker()
self.statusInterfaceId = None
self.statusRunning = None
self.statusDisabled = None
self.totalTrafficToday = {'rx': 0, 'tx': 0}
def onStart(self):
if Parameters['Mode6'] == 'Debug':
Domoticz.Debugging(1)
DumpConfigToLog()
if self.iconName not in Images:
Domoticz.Image('icons.zip').Create()
iconID = Images[self.iconName].ID
if self.bwUpUnit not in Devices:
Domoticz.Device(Name='Bandwidth UP', Unit=self.bwUpUnit, TypeName='Custom', Options=self.bwOptions,
Image=iconID).Create()
if self.bwDownUnit not in Devices:
Domoticz.Device(Name='Bandwidth Down', Unit=self.bwDownUnit, TypeName='Custom', Options=self.bwOptions,
Image=iconID).Create()
if self.statusUnit not in Devices:
Domoticz.Device(Name='Status', Unit=self.statusUnit, TypeName='Selector Switch', Image=iconID,
Options=self.statusOptions).Create()
if self.totalTrafficUnit not in Devices:
Domoticz.Device(Name='Total Traffic', Unit=self.totalTrafficUnit, TypeName='Custom', Options=self.bwOptions,
Image=iconID).Create()
if self.dailyDownloadUnit not in Devices:
Domoticz.Device(Name='Daily Download Traffic', Unit=self.dailyDownloadUnit, TypeName='Custom', Options=self.bwOptions,
Image=iconID).Create()
if self.dailyUploadUnit not in Devices:
Domoticz.Device(Name='Daily Upload Traffic', Unit=self.dailyUploadUnit, TypeName='Custom', Options=self.bwOptions,
Image=iconID).Create()
self.miktConn = Domoticz.Connection(Name='Mikrotik', Transport='TCP/IP', Protocol='None',
Address=Parameters['Address'], Port=Parameters['Port'])
self.miktConn.Connect()
Domoticz.Heartbeat(int(Parameters['Mode1']))
def onStop(self):
if Parameters['Mode3'] and self.miktConn.Connected() and self.miktLoggedIn:
self._miktCommand([
'/cancel',
'=tag=interface_status_update'
])
self._miktResetLoginFlags()
def onConnect(self, Connection, Status, Description):
self._miktResetLoginFlags()
if Status == 0:
Domoticz.Log('Mikrotik connected. Login...')
self.miktConn.Send(sentence_pack(['/login', '.tag=initial_login']))
else:
Domoticz.Error("Mikrotik connection error. Status [%s] [%s]" % (Status, Description))
def onMessage(self, Connection, Data):
try:
self.miktUnpacker.feed(Data)
for sentence in self.miktUnpacker:
reply, tag, words = SentenceParser.parse_sentence(sentence)
if tag == 'initial_login' and reply == '!done':
self.miktConn.Send(sentence_pack([
'/login',
'=name=%s' % Parameters['Username'],
'=password=%s' % Parameters['Password'],
'.tag=authorize'
]))
elif tag == 'authorize' and reply == '!done' and not self.miktAuthError:
Domoticz.Log('Mikrotik logged in successfully')
self.miktLoggedIn = True
if Parameters['Mode3']:
self._miktCommand([
'/interface/listen',
'=.proplist=.id,name,running,disabled',
'?name=%s' % Parameters['Mode3'],
'.tag=interface_status_update'
])
self._miktCommand([
'/interface/print',
'=.proplist=.id,name,running,disabled',
'?name=%s' % Parameters['Mode3'],
'.tag=interface_status'
])
elif tag in ('interface_status', 'interface_status_update') and reply == '!re':
if not self.statusInterfaceId:
self.statusInterfaceId = words.get('.id', None)
if words.get('running', None) is not None:
self.statusRunning = words.get('running')
if words.get('disabled', None) is not None:
self.statusDisabled = words.get('disabled')
if self.statusRunning:
UpdateDevice(self.statusUnit, 1, '10', ShowInLog=True)
elif self.statusDisabled:
UpdateDevice(self.statusUnit, 0, '0', ShowInLog=True)
else:
UpdateDevice(self.statusUnit, 1, '20', ShowInLog=True)
elif tag == 'bw' and reply == '!re':
rx_bits = words.get('rx-bits-per-second', 0)
tx_bits = words.get('tx-bits-per-second', 0)
UpdateDevice(self.bwDownUnit, 1, str(bitToMbyte(rx_bits)), interface=words.get('.interface'))
UpdateDevice(self.bwUpUnit, 1, str(bitToMbyte(tx_bits)), interface=words.get('.interface'))
self.totalTrafficToday['rx'] += rx_bits
self.totalTrafficToday['tx'] += tx_bits
total_traffic = self.totalTrafficToday['rx'] + self.totalTrafficToday['tx']
UpdateDevice(self.totalTrafficUnit, 1, str(bitToMbyte(total_traffic)))
# Update daily download and upload traffic
UpdateDevice(self.dailyDownloadUnit, 1, str(bitToMbyte(self.totalTrafficToday['rx'])))
UpdateDevice(self.dailyUploadUnit, 1, str(bitToMbyte(self.totalTrafficToday['tx'])))
elif tag == 'authorize' and reply == '!trap':
self.miktAuthError = True
Domoticz.Error('Mikrotik login error [%s]' % words.get('message', None))
elif reply in ('!fatal', '!trap'):
Domoticz.Error(
'Mikrotik error. Reply [%s]. Message [%s]. Tag [%s].' % (
reply, words.get('message', None), tag))
except UnpackerException as e:
Domoticz.Error('UnpackerException [%s]' % str(e))
except ParseException as e:
Domoticz.Error('ParseException [%s]' % str(e))
def onCommand(self, Unit, Command, Level, Hue):
if self.statusUnit == Unit:
if self.statusInterfaceId is None:
Domoticz.Error('No interface ID')
return
if self.statusDisabled is None or self.statusRunning is None:
Domoticz.Error('No current interface status')
return
# disable
if Level == 0 and not self.statusDisabled:
self._miktChangeInterfaceStatus(disabled=True)
# run
elif Level == 10 and not self.statusRunning:
self._miktChangeInterfaceStatus(disabled=True)
self._miktChangeInterfaceStatus(disabled=False)
# enable
elif Level == 20 and self.statusDisabled and not self.statusRunning:
self._miktChangeInterfaceStatus(disabled=False)
def onDisconnect(self, Connection):
self._miktResetLoginFlags()
def onHeartbeat(self):
if not self.miktConn.Connected() and not self.miktConn.Connecting():
Domoticz.Log('Mikrotik re-connecting...')
self.miktConn.Connect()
else:
self._miktCommand([
'/interface/monitor-traffic',
'=interface=%s' % Parameters['Mode2'],
'=once=yes',
'=.proplist=rx-bits-per-second,tx-bits-per-second',
'.tag=bw'
])
# Reset daily traffic counters at the beginning of each day
if self.isNewDay():
self.totalTrafficToday['rx'] = 0
self.totalTrafficToday['tx'] = 0
def _miktCommand(self, words_list):
if self.miktLoggedIn and self.miktConn.Connected():
try:
self.miktConn.Send(sentence_pack(words_list))
except PackException as e:
Domoticz.Error('PackException [%s]' % str(e))
def _miktChangeInterfaceStatus(self, disabled):
self._miktCommand([
'/interface/set',
'=disabled=%s' % ('yes' if disabled else 'no'),
'=.id=%s' % self.statusInterfaceId,
'.tag=interface_set'
])
def _miktResetLoginFlags(self):
self.miktAuthError = False
self.miktLoggedIn = False
def bitToMbyte(value):
return math.ceil(value / (8 * 10 ** 6) * 100) / 100
def UpdateDevice(Unit, nValue, sValue, AlwaysUpdate=False, ShowInLog=False, interface=None):
if interface:
unitKey = (Unit, interface)
else:
unitKey = Unit
if unitKey not in Devices:
return
if Devices[unitKey].nValue != nValue or Devices[unitKey].sValue != sValue or AlwaysUpdate:
Devices[unitKey].Update(nValue, str(sValue))
if ShowInLog:
Domoticz.Log("%s: nValue %s - sValue %s" % (
Devices[unitKey].Name,
nValue,
sValue
))
global _plugin
_plugin = BasePlugin()
def onStart():
global _plugin
_plugin.onStart()
def onStop():
global _plugin
_plugin.onStop()
def onConnect(Connection, Status, Description):
global _plugin
_plugin.onConnect(Connection, Status, Description)
def onMessage(Connection, Data):
global _plugin
_plugin.onMessage(Connection, Data)
def onCommand(Unit, Command, Level, Hue):
global _plugin
_plugin.onCommand(Unit, Command, Level, Hue)
def onDisconnect(Connection):
global _plugin
_plugin.onDisconnect(Connection)
def onHeartbeat():
global _plugin
_plugin.onHeartbeat()
def DumpConfigToLog():
for x in Parameters:
if Parameters[x] != "":
Domoticz.Debug("'" + x + "':'" + str(Parameters[x]) + "'")
Domoticz.Debug("Device count: " + str(len(Devices)))
for x in Devices:
Domoticz.Debug("Device: " + str(x) + " - " + str(Devices[x]))
Domoticz.Debug("Device ID: '" + str(Devices[x].ID) + "'")
Domoticz.Debug("Device Name: '" + Devices[x].Name + "'")
Domoticz.Debug("Device nValue: " + str(Devices[x].nValue))
Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
return
I added a few more metrics, Total daliy traffic, total daily upload and total daily download.
I'm sorry i put here the code but I can't open PR.
import Domoticz
import math
import os
import sys
module_paths = [x[0] for x in os.walk(os.path.join(os.path.dirname(file), '.', '.env/lib/')) if x[0].endswith('site-packages')]
for mp in module_paths:
sys.path.append(mp)
from miktapi.sentence import sentence_pack, SentenceUnpacker
from miktapi.helper import SentenceParser
from miktapi.exceptions import UnpackerException, ParseException, PackException
class BasePlugin:
bwOptions = {"Custom": "1;Mbit/s"}
iconName = 'mikrotik-routeros-winbox'
bwUpUnit = 1
bwDownUnit = 2
statusUnit = 3
totalTrafficUnit = 4
dailyDownloadUnit = 5
dailyUploadUnit = 6
def bitToMbyte(value):
return math.ceil(value / (8 * 10 ** 6) * 100) / 100
def UpdateDevice(Unit, nValue, sValue, AlwaysUpdate=False, ShowInLog=False, interface=None):
if interface:
unitKey = (Unit, interface)
else:
unitKey = Unit
global _plugin
_plugin = BasePlugin()
def onStart():
global _plugin
_plugin.onStart()
def onStop():
global _plugin
_plugin.onStop()
def onConnect(Connection, Status, Description):
global _plugin
_plugin.onConnect(Connection, Status, Description)
def onMessage(Connection, Data):
global _plugin
_plugin.onMessage(Connection, Data)
def onCommand(Unit, Command, Level, Hue):
global _plugin
_plugin.onCommand(Unit, Command, Level, Hue)
def onDisconnect(Connection):
global _plugin
_plugin.onDisconnect(Connection)
def onHeartbeat():
global _plugin
_plugin.onHeartbeat()
def DumpConfigToLog():
for x in Parameters:
if Parameters[x] != "":
Domoticz.Debug("'" + x + "':'" + str(Parameters[x]) + "'")
Domoticz.Debug("Device count: " + str(len(Devices)))
for x in Devices:
Domoticz.Debug("Device: " + str(x) + " - " + str(Devices[x]))
Domoticz.Debug("Device ID: '" + str(Devices[x].ID) + "'")
Domoticz.Debug("Device Name: '" + Devices[x].Name + "'")
Domoticz.Debug("Device nValue: " + str(Devices[x].nValue))
Domoticz.Debug("Device sValue: '" + Devices[x].sValue + "'")
Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
return