From e462673fec6d560fe86598234b860fa318757b70 Mon Sep 17 00:00:00 2001 From: smallsolar Date: Mon, 18 Dec 2023 09:23:49 +0000 Subject: [PATCH] first commit --- solar_bot.py | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 solar_bot.py diff --git a/solar_bot.py b/solar_bot.py new file mode 100644 index 0000000..69e133b --- /dev/null +++ b/solar_bot.py @@ -0,0 +1,94 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +# https://github.com/karioja/vedirect +# https://github.com/halcy/Mastodon.py +# Command: python3 solar_bot.py --port /dev/ttyUSB0 + +import settings +import argparse, os, time +from vedirect import Vedirect +from mastodon import Mastodon +from apscheduler.schedulers.background import BackgroundScheduler +scheduler = BackgroundScheduler() +scheduler.start() + +# DB 1 is used as DB 0 is used by mastodon +import redis +r = redis.Redis(host='localhost', port=6379, db=1, decode_responses=True) + +import logging +logging.basicConfig(encoding='utf-8', level=logging.INFO) + +# This needs to be uncommented on first run and then commented out after that - obviously there is a better way to do this. +#Mastodon.create_app( +# 'pytooterapp', +# api_base_url = instance_url, +# to_file = 'pytooter_clientcrednew.secret' +#) + +def mastodon_login(): + mastodon = Mastodon(client_id = settings.access_client_id,) + mastodon.log_in( + settings.mastodon_user, + settings.mastodon_password, + to_file = settings.access_secret + ) + +def print_data_callback(packet): + r.set('batt_v', packet['V']) + r.set('main_current', packet['I']) + r.set('panel_voltage',packet['VPV']) + r.set('panel_power',packet['PPV']) + r.set('load_current',packet['IL']) + r.set('yield_today',packet['H20']) + r.set('max_power_today',packet['H21']) + r.set('yield_yesterday',packet['H22']) + r.set('max_power_yesterday',packet['H23']) + +def send_toot(): + logging.info('Preparing Toot') + try: + batt_v_V = int(r.get('batt_v')) / 1000 + main_current = r.get('main_current') + panel_voltage = int(r.get('panel_voltage')) / 1000 + panel_power = r.get('panel_power') + load_current = int(r.get('load_current')) / 1000 + yield_today = int(r.get('yield_today')) / 1000 + max_power_today = r.get('max_power_today') + load_power = load_current * batt_v_V + toot_to_send = 'Solarcene.community Power Data\nBattery Voltage: {}V\nBattery Current: {}mA\nPanel Voltage: {}V\nPanel Power: {}W\nLoad Current: {}A\nLoad Power: {}W\nYield Today: {}kWh\nMax Power Today: {}W\nUpdated every 60 minutes'.format(batt_v_V, main_current, panel_voltage, panel_power, load_current, load_power, yield_today, max_power_today) + logging.info(toot_to_send) + except: + logging.info('Failed to construct toot') + + try: + mastodon = Mastodon(access_token = settings.access_secret, api_base_url = settings.instance_url) + mastodon.toot(toot_to_send) + except: + logging.info('Failed to send toot') + +def start_toot(): + try: + mastodon = Mastodon(access_token = settings.access_secret, api_base_url = settings.instance_url) + mastodon.toot('System Online') + except: + logging.info('Failed to send toot') + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Process VE.Direct protocol') + parser.add_argument('--port', help='Serial port') + parser.add_argument('--timeout', help='Serial port read timeout', type=int, default='60') + args = parser.parse_args() + scheduler.add_job(send_toot, trigger='cron', minute=1) + + logging.info('Starting') + mastodon_login() + logging.info('Logged In') + + start_toot() + + ve = Vedirect(args.port, args.timeout) + ve.read_data_callback(print_data_callback) + + logging.info('Exit') \ No newline at end of file