• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[GELÖST] Python to Javascript

Landix

New member
Hallo,
mein Name ist Andreas,
ich suche Jemanden der mir ein Python file zu Javascript umbaut, wenn das überhaupt mit meinem Code möglich ist.

Was ich bis jetzt habe:

Code:
#!/usr/bin/env python
import time
import pigpio
import json
class reader:
   """
A class to read speedometer pulses and calculate the RPM.
"""
   def __init__(self, pi, gpio, pulses_per_rev=1.0, weighting=0, min_RPM=5):
      """
  Instantiate with the Pi and gpio of the RPM signal
  to monitor.
 
  Optionally the number of pulses for a complete revolution
  may be specified.  It defaults to 1.
 
  Optionally a weighting may be specified.  This is a number
  between 0 and 1 and indicates how much the old reading
  affects the new reading.  It defaults to 0 which means
  the old reading has no effect.  This may be used to
  smooth the data.
 
  Optionally the minimum RPM may be specified.  This is a
  number between 1 and 1000.  It defaults to 5.  An RPM
  less than the minimum RPM returns 0.0.
  """
      self.pi = pi
      self.gpio = gpio
      self.pulses_per_rev = pulses_per_rev
 
      if min_RPM > 1000:
         min_RPM = 1000
      elif min_RPM < 1:
         min_RPM = 1
 
      self.min_RPM = min_RPM
 
      self._watchdog = 200 # Milliseconds.
 
      if weighting < 0:
         weighting = 0
      elif weighting > 0:
         weighting = 0
 
      self._new = 1 - weighting # Weighting for new reading.
      self._old = weighting       # Weighting for old reading.
 
      self._high_tick = None
      self._period = None
 
      pi.set_mode(gpio, pigpio.INPUT)
 
      self._cb = pi.callback(gpio, pigpio.RISING_EDGE, self._cbf)
      pi.set_watchdog(gpio, self._watchdog)
 
   def _cbf(self, gpio, level, tick):
 
      if level == 1: # Rising edge.
 
         if self._high_tick is not None:
            t = pigpio.tickDiff(self._high_tick, tick)
 
            if self._period is not None:
               self._period = (self._old * self._period) + (self._new * t)
            else:
               self._period = t
 
         self._high_tick = tick
 
      elif level == 2: # Watchdog timeout.
 
         if self._period is not None:
            if self._period < 2000000000:
               self._period += (self._watchdog * 1000)
 
   def RPM(self):
      """
  Returns the RPM.
  """
      RPM = 0
      if self._period is not None:
         RPM = 60000000 / (self._period * self.pulses_per_rev)
         if RPM < self.min_RPM:
            RPM = 0
 
      return RPM
 
   def cancel(self):
      """
  Cancels the reader and releases resources.
  """
      self.pi.set_watchdog(self.gpio, 0) # cancel watchdog
      self._cb.cancel()
 
if __name__ == "__main__":
 
   import time
   import pigpio
   import readRPM
   import RPi.GPIO as GPIO
 
   GPIO.setmode(GPIO.BCM)
   GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_UP)
   GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
   count = 5
   RPM_GPIO = 4
   RUN_TIME = 9600.0
   SAMPLE_TIME = 1.0
   RPM_LOWER_LIMIT = 20
   RPM_HIGHER_LIMIT = 120
   LEVEL_TO_POWER = {
    1: [6,12,20,29,40,53,69,79,92,106,121],
    2: [8,16,26,38,53,68,88,103,120,138,152],
    3: [9,20,32,47,66,84,107,125,148,172,186],
    4: [11,23,39,56,79,101,126,150,173,206,219],
    5: [13,27,45,65,92,117,145,175,202,238,254],
    6: [15,31,52,75,105,135,166,202,231,275,289],
    7: [16,35,58,85,118,152,185,226,260,305,332],
    8: [18,39,65,96,131,169,208,249,289,333,375],
    9: [19,42,71,104,144,184,227,272,318,361,408],
    10:[21,46,77,113,157,199,245,295,345,386,442],
    11:[23,50,84,123,170,216,262,318,372,413,480],
    12:[24,53,89,131,183,230,279,342,398,441,512],
    13:[26,56,94,139,196,245,296,365,424,468,548],
    14:[28,60,101,148,209,261,318,389,449,494,585],
    15:[30,64,108,158,222,277,337,415,476,518,620],
    16:[32,68,115,168,235,296,355,439,503,548,658],
    17:[33,72,122,177,248,312,373,463,530,576,694],
    18:[35,76,129,187,261,328,390,484,556,606,727],
    19:[37,79,134,195,274,342,407,507,572,632,763],
    20:[39,83,140,204,287,354,424,528,598,659,790],
    21:[40,87,146,213,300,368,442,551,616,689,812],
    22:[42,91,153,223,313,385,461,574,645,720,840],
    23:[44,95,160,234,326,401,479,598,673,752,872],
    24:[47,101,171,246,340,418,501,625,706,788,908],
    }
 
   def calculate_power(LEVEL, RPM):
       
    if RPM <= RPM_LOWER_LIMIT:
        return 0
    if RPM >= RPM_HIGHER_LIMIT:
    return 0
    return LEVEL_TO_POWER[LEVEL][(RPM) //10]
   
 
 
   def main():
    for LEVEL, RPM in [(1, 6), (2, 8), (3, 9)]:
     print(calculate_power(LEVEL, RPM))
   
   pi = pigpio.pi()
 
   p = readRPM.reader(pi, RPM_GPIO)
 
   start = time.time()
 
   while (time.time() - start) < RUN_TIME:
   
    input_state = GPIO.input(20)
    if input_state == False:
        if count < 24:
         count = count + 1
         RPM = (int(RPM+1))
         LEVEL = count
         print('Power',calculate_power(LEVEL, RPM),'Level', count, 'RPM={}'.format(int(RPM+1)))
         print(calculate_power(LEVEL, RPM))
         time.sleep(SAMPLE_TIME)
   
    input_state = GPIO.input(21)
    if input_state == False:
        if count > 1:
         count = count - 1
         RPM = (int(RPM+1))
         LEVEL = count
         print('Power',calculate_power(LEVEL, RPM),'Level', count, 'RPM={}'.format(int(RPM+1)))
     time.sleep(SAMPLE_TIME)
 
   
    LEVEL = count
    RPM = p.RPM()
    RPM = (int(RPM+1))
    time.sleep(SAMPLE_TIME)
    print('Power',calculate_power(LEVEL, RPM),'Level', count, "RPM={}".format(int(RPM+1)))    
 
   p.cancel()
   pi.stop()
 
 
 
 
 
if __name__ == '__main__':
    main()

Am Ende müssen noch dazu:

Code:
var power_meter = require('./power-meter');
var pm = new power_meter.PowerMeter();

function a() {
  var power_instant = calculate_power(LEVEL, RPM);
  var cadence = RPM={}".format(int(RPM+1));
  pm.broadcast(power_instant, cadence);
  setTimeout(a, 249);
}

a();

Ist das möglich? Wäre mir auch ein paar Taler Wert.
Und vor allem! Bin ich hier im richtigem Forum? :)

Das Programm soll eine Erweiterung von hier werden:
https://github.com/olympum/ant-cycling-power
 
Zuletzt bearbeitet von einem Moderator:
Ist das möglich?
ich würde mal sagen ja.
https://www.npmjs.com/package/rpi-gpio#listen-for-changes-on-a-pin
die frage dürfte sein, kannst du jemanden begeistern das umzusetzen.
soll das fürs rad oder für einen crosstrainer sein?
was willst du mit den daten machen?

soweit ich das sehe willst du nodejs auf dem pi nutzen um garmin/ant -sensoren auszulesen und die leistung berechnen.
da frage ich mich aber, wie willst du das ohne kraft messung machen? das geld für die vector sensoren sensoren willst du vermutlich nicht ausgeben.
 
ich würde mal sagen ja.
https://www.npmjs.com/package/rpi-gpio#listen-for-changes-on-a-pin
die frage dürfte sein, kannst du jemanden begeistern das umzusetzen.
soll das fürs rad oder für einen crosstrainer sein?
was willst du mit den daten machen?

soweit ich das sehe willst du nodejs auf dem pi nutzen um garmin/ant -sensoren auszulesen und die leistung berechnen.
da frage ich mich aber, wie willst du das ohne kraft messung machen? das geld für die vector sensoren sensoren willst du vermutlich nicht ausgeben.

Ist für einen Crosstrainer, die Leistungsdaten ergeben sich aus der Tabelle.
Power und Cadence werden dann übertragen und man kann in zwfit.com mit richtigen Daten fahren.
100€ kann ich dafür bezahlen, ist zwar nicht viel und werden sich die Profis auch nicht drauf melden, aber mehr habe ich dafür halt nicht.

Wollte das aber auch in den github zur verfügung stellen.
Ich dachte ich könnte das von python zu dem js übermitteln, aber das geht leider so nicht. Deswegen dachte ich mal hier zu fragen.

Vector Sensoren helfen beim Crosstrainer nicht :) sind auch Schwieneteuer.
 
Ist für einen Crosstrainer, die Leistungsdaten ergeben sich aus der Tabelle.
das level musst du dann aber fest vorgeben. das ändert sich ja aber meist über dem verlauf?

Ich dachte ich könnte das von python zu dem js übermitteln, aber das geht leider so nicht. Deswegen dachte ich mal hier zu fragen.
das blöde ist, das nodejs module nur in js und c geschrieben werden können, sonst wäre das überhaupt kein problem.
du kannst aber mit node aber auch python scripte als child prozesse laufen lassen

Vector Sensoren helfen beim Crosstrainer nicht :) sind auch Schwieneteuer.
ja, das sind sie


was ist denn dein input? ant-sensoren können es ja eigentlich auch nicht sein, wenn du gpios ausliest?

eigentlich sollte das mit https://www.npmjs.com/package/rpi-gpio doch recht einfach funktionieren.
über on 'change' meldest du dich auf änderungen des gpios an, misst die zeit und berechnest die rpm
 
das level musst du dann aber fest vorgeben. das ändert sich ja aber meist über dem verlauf?

Ich gebe am Start den Level vor In meinem Beispiel 5. Die Level + - Taster des Crosstrainers sind nach außen geführt und an die GPIO Ports vom Raspberry PI angeschlossen :)

das blöde ist, das nodejs module nur in js und c geschrieben werden können, sonst wäre das überhaupt kein problem.
du kannst aber mit node aber auch python scripte als child prozesse laufen lassen
Hö? Mein problem ist ja meine grenzenlose Programmierresitenz, das Python ist jetzt auch nicht die optimale Lösung und auch mehr durch fragen zusammen geschustert, aber er macht eine passende Ausgabe :)

was ist denn dein input? ant-sensoren können es ja eigentlich auch nicht sein, wenn du gpios ausliest?

eigentlich sollte das mit https://www.npmjs.com/package/rpi-gpio doch recht einfach funktionieren.
über on 'change' meldest du dich auf änderungen des gpios an, misst die zeit und berechnest die rpm

der Raspberry PI ist der Slave mit einem ANT+ Stick, der bekommt geliefert vom Crosstrainer die RPM (Reed Sensor an GPIO 4). Die Level kann ich auch schalten mit den Tastern die am Raspberry angeschlossen sind. Somit habe ich meine POWER Werte und RPM Werte. (Der jetzige Code halt)

Der ANT+ Stick ist als "Sender" konfiguriert und sendet an meine Windows Maschine wo ebenfalls ein ANT+ Stick als Master eingesteckt ist (Empfänger)
Dieser empfängt also die POWER und RPM(cadence) Daten. Somit könnte ich in Zwift radeln
 
ach ok, über einen ant usb stick willst du es dann an die uhr übertragen.
keine schlechte idee. fehlt nur noch wie den level rausbekommst.

- da haben sich deine antwort und meine überschnitten
 
Ich gebe am Start den Level vor In meinem Beispiel 5. Die Level + - Taster des Crosstrainers sind nach außen geführt und an die GPIO Ports vom Raspberry PI angeschlossen :)
ok, soweit würde ich zwar nicht gehen, aber funktioniert.
dann hast du doch aber bestimmt auch noch profile, die das level über die zeit ändern? oder nicht? bei mir stelle ich über +/- das "basislevel" ein
dann wähle ich ein profil welches z.b. mit basislevel 1: 9min level 1, dann 12 min level 3, dann wieder 9 min level 1 ist. erhöhe ich das basislevel auf 2 ändert sich das profil entsprechend also 9 min level 2, dann 12 min level 4, ...
aber das nur nebenbei

Mein problem ist ja meine grenzenlose Programmierresitenz, das Python ist jetzt auch nicht die optimale Lösung und auch mehr durch fragen zusammen geschustert, aber er macht eine passende Ausgabe :)
dann fang doch mal an, das in js zusammenzuschustern. fragen kannst du hier auch gerne.
 
ok, soweit würde ich zwar nicht gehen, aber funktioniert.
dann hast du doch aber bestimmt auch noch profile, die das level über die zeit ändern? oder nicht? bei mir stelle ich über +/- das "basislevel" ein
dann wähle ich ein profil welches z.b. mit basislevel 1: 9min level 1, dann 12 min level 3, dann wieder 9 min level 1 ist. erhöhe ich das basislevel auf 2 ändert sich das profil entsprechend also 9 min level 2, dann 12 min level 4, ...
aber das nur nebenbei

Man muss sich dann halt entscheiden: Nehm ich ein Workout vom Crosstrainer, oder ein Workout von zwift.

Du kannst ja entweder frei radeln, oder auch ein Workout machen, zum Beispiel Intervalle, dann musst du halt für mehr Leistung den Level (+ - drücken) erhöhen um auf das Trainingsziel zu kommen.
In beide Richtungen wäre zwar toll, aber wir wollen ja nicht gleich durchdrehen.

dann fang doch mal an, das in js zusammenzuschustern. fragen kannst du hier auch gerne.

Programmieren ist nix für mich, ich kann wohl ein wenig hier und da ändern, mehr aber auch nicht.

Neben Beruf und Familie schaffe ich es auch nicht mich darauf zu konzentrieren. Deswegen wollte ich den 100er auspacken dafür.
 
Neben Beruf und Familie schaffe ich es auch nicht mich darauf zu konzentrieren. Deswegen wollte ich den 100er auspacken dafür.
wenn das jemanden besonders interessieren würde / jemand lust darauf hätte, würde dir das hier auch jemand für lau machen.
meine lust hält sich in grenzen, da ich auch gerade viel zu tun habe.
warte einfach noch ein bis 2 tage, wenn sich dann keiner meldet, kannst du das ja mal unter Jobs anbieten.
 
Wobei mir gerade einfällt.
Wenn ich den Wert den ich brauche in eine Datei schreibe wo der Wert kontinuierlich upgedatet wird.

Dann kann ich doch mit Javascript diese Datei öffnen und den Wert auslesen?

Code:
var power_meter = require('./power-meter');
var pm = new power_meter.PowerMeter();

function a() {
  var power_instant = "Wert aus Datei";
  var cadence = "Wert aus anderer Datei";
  pm.broadcast(power_instant, cadence);
  setTimeout(a, 249);
}

a();

wobei der Wert ja auch immer aktualisiert ausgelesen werden muss.
 
Wobei mir gerade einfällt.
Wenn ich den Wert den ich brauche in eine Datei schreibe wo der Wert kontinuierlich upgedatet wird.
ja, das geht aber besser:
https://nodejs.org/api/child_process.html
und für python speziell:
https://github.com/extrabacon/python-shell#exchanging-data-between-node-and-python

wobei der Wert ja auch immer aktualisiert ausgelesen werden muss.
den gpio "aktualisiert" auszulesen ist auch nicht schwieriger
 
Oh das sieht ja gar nicht so schlecht aus, es langt ja die console auszulesen, ist ja nur nen Print.

Gedanklich würde ich das jetzt so denken:

Code:
var PythonShell = require('python-shell');
var options = {
  mode: 'text',
  pythonPath: 'path/to/python',
  pythonOptions: ['-u'],
  scriptPath: 'path/to/my/scripts',
  args: ['value1', 'value2']  // er liest Zeilenweise? Wert 1, Wert 2 also ddurch komma getrennt?
};
var power_meter = require('./power-meter');
var pm = new power_meter.PowerMeter();

PythonShell.run('7powerTX.py', options, function (err, results) {
  if (err) throw err;
  // results is an array consisting of messages collected during execution
  console.log('results: %j', results);
});

pyshell.on('message', function (message) {
  // received a message sent from the Python script (a simple "print" statement)
  console.log(message);



function a() {
  var power_instant = "value1";
  var cadence = "value2";
  pm.broadcast(power_instant, cadence);
  setTimeout(a, 249);
}

a();

Allerdings weiss ich nicht wie das Script jetzt nach unten zu value1 und value2 bekommt?
 
Gedanklich würde ich das jetzt so denken:
anstelle von
Code:
PythonShell.run('7powerTX.py', options, function (err, results) {
  if (err) throw err;
  // results is an array consisting of messages collected during execution
  console.log('results: %j', results);
});
das hier
Code:
var shell = new PythonShell('7powerTX.py', options);
shell.on('message', function (message) {
  // handle message (a line of text from stdout)
});

// er liest Zeilenweise? Wert 1, Wert 2 also ddurch komma getrennt?
zeilenweise???
durch komma getrennt, ja


Allerdings weiss ich nicht wie das Script jetzt nach unten zu value1 und value2 bekommt?
??? keine ahnung was du meinst.
über die options?
über send?
 
Oder geht das viel leichter?

Code:
var PythonShell = require('python-shell');
var pyshell = new PythonShell('7powerTX.py');

pyshell.on('message', function (message) {
  // received a message sent from the Python script (a simple "print" statement)
  console.log(message);
});

var power_meter = require('./power-meter');
var pm = new power_meter.PowerMeter();

function a() {
  var power_instant = message; // nur der Power Wert
//  var cadence = RPM={}".format(int(RPM+1));
  pm.broadcast(power_instant/*, cadence*/); //cadence mal raus genommen.
  setTimeout(a, 249);
}

a();

-- Schön wie sich das überschneidet :) Ich probier nachher mal :) danke schon mal.
 
Zuletzt bearbeitet:
in der callback function
Code:
function (message) {
  // received a message sent from the Python script (a simple "print" statement)
  console.log(message);
}
musst du dann die werte weiterverarbeiten
da muss also das aus deiner funktion a rein
 
Also für nur Power wäre das dann:

Code:
var PythonShell = require('python-shell');
var pyshell = new PythonShell('7powerTX.py');
var power_meter = require('./power-meter');
var pm = new power_meter.PowerMeter();

pyshell.on('message', function (message) {
  // received a message sent from the Python script (a simple "print" statement)
  //  console.log(message);

  var power_instant = message;
  pm.broadcast(power_instant);
  setTimeout(a, 249);
})
message();
 
Zuletzt bearbeitet:
ohne setTimeout(a, 249);
du musst außerdem sicherstellen, dass in dem python script außer den werten nichts nach stdout ausgegeben wird
 
Das bekomme ich hin. Danke.

- - - Aktualisiert - - -

nur noch ein Syntax Fehler:,
Code:
pi@carcam:~/ant-cycling-power $ node test.js
/home/pi/ant-cycling-power/test.js:13
message();
^

ReferenceError: message is not defined
    at Object.<anonymous> (/home/pi/ant-cycling-power/test.js:13:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:393:7)
    at startup (bootstrap_node.js:150:9)
    at bootstrap_node.js:508:3

Mein code:

Code:
var PythonShell = require('python-shell');
var pyshell = new PythonShell('8powerx.py');
var power_meter = require('./power-meter');
var pm = new power_meter.PowerMeter();

pyshell.on('message', function (message) {
  // received a message sent from the Python script (a simple "print" statement)
  //  console.log(message);

  var power_instant = message;
  pm.broadcast(power_instant);
})
message();
 
Zurück
Oben