Pagina 1 van 1
python vraagje ?
Geplaatst: 06 dec 2017, 15:54
door broke23
heeft er iemand enig idee hoe ik een datum en tijd kan toevoegen in een file die ik probeer weg te schrijven ?
Code: Selecteer alles
file = open("/run/shm/em-"+format(serial)+"-"+format(value), "a")
file.write('%.4f' % emparts[value])
file.close()
geeft als output een waarde van mijn energiemeter, nu die energiemeter struurt geen datum en tijd mee ...
had iets geprobeerd in de zin van :
Code: Selecteer alles
file = open("/run/shm/em-"+format(serial)+"-"+format(value), "a")
file.write('{%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())+'%.4f' "\n" % emparts[value])
file.close()
maar dan schrijft het geen data meer weg,
ik zou een verwijzing ofzo kunnen definiëren maar heb echt geen idee, ik probeer de code te manipuleren naar eigen noden, maar zonder succes dus (paar dingen toch al gelukt, maar meer ook niet)
origineel komt van hier:
https://github.com/datenschuft/SMA-EM/
Re: python vraagje ?
Geplaatst: 06 dec 2017, 16:02
door elmariachi2920
wat gebeurt er als je "\n" verwijderd?
als je datum en de waardes op verschillende lijnen wilt hebben kan je evt het volgende proberen:
Code: Selecteer alles
file = open("/run/shm/em-"+format(serial)+"-"+format(value), "a")
file.write('{%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now()))
file.write('%.4f' % emparts[value])
file.close()
Re: python vraagje ?
Geplaatst: 06 dec 2017, 16:03
door Didymus
Probeer eens met:
Code: Selecteer alles
file.write(str(datetime.datetime.now()) + " " + '%.4f' "\n" % + emparts[value])
edit: Of in het format dat je zelf wou:
Code: Selecteer alles
file.write(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + "%.4f" % + emparts[value])
Re: python vraagje ?
Geplaatst: 06 dec 2017, 16:10
door ubremoved_539
Je newline character staat op de verkeerde plaats.
Re: python vraagje ?
Geplaatst: 06 dec 2017, 16:21
door Didymus
Newline komt op de juiste plaats terecht, is volgens mij niet het probleem. Niet erg logisch/leesbaar, dat niet:
Code: Selecteer alles
In [151]: str(datetime.datetime.now()) + " " + '%.4f' "\n" % + 0.379234790345
Out[151]: '2017-12-06 16:20:38.731463 0.3792\n'
Re: python vraagje ?
Geplaatst: 06 dec 2017, 17:23
door brubbel
import datetime
dt = datetime.datetime.now()
strDate = dt.replace(tzinfo=None).strftime("%Y%m%d%H%M%S")
https://docs.python.org/2/library/datet ... e-behavior
Re: python vraagje ?
Geplaatst: 06 dec 2017, 18:20
door broke23
Didymus schreef:Probeer eens met:
Code: Selecteer alles
file.write(str(datetime.datetime.now()) + " " + '%.4f' "\n" % + emparts[value])
edit: Of in het format dat je zelf wou:
Code: Selecteer alles
file.write(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + "%.4f" % + emparts[value])
Code: Selecteer alles
File "sma-daemon.py", line 49
file.write(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + '%.4f' + % emparts[value])
^
SyntaxError: invalid syntax
Zelfde met of zonder "\n"
Re: python vraagje ?
Geplaatst: 06 dec 2017, 18:49
door Didymus
Als je dit wil debuggen ga je best systematisch te werk:
Code: Selecteer alles
In [3]: datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
Out[3]: '2017-12-06 18:43:17'
In [4]: datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " "
Out[4]: '2017-12-06 18:43:24 '
In [5]: datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + '%.4f' 0.83039434
File "<ipython-input-5-081ef786934f>", line 1
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + '%.4f' 0.83039434
^
SyntaxError: invalid syntax
In [6]: datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + '%.4f' % 8.3983
Out[6]: '2017-12-06 18:43:55 8.3983'
In [7]: datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + '%.4f' % 8.3983 + "\n"
Out[7]: '2017-12-06 18:46:02 8.3983\n'
Probleem is de positie van je %-teken dat na de + operator staat en daar geen betekenis heeft. Vervang gewoon de dummyvalue in mijn bv. door emparts[value]
Re: python vraagje ?
Geplaatst: 06 dec 2017, 19:43
door gm123
De properste manier om strings aan elkaar te zetten in python is als volgt.
Code: Selecteer alles
from datetime import datetime
tijd = datetime.now().strftime("%Y-%m-%d %H:%M");
value = 14.5
string = "%s - %.4f \n" % (tijd, value)
print(string)
Het resultaat hiervan is:
Je definieert eerst het formaat van de string en je vult hem dan op. %s wordt gesubstitueerd door de string
tijd en %.4f wordt gesubstitueerd door het kommagetal
value. De volgorde van de substitutie is van links naar rechts, vandaar dat we (tijd, value) schrijven en niet (value, tijd) in dit voorbeeld. Verder kan je hier in schrijven wat je wil, je kan er ook iets van maken zoals
Code: Selecteer alles
string = "Op tijdstip %s verbruikte ik %.4f W \n" % (tijd, value)
In de variabele
value steek je de waarde afkomstig van je energiemeter. In de variabele
string zit vervolgens wat je moet wegschrijven naar je bestand. Enkel nog maar file.write(string) doen en klaar.
Als je niet zeker bent hoe het werkt gebruik je best altijd tussenvariabelen, dan kan je stap per stap debuggen indien je ergens een fout hebt. Het voorbeeld van hierboven is nu niet zo ingewikkeld, dus je kan ook evengoed het volgende schrijven (er vanuitgaande dat er een waarde in de variabele
value zit), maar tussenvariabelen maken de boel direct een pak leesbaarder.
Code: Selecteer alles
file.write("%s - %.4f \n" % (datetime.now().strftime("%Y-%m-%d %H:%M"), value))
Re: python vraagje ?
Geplaatst: 06 dec 2017, 20:10
door broke23
@gm123 en de rest
ik krijg alvast geen fouten meer met je laatste code gm123, maar de output geeft enkel de waarde van de energiemeter weer, dus GEEN datum EN de append modus valt precies weg met deze aanpassingen ?
Alvast bedankt voor de hulp, maar ik geraak er dus niet uit
Re: python vraagje ?
Geplaatst: 06 dec 2017, 20:14
door gm123
En als je mijn eerste voorbeeld uitvoert, met gewoon die print? Krijg je dan wel een datum te zien? Print eens gewoon al je tussenvariabelen uit en kijk dan wat er misloopt. Schrijven naar een bestand doe je als allerlaatste, eerst debuggen met prints in de console. Zeker dat de waarde van je energiemeter een getal is?
De volgende code werkt hier:
Code: Selecteer alles
from datetime import datetime
tijd = datetime.now().strftime("%Y-%m-%d %H:%M");
value = 14.5
string = "%s - %.4f \n" % (tijd, value)
f = open('test.txt', 'a+')
f.write(string)
f.close()
Resultaat na 4x uitvoeren:
Re: python vraagje ?
Geplaatst: 06 dec 2017, 20:27
door broke23
de waarde is idd een getal (met cijfers achter de komma)
dus als het werkt, print het altijd dat getal met cijfers achter de komma, maar niet meerdere onder elkaar dus
met je 1e voorbeeld:
Code: Selecteer alles
Traceback (most recent call last):
File "sma-daemon.py", line 29, in <module>
string = "%s - %.4f \n" % (tijd, value)
TypeError: a float is required
Re: python vraagje ?
Geplaatst: 06 dec 2017, 20:33
door gm123
broke23 schreef:
de waarde is idd een getal (met cijfers achter de komma)
Blijkbaar niet! De error die je krijgt zegt letterlijk "a float is required". Hij verwacht dus dat 1 van je variabelen een float is. Er zit maar 1 float in die string, namelijk %.4f, wat wil zeggen dat je in de variabele
value geen float hebt steken. Zeker dat je waarde geen kommagetal in de vorm van een string is?
Je kan het volgende proberen:
Of indien het toch een string is:
Maar het beste is misschien om het met format doen zoals je in jouw code al had geprobeerd. Dan heb je dat probleem niet met de types van je variabelen niet, python plakt dan automatisch het juiste type er in. Ik had het van in het begin ook zo moeten doen eigenlijk. Aangezien dit de 'nieuwe' manier is, de mijne is nog de 'oude'.
Re: python vraagje ?
Geplaatst: 06 dec 2017, 20:55
door broke23
Code: Selecteer alles
ValueError: could not convert string to float: 'emparts[value]'
dus ja, het zal dan een string zijn zeker
het is een berekend getal: pregardcounter=hex2dec(smainfoasci[80:96])/3600000
soit, ik blijf proberen
Re: python vraagje ?
Geplaatst: 06 dec 2017, 20:58
door gm123
Dan zou mijn laatste stukje code wel moeten werken. Dat plakt gewoon de waarde van tijd en value integraal in de string op de plaats waar {} staat, python zorgt zelf voor de correcte typecasting. Ik zie dat je in jouw code ook de variabele 'value' gebruikt voor iets anders, die hergebruik je toch niet he? Want ik noem die variabele ook toevallig 'value' in mijn voorbeeldje, dat zijn 2 verschillende dingen natuurlijk.
Als het dan toch nog niet werkt dan zit er in je waarde afkomstig uit de meter toch echt wel iets meer dan gewoon een getal.
Re: python vraagje ?
Geplaatst: 06 dec 2017, 21:10
door broke23
daarom dat ik dus nooit geen informatica ben gaan studeren hé, die kunde, of hoe dat ik het moet noemen, om te programmeren is er gewoon niet
Code: Selecteer alles
import sys, time
from datetime import datetime
from daemon3x import daemon3x
from configparser import SafeConfigParser
import smaem
tijd = datetime.now().strftime("%Y-%m-%d %H:%M:%S");
waarde = 'emparts[value]'
string = "{} - {} \n".format(tijd, waarde)
#read configuration
parser = SafeConfigParser()
parser.read('/etc/smaemd/config')
smaemserials=parser.get('SMA-EM', 'serials')
serials=smaemserials.split(' ')
smavalues=parser.get('SMA-EM', 'values')
values=smavalues.split(' ')
pidfile=parser.get('DAEMON', 'pidfile')
class MyDaemon(daemon3x):
def run(self):
emparts = {}
while True:
emparts=smaem.readem()
for serial in serials:
#print(serial)
#print(emparts['serial'])
if serial==format(emparts['serial']):
#print("match")
for value in values:
file = open("/run/shm/em-"+format(serial)+"-"+format(value),"a")
file.write(string)
file.close()
Dat heb ik er nu van gemaakt en dat logt dan als volgt:
Code: Selecteer alles
2017-12-06 21:06:59 - emparts[value]
2017-12-06 21:06:59 - emparts[value]
2017-12-06 21:06:59 - emparts[value]
dus het werkt inderdaad wel, maar ben toch ergens de mist in gegaan, want nu krijg ik dus mijn data van de energiemeter niet meer te zien (waarschijnlijk omdat ik mijn string ergens te vroeg invoeg ?) en dat tijdstip staat fixed precies ? dat loopt niet op ? (almost there denk ik ze)
denk niet dat je gezien hebt dat ik de waarde gepost heb hierboven :
Re: python vraagje ?
Geplaatst: 06 dec 2017, 21:24
door gm123
Dat is niet je volledige code veronderstel ik? Maar ik denk dat ik het zie.
Allereerst vervang
door
In het eerste geval plak je letterlijk de woorden 'emparts[value]' in je string. Je wil natuurlijk de waarde uit de variabele emparts[value] opvragen, dit doe je zonder quotes. Als je nog zo'n basic fouten maakt raad ik je aan om toch eerst nog wat python tutorials te volgen alvorens je dit soort projectjes doet, daar hoef je zeker niet voor gestudeerd te hebben, er zijn op internet genoeg tutorials voor beginners te vinden die een overzicht van alle basis geven. Niet slecht bedoeld hé, maar dit is echt de basis van de basis en je moet toch wel een beetje weten wat je aan het doen bent.
Vervolgens kan je tijd, waarde en string pas definiëren op de plaats in je code waar je effectief de meetwaarde uitleest, dit is net boven de plaats waar je file.write() doet. Als ik het goed heb moet het dus zo zijn.
Code: Selecteer alles
import sys, time
from datetime import datetime
from daemon3x import daemon3x
from configparser import SafeConfigParser
import smaem
#read configuration
parser = SafeConfigParser()
parser.read('/etc/smaemd/config')
smaemserials=parser.get('SMA-EM', 'serials')
serials=smaemserials.split(' ')
smavalues=parser.get('SMA-EM', 'values')
values=smavalues.split(' ')
pidfile=parser.get('DAEMON', 'pidfile')
class MyDaemon(daemon3x):
def run(self):
emparts = {}
while True:
emparts=smaem.readem()
for serial in serials:
#print(serial)
#print(emparts['serial'])
if serial==format(emparts['serial']):
#print("match")
for value in values:
file = open("/run/shm/em-"+format(serial)+"-"+format(value),"a")
tijd = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
waarde = emparts[value]
string = "{} - {} \n".format(tijd, waarde)
file.write(string)
file.close()
Re: python vraagje ?
Geplaatst: 06 dec 2017, 21:33
door broke23
HALLELUJA
dikke merci gm123!!!!
Code: Selecteer alles
2017-12-06 21:32:20 - 203.6328
2017-12-06 21:32:21 - 203.6329
2017-12-06 21:32:22 - 203.6329
2017-12-06 21:32:23 - 203.633
2017-12-06 21:32:24 - 203.6331
2017-12-06 21:32:25 - 203.6332
2017-12-06 21:32:26 - 203.6333
2017-12-06 21:32:27 - 203.6334
Hen specifiek gezocht naar info van wat ik nodig had maar denk dat ik te vaak of foute terminologie gezocht heb
Re: python vraagje ?
Geplaatst: 07 dec 2017, 17:16
door fujiwara
Die orginele code ziet er niet echt proper geschreven uit moet ik zeggen. Welke versie van Python wordt er hier gebruikt trouwens?
Met wat aanpassingen kan het een stuk duidelijker geschreven worden:
Code: Selecteer alles
import sys, time
from datetime import datetime
from daemon3x import daemon3x
from configparser import ConfigParser
import smaem
CONFIG_FILE_PATH = '/etc/smaemd/config'
def read_config(config_file_path):
#read configuration
parser = ConfigParser()
parser.read('/etc/smaemd/config')
smaemserials=parser.get('SMA-EM', 'serials')
serials=smaemserials.split(' ')
smavalues=parser.get('SMA-EM', 'values')
values=smavalues.split(' ')
pidfile=parser.get('DAEMON', 'pidfile')
return (pidfile, serials, values)
class MyDaemon(daemon3x):
def __init__(self, pid_file, sma_serials, sma_value_types):
super(MyDaemon, self).__init__(pid_file)
self.sma_serials = sma_serials
self.sma_value_types = sma_value_types
def run(self):
while True:
# Read the emparts & get the current time since that is the timestamp of the data
emparts = smaem.readem()
now = datetime.now()
# Only write the data if it has the requested serial
sma_serial = str(emparts.get('serial'))
if sma_serial in self.sma_serials:
for sma_value_type in self.sma_value_types:
with open("/run/shm/em-{}-{}".format(sma_serial, sma_value_type),"a") as fh:
fh.write("{:%Y-%m-%d %H:%M:%S} - {}\n".format(now, emparts.get(sma_value_type, "NA")))
if __name__ == "__main__":
pidfile, serials, values = read_config(CONFIG_FILE_PATH)
daemon = MyDaemon(pidfile, serials, values)
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
else:
print ("Unknown command")
sys.exit(2)
sys.exit(0)
else:
print("usage: %s start|stop|restart" % sys.argv[0])
print(pidfile)
sys.exit(2)
Code: Selecteer alles
sma_serial = str(emparts.get('serial'))
if sma_serial in self.sma_serials:
...
De serial die je krijgt is in integer formaat. De normale manier om deze om te zetten in een string is de 'str()' functie te gebruiken. Snap niet waarom ze format() gebruiken zonder een format specifier dan nog.
Daarnaast gebruik je best de get() functie om de waardes uit de dict te lezen. Dit voorkomt dat je KeyError exception kan krijgen moest er iets ontbreken in de uitgelezen data.
Vermits er enkel wordt gekeken of de serial van de uitgeleesde data in de geconfigureerde serials zit, kan beter de 'in' constructie gebruikt worden.
Code: Selecteer alles
"{:%Y-%m-%d %H:%M:%S} - {}\n".format(now, emparts.get(sma_value_type, "NA"))
Je kan met de format functie rechtstreeks de date formatting gebruiken. Het tweede argument van de get functie geeft je een default waarde terug indien de key niet in de dict wordt gevonden.
Code: Selecteer alles
with open("/run/shm/em-{}-{}".format(sma_serial, sma_value_type),"a") as fh:
...
Ook wordt het beste de 'with' constructie gebruikt om bestanden te openen. Dit zorgt ervoor dat de file altijd gesloten wordt ook in het geval van exceptions. Deze functie is wel niet in alle Python versies beschikbaar.
PS. Deze code is niet getest dus kan nog fouten bevatten
Re: python vraagje ?
Geplaatst: 21 dec 2017, 13:09
door broke23
@fujiwara, je code net even getest omdat ik wat aan het prullen was om iets nieuw te implementeren, en je code werkt
nu nog uitvogelen hoe ik de creatie van die file limiteer per dag