Skip to content

Instantly share code, notes, and snippets.

@kdrag0n
Last active June 26, 2021 19:51
Show Gist options
  • Save kdrag0n/d087f09a7ff441f0acb204ab246c878d to your computer and use it in GitHub Desktop.
Save kdrag0n/d087f09a7ff441f0acb204ab246c878d to your computer and use it in GitHub Desktop.
An OPP power usage and EAS energy model calculator
#!/usr/bin/env python
#
# OPP Power Usage and EAS Energy Model Calculator
# by @kdrag0n
#
# This program is licensed under the MIT License (MIT)
#
# Copyright (c) 2019 Danny Lin <[email protected]>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
import sys
from enum import Enum
#######################
# CONSTANTS TO EDIT #
#######################
freq_l = [633600, 902400, 1113600, 1401600, 1536000, 1747200, 1843200]
mv_l = [320, 380, 460, 580, 640, 720, 760]
ma_l = [12, 23, 30, 40, 50, 55, 65]
freq_b = [1113600, 1401600, 1747200, 1958400, 2150400, 2208000]
mv_b = [460, 580, 720, 810, 890, 920]
ma_b = [75, 110, 155, 220, 285, 310]
###################################
# DO NOT EDIT BEYOND THIS POINT #
###################################
class Mode(Enum):
NORMAL = 1
CSV = 2
EAS = 3
# Calculate the power usage of a given OPP in mW
def calc_freq_mw(idx, mv_src, ma_src):
mv_opp = mv_src[idx] # Get the corresponding mV
ma_opp = ma_src[idx] # Get the corresponding mA
uw_final = mv_opp * ma_opp # mV * mA = uW
mw_final = uw_final / 1000 # uW / 1000 = mW
return mw_final
def format_eas_power(power_map, old_min, old_max):
if old_min and old_max:
new_min = calc_freq_mw(0, mv_l, ma_l)
new_max = calc_freq_mw(len(freq_b) - 1, mv_b, ma_b)
# Calculate normalization constants
factor = (old_max - old_min) / (new_max - new_min)
base = old_min - (factor * new_min)
for freq_khz, power in power_map.items():
# Normalize power to old EM's min and max
power = factor * power + base
power_map[freq_khz] = power
else:
for freq_khz, power in power_map.items():
# Scale it up for reduced precision loss
power *= 100
power_map[freq_khz] = power
# Print the power usage of each OPP
def print_opp_mw(freq_src, mv_src, ma_src, mode, eas_min, eas_max):
# { freq_khz: mW }
power_map = {}
# Calculate power consumption
for idx, freq_khz in enumerate(freq_src):
mw_final = calc_freq_mw(idx, mv_src, ma_src)
power_map[freq_khz] = mw_final
# Format power values for EM
if mode == Mode.EAS:
format_eas_power(power_map, eas_min, eas_max)
# Print CSV header
if mode == Mode.CSV:
print('Frequency,Power usage')
for freq_khz, power in power_map.items():
if mode == Mode.CSV: # CSV format
print('%d,%f' % (freq_khz, power))
elif mode == Mode.EAS: # EM format
print('%7d %.0f' % (freq_khz, power))
else: # Visual format
# Convert freq to MHz for readability
freq_mhz = freq_khz / 1000
idx = freq_src.index(freq_khz)
print('%6.1f MHz: %5.1f mW (%3d mV * %3d mA)' % (freq_mhz, power, mv_src[idx], ma_src[idx]))
def main():
mode = Mode.NORMAL
if len(sys.argv) > 1:
if sys.argv[1] == 'csv':
mode = Mode.CSV
elif sys.argv[1] == 'eas':
mode = Mode.EAS
# Parse EAS target min/max cost arguments
eas_min = 0
eas_max = 0
if mode == Mode.EAS and len(sys.argv) >= 3:
eas_min = int(sys.argv[2])
eas_max = int(sys.argv[3])
# Print stats for the little cluster
print('Little cluster:')
print_opp_mw(freq_l, mv_l, ma_l, mode, eas_min, eas_max)
# Print stats for the big cluster
print('\nBig cluster:')
print_opp_mw(freq_b, mv_b, ma_b, mode, eas_min, eas_max)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment