import asyncdispatch, tables, times, options, tables import ../types, ../vars, ../modbus, ../influx, ../utils proc updatePowermeter (key: string, device: DeviceConfig) {.async.} = let deviceAddress = device.address.get let currentTimestamp = toUnix(getTime()) let voltage = (await mb.asyncReadFloat(deviceAddress, 0)).isaRound(3) let current = (await mb.asyncReadFloat(deviceAddress, 6)).isaRound(3) let frequency = (await mb.asyncReadFloat(deviceAddress, 70)).isaRound(3) let `import` = (await mb.asyncReadFloat(deviceAddress, 72)).isaRound(3) let cosphi = (await mb.asyncReadFloat(deviceAddress, 30)).isaRound(3) let power = (await mb.asyncReadFloat(deviceAddress, 12)).isaRound(3) if server.config.serverConfig.influx.isSome: let config = server.config.serverConfig.influx.get if config.powermetersDatabase.isSome: if server.state[key].lastUpdated.isSome: if (currentTimestamp - server.state[key].lastUpdated.get) < 30: break var tags, fields = initTable[string, string]() tags["device"] = key fields["voltage"] = $voltage fields["current"] = $current fields["frequency"] = $frequency fields["import"] = $`import` fields["cosphi"] = $cosphi fields["power"] = $power discard await config.insertDatabase(config.powermetersDatabase.get, key, tags, fields, currentTimestamp * 1000000000) server.state[key].voltage = voltage server.state[key].frequency = frequency server.state[key].`import` = `import` server.state[key].cosphi = cosphi server.state[key].power = power server.state[key].lastUpdated = some(currentTimestamp) broadcastServerState() proc updatePowermeters () {.async.} = for key, device in server.config.devices.pairs(): if device.type != PowerMeter: continue try: await updatePowermeter(key, device) except: echo "Error[updatePowermeters]:\n", getCurrentExceptionMsg() proc powermetersLoop () {.async.} = await sleepAsync(500) while true: await updatePowermeters() await sleepAsync(int(server.config.serverConfig.powermeterUpdateIntervalSec * 1000)) proc initModbusPowermeters* () = for key, device in server.config.devices.pairs(): if device.type != PowerMeter: continue server.state[key] = DeviceState(type: PowerMeter) asyncCheck powermetersLoop()